1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <errno.h>
21: #include <string.h>
22: #include <stdlib.h>
23: #include <unistd.h>
24: #include <ldsodefs.h>
25:
26: #include <assert.h>
27:
28:
29:
30:
31:
32: struct link_map *
33: internal_function
34: _dl_new_object (char *realname, const char *libname, int type,
35: struct link_map *loader, int mode, Lmid_t nsid)
36: {
37: struct link_map *l;
38: int idx;
39: size_t libname_len = strlen (libname) + 1;
40: struct link_map *new;
41: struct libname_list *newname;
42: #ifdef SHARED
43:
44:
45: unsigned int naudit = GLRO(dl_naudit) ?: ((mode & __RTLD_OPENEXEC)
46: ? DL_NNS : 0);
47: size_t audit_space = naudit * sizeof (new->l_audit[0]);
48: #else
49: # define audit_space 0
50: #endif
51:
52: new = (struct link_map *) calloc (sizeof (*new) + audit_space
53: + sizeof (*newname) + libname_len, 1);
54: if (new == NULL)
55: return NULL;
56:
57: new->l_real = new;
58: new->l_libname = newname = (struct libname_list *) ((char *) (new + 1)
59: + audit_space);
60: newname->name = (char *) memcpy (newname + 1, libname, libname_len);
61:
62: newname->dont_free = 1;
63:
64: new->l_name = realname;
65: new->l_type = type;
66: new->l_loader = loader;
67: #if NO_TLS_OFFSET != 0
68: new->l_tls_offset = NO_TLS_OFFSET;
69: #endif
70: new->l_ns = nsid;
71:
72: #ifdef SHARED
73: for (unsigned int cnt = 0; cnt < naudit; ++cnt)
74: {
75: new->l_audit[cnt].cookie = (uintptr_t) new;
76:
77: }
78: #endif
79:
80:
81:
82:
83:
84:
85: new->l_scope = new->l_scope_mem;
86: new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]);
87:
88:
89: idx = 0;
90:
91: if (GL(dl_ns)[nsid]._ns_loaded != NULL)
92: {
93: l = GL(dl_ns)[nsid]._ns_loaded;
94: while (l->l_next != NULL)
95: l = l->l_next;
96: new->l_prev = l;
97:
98: l->l_next = new;
99:
100:
101: new->l_scope[idx++] = &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
102: }
103: else
104: GL(dl_ns)[nsid]._ns_loaded = new;
105: ++GL(dl_ns)[nsid]._ns_nloaded;
106: new->l_serial = GL(dl_load_adds);
107: ++GL(dl_load_adds);
108:
109:
110: if (loader == NULL)
111: loader = new;
112: else
113:
114: while (loader->l_loader != NULL)
115: loader = loader->l_loader;
116:
117:
118: if (idx == 0 || &loader->l_searchlist != new->l_scope[0])
119: {
120: if ((mode & RTLD_DEEPBIND) != 0 && idx != 0)
121: {
122: new->l_scope[1] = new->l_scope[0];
123: idx = 0;
124: }
125:
126: new->l_scope[idx] = &loader->l_searchlist;
127: }
128:
129: new->l_local_scope[0] = &new->l_searchlist;
130:
131:
132: if (realname[0] != '\0')
133: {
134: size_t realname_len = strlen (realname) + 1;
135: char *origin;
136: char *cp;
137:
138: if (realname[0] == '/')
139: {
140:
141:
142: cp = origin = (char *) malloc (realname_len);
143: if (origin == NULL)
144: {
145: origin = (char *) -1;
146: goto out;
147: }
148: }
149: else
150: {
151: size_t len = realname_len;
152: char *result = NULL;
153:
154:
155: origin = NULL;
156: do
157: {
158: char *new_origin;
159:
160: len += 128;
161: new_origin = (char *) realloc (origin, len);
162: if (new_origin == NULL)
163:
164: break;
165: origin = new_origin;
166: }
167: while ((result = __getcwd (origin, len - realname_len)) == NULL
168: && errno == ERANGE);
169:
170: if (result == NULL)
171: {
172:
173:
174: free (origin);
175: origin = (char *) -1;
176: goto out;
177: }
178:
179:
180:
181:
182: cp = (strchr) (origin, '\0');
183: if (cp[-1] != '/')
184: *cp++ = '/';
185: }
186:
187:
188: cp = __mempcpy (cp, realname, realname_len);
189:
190:
191:
192: do
193: --cp;
194: while (*cp != '/');
195:
196: if (cp == origin)
197:
198: ++cp;
199: *cp = '\0';
200:
201: out:
202: new->l_origin = origin;
203: }
204:
205: return new;
206: }