1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <assert.h>
21: #include <elf.h>
22: #include <errno.h>
23: #include <fcntl.h>
24: #include <libintl.h>
25: #include <stdlib.h>
26: #include <string.h>
27: #include <unistd.h>
28: #include <sys/types.h>
29: #include <sys/stat.h>
30: #include <sys/mman.h>
31: #include <ldsodefs.h>
32: #include <stdio-common/_itoa.h>
33: #include <fpu_control.h>
34:
35: #include <entry.h>
36: #include <dl-machine.h>
37: #include <dl-procinfo.h>
38: #include <dl-osinfo.h>
39: #include <hp-timing.h>
40: #include <tls.h>
41:
42: #ifdef _DL_FIRST_PLATFORM
43: # define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT)
44: #else
45: # define _DL_FIRST_EXTRA _DL_HWCAP_COUNT
46: #endif
47:
48: extern char **_environ attribute_hidden;
49: extern void _end attribute_hidden;
50:
51:
52: extern void __libc_check_standard_fds (void);
53:
54: #ifdef NEED_DL_BASE_ADDR
55: ElfW(Addr) _dl_base_addr;
56: #endif
57: int __libc_enable_secure attribute_relro = 0;
58: INTVARDEF(__libc_enable_secure)
59: int __libc_multiple_libcs = 0;
60:
61:
62: void *__libc_stack_end attribute_relro = NULL;
63: rtld_hidden_data_def(__libc_stack_end)
64: static ElfW(auxv_t) *_dl_auxv attribute_relro;
65:
66: #ifndef DL_FIND_ARG_COMPONENTS
67: # define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp) \
68: do { \
69: void **_tmp; \
70: (argc) = *(long int *) cookie; \
71: (argv) = (char **) ((long int *) cookie + 1); \
72: (envp) = (argv) + (argc) + 1; \
73: for (_tmp = (void **) (envp); *_tmp; ++_tmp) \
74: continue; \
75: (auxp) = (void *) ++_tmp; \
76: } while (0)
77: #endif
78:
79: #ifndef DL_STACK_END
80: # define DL_STACK_END(cookie) ((void *) (cookie))
81: #endif
82:
83: ElfW(Addr)
84: _dl_sysdep_start (void **start_argptr,
85: void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
86: ElfW(Addr) *user_entry))
87: {
88: const ElfW(Phdr) *phdr = NULL;
89: ElfW(Word) phnum = 0;
90: ElfW(Addr) user_entry;
91: ElfW(auxv_t) *av;
92: #ifdef HAVE_AUX_SECURE
93: # define set_seen(tag) (tag)
94: # define set_seen_secure() ((void) 0)
95: #else
96: uid_t uid = 0;
97: gid_t gid = 0;
98: unsigned int seen = 0;
99: # define set_seen_secure() (seen = -1)
100: # ifdef HAVE_AUX_XID
101: # define set_seen(tag) (tag)
102: # else
103: # define M(type) (1 << (type))
104: # define set_seen(tag) seen |= M ((tag)->a_type)
105: # endif
106: #endif
107: #ifdef NEED_DL_SYSINFO
108: uintptr_t new_sysinfo = 0;
109: #endif
110:
111: __libc_stack_end = DL_STACK_END (start_argptr);
112: DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, INTUSE(_dl_argv), _environ,
113: _dl_auxv);
114:
115: user_entry = (ElfW(Addr)) ENTRY_POINT;
116: GLRO(dl_platform) = NULL;
117:
118: for (av = _dl_auxv; av->a_type != AT_NULL; set_seen (av++))
119: switch (av->a_type)
120: {
121: case AT_PHDR:
122: phdr = (void *) av->a_un.a_val;
123: break;
124: case AT_PHNUM:
125: phnum = av->a_un.a_val;
126: break;
127: case AT_PAGESZ:
128: GLRO(dl_pagesize) = av->a_un.a_val;
129: break;
130: case AT_ENTRY:
131: user_entry = av->a_un.a_val;
132: break;
133: #ifdef NEED_DL_BASE_ADDR
134: case AT_BASE:
135: _dl_base_addr = av->a_un.a_val;
136: break;
137: #endif
138: #ifndef HAVE_AUX_SECURE
139: case AT_UID:
140: case AT_EUID:
141: uid ^= av->a_un.a_val;
142: break;
143: case AT_GID:
144: case AT_EGID:
145: gid ^= av->a_un.a_val;
146: break;
147: #endif
148: case AT_SECURE:
149: #ifndef HAVE_AUX_SECURE
150: seen = -1;
151: #endif
152: INTUSE(__libc_enable_secure) = av->a_un.a_val;
153: break;
154: case AT_PLATFORM:
155: GLRO(dl_platform) = (void *) av->a_un.a_val;
156: break;
157: case AT_HWCAP:
158: GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
159: break;
160: case AT_CLKTCK:
161: GLRO(dl_clktck) = av->a_un.a_val;
162: break;
163: case AT_FPUCW:
164: GLRO(dl_fpu_control) = av->a_un.a_val;
165: break;
166: #ifdef NEED_DL_SYSINFO
167: case AT_SYSINFO:
168: new_sysinfo = av->a_un.a_val;
169: break;
170: #endif
171: #if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
172: case AT_SYSINFO_EHDR:
173: GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val;
174: break;
175: #endif
176: #ifdef DL_PLATFORM_AUXV
177: DL_PLATFORM_AUXV
178: #endif
179: }
180:
181: #ifndef HAVE_AUX_SECURE
182: if (seen != -1)
183: {
184:
185:
186: # ifndef HAVE_AUX_XID
187: # define SEE(UID, var, uid) \
188: if ((seen & M (AT_##UID)) == 0) var ^= __get##uid ()
189: SEE (UID, uid, uid);
190: SEE (EUID, uid, euid);
191: SEE (GID, gid, gid);
192: SEE (EGID, gid, egid);
193: # endif
194:
195:
196:
197: INTUSE(__libc_enable_secure) = uid | gid;
198: }
199: #endif
200:
201: #ifndef HAVE_AUX_PAGESIZE
202: if (GLRO(dl_pagesize) == 0)
203: GLRO(dl_pagesize) = __getpagesize ();
204: #endif
205:
206: #if defined NEED_DL_SYSINFO
207:
208: if (GLRO(dl_sysinfo_dso) != 0 && new_sysinfo)
209: GLRO(dl_sysinfo) = new_sysinfo;
210: #endif
211:
212: #ifdef DL_SYSDEP_INIT
213: DL_SYSDEP_INIT;
214: #endif
215:
216: #ifdef DL_PLATFORM_INIT
217: DL_PLATFORM_INIT;
218: #endif
219:
220:
221: if (GLRO(dl_platform) != NULL)
222: GLRO(dl_platformlen) = strlen (GLRO(dl_platform));
223:
224: if (__sbrk (0) == &_end)
225:
226:
227:
228:
229:
230: __sbrk (GLRO(dl_pagesize)
231: - ((&_end - (void *) 0) & (GLRO(dl_pagesize) - 1)));
232:
233:
234:
235:
236: if (__builtin_expect (INTUSE(__libc_enable_secure), 0))
237: __libc_check_standard_fds ();
238:
239: (*dl_main) (phdr, phnum, &user_entry);
240: return user_entry;
241: }
242:
243: void
244: internal_function
245: _dl_sysdep_start_cleanup (void)
246: {
247: }
248:
249: void
250: internal_function
251: _dl_show_auxv (void)
252: {
253: char buf[64];
254: ElfW(auxv_t) *av;
255:
256:
257: buf[63] = '\0';
258:
259:
260:
261:
262:
263:
264: for (av = _dl_auxv; av->a_type != AT_NULL; ++av)
265: {
266: static const struct
267: {
268: const char label[20];
269: enum { unknown = 0, dec, hex, str, ignore } form;
270: } auxvars[] =
271: {
272: [AT_EXECFD - 2] = { "AT_EXECFD: ", dec },
273: [AT_PHDR - 2] = { "AT_PHDR: 0x", hex },
274: [AT_PHENT - 2] = { "AT_PHENT: ", dec },
275: [AT_PHNUM - 2] = { "AT_PHNUM: ", dec },
276: [AT_PAGESZ - 2] = { "AT_PAGESZ: ", dec },
277: [AT_BASE - 2] = { "AT_BASE: 0x", hex },
278: [AT_FLAGS - 2] = { "AT_FLAGS: 0x", hex },
279: [AT_ENTRY - 2] = { "AT_ENTRY: 0x", hex },
280: [AT_NOTELF - 2] = { "AT_NOTELF: ", hex },
281: [AT_UID - 2] = { "AT_UID: ", dec },
282: [AT_EUID - 2] = { "AT_EUID: ", dec },
283: [AT_GID - 2] = { "AT_GID: ", dec },
284: [AT_EGID - 2] = { "AT_EGID: ", dec },
285: [AT_PLATFORM - 2] = { "AT_PLATFORM: ", str },
286: [AT_HWCAP - 2] = { "AT_HWCAP: ", hex },
287: [AT_CLKTCK - 2] = { "AT_CLKTCK: ", dec },
288: [AT_FPUCW - 2] = { "AT_FPUCW: ", hex },
289: [AT_DCACHEBSIZE - 2] = { "AT_DCACHEBSIZE: 0x", hex },
290: [AT_ICACHEBSIZE - 2] = { "AT_ICACHEBSIZE: 0x", hex },
291: [AT_UCACHEBSIZE - 2] = { "AT_UCACHEBSIZE: 0x", hex },
292: [AT_IGNOREPPC - 2] = { "AT_IGNOREPPC", ignore },
293: [AT_SECURE - 2] = { "AT_SECURE: ", dec },
294: [AT_SYSINFO - 2] = { "AT_SYSINFO: 0x", hex },
295: [AT_SYSINFO_EHDR - 2] = { "AT_SYSINFO_EHDR: 0x", hex },
296: };
297: unsigned int idx = (unsigned int) (av->a_type - 2);
298:
299: if ((unsigned int) av->a_type < 2u || auxvars[idx].form == ignore)
300: continue;
301:
302: assert (AT_NULL == 0);
303: assert (AT_IGNORE == 1);
304:
305: if (av->a_type == AT_HWCAP)
306: {
307:
308: if (_dl_procinfo (av->a_un.a_val) == 0)
309: continue;
310: }
311:
312: if (idx < sizeof (auxvars) / sizeof (auxvars[0])
313: && auxvars[idx].form != unknown)
314: {
315: const char *val = (char *) av->a_un.a_val;
316:
317: if (__builtin_expect (auxvars[idx].form, dec) == dec)
318: val = _itoa ((unsigned long int) av->a_un.a_val,
319: buf + sizeof buf - 1, 10, 0);
320: else if (__builtin_expect (auxvars[idx].form, hex) == hex)
321: val = _itoa ((unsigned long int) av->a_un.a_val,
322: buf + sizeof buf - 1, 16, 0);
323:
324: _dl_printf ("%s%s\n", auxvars[idx].label, val);
325:
326: continue;
327: }
328:
329:
330: char buf2[17];
331: buf[sizeof (buf2) - 1] = '\0';
332: const char *val2 = _itoa ((unsigned long int) av->a_un.a_val,
333: buf2 + sizeof buf2 - 1, 16, 0);
334: const char *val = _itoa ((unsigned long int) av->a_type,
335: buf + sizeof buf - 1, 16, 0);
336: _dl_printf ("AT_??? (0x%s): 0x%s\n", val, val2);
337: }
338: }
339:
340:
341:
342: const struct r_strlenpair *
343: internal_function
344: _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
345: size_t *max_capstrlen)
346: {
347:
348: uint64_t masked = GLRO(dl_hwcap) & GLRO(dl_hwcap_mask);
349: size_t cnt = platform != NULL;
350: size_t n, m;
351: size_t total;
352: struct r_strlenpair *temp;
353: struct r_strlenpair *result;
354: struct r_strlenpair *rp;
355: char *cp;
356:
357:
358: for (n = 0; (~((1ULL << n) - 1) & masked) != 0; ++n)
359: if ((masked & (1ULL << n)) != 0)
360: ++cnt;
361:
362: #if (defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO) && defined SHARED
363:
364:
365:
366: const char *dsocaps = NULL;
367: size_t dsocapslen = 0;
368: if (GLRO(dl_sysinfo_map) != NULL)
369: {
370: const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr;
371: const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum;
372: for (uint_fast16_t i = 0; i < phnum; ++i)
373: if (phdr[i].p_type == PT_NOTE)
374: {
375: const ElfW(Addr) start = (phdr[i].p_vaddr
376: + GLRO(dl_sysinfo_map)->l_addr);
377: const struct
378: {
379: ElfW(Word) vendorlen;
380: ElfW(Word) datalen;
381: ElfW(Word) type;
382: } *note = (const void *) start;
383: while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz)
384: {
385: #define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word)))
386: if (note->type == 2
387: && note->vendorlen == sizeof "GNU"
388: && !memcmp ((note + 1), "GNU", sizeof "GNU")
389: && note->datalen > 2 * sizeof (ElfW(Word)) + 2)
390: {
391: const ElfW(Word) *p = ((const void *) (note + 1)
392: + ROUND (sizeof "GNU"));
393: cnt += *p++;
394: ++p;
395: dsocaps = (const char *) p;
396: dsocapslen = note->datalen - sizeof *p * 2;
397: break;
398: }
399: note = ((const void *) (note + 1)
400: + ROUND (note->vendorlen) + ROUND (note->datalen));
401: }
402: if (dsocaps != NULL)
403: break;
404: }
405: }
406: #endif
407:
408:
409: ++cnt;
410:
411:
412: temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp));
413: m = 0;
414: #if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
415: if (dsocaps != NULL)
416: {
417: const ElfW(Word) mask = ((const ElfW(Word) *) dsocaps)[-1];
418: GLRO(dl_hwcap) |= (uint64_t) mask << _DL_FIRST_EXTRA;
419: size_t len;
420: for (const char *p = dsocaps; p < dsocaps + dsocapslen; p += len + 1)
421: {
422: uint_fast8_t bit = *p++;
423: len = strlen (p);
424:
425:
426: if (__builtin_expect (mask & ((ElfW(Word)) 1 << bit), 1))
427: {
428: temp[m].str = p;
429: temp[m].len = len;
430: ++m;
431: }
432: else
433: --cnt;
434: }
435: }
436: #endif
437: for (n = 0; masked != 0; ++n)
438: if ((masked & (1ULL << n)) != 0)
439: {
440: temp[m].str = _dl_hwcap_string (n);
441: temp[m].len = strlen (temp[m].str);
442: masked ^= 1ULL << n;
443: ++m;
444: }
445: if (platform != NULL)
446: {
447: temp[m].str = platform;
448: temp[m].len = platform_len;
449: ++m;
450: }
451:
452: temp[m].str = "tls";
453: temp[m].len = 3;
454: ++m;
455:
456: assert (m == cnt);
457:
458:
459: if (cnt == 1)
460: total = temp[0].len + 1;
461: else
462: {
463: total = temp[0].len + temp[cnt - 1].len + 2;
464: if (cnt > 2)
465: {
466: total <<= 1;
467: for (n = 1; n + 1 < cnt; ++n)
468: total += temp[n].len + 1;
469: if (cnt > 3
470: && (cnt >= sizeof (size_t) * 8
471: || total + (sizeof (*result) << 3)
472: >= (1UL << (sizeof (size_t) * 8 - cnt + 3))))
473: _dl_signal_error (ENOMEM, NULL, NULL,
474: N_("cannot create capability list"));
475:
476: total <<= cnt - 3;
477: }
478: }
479:
480:
481:
482: *sz = 1 << cnt;
483: result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total);
484: if (result == NULL)
485: _dl_signal_error (ENOMEM, NULL, NULL,
486: N_("cannot create capability list"));
487:
488: if (cnt == 1)
489: {
490: result[0].str = (char *) (result + *sz);
491: result[0].len = temp[0].len + 1;
492: result[1].str = (char *) (result + *sz);
493: result[1].len = 0;
494: cp = __mempcpy ((char *) (result + *sz), temp[0].str, temp[0].len);
495: *cp = '/';
496: *sz = 2;
497: *max_capstrlen = result[0].len;
498:
499: return result;
500: }
501:
502:
503:
504:
505:
506:
507:
508:
509:
510: result[1].str = result[0].str = cp = (char *) (result + *sz);
511: #define add(idx) \
512: cp = __mempcpy (__mempcpy (cp, temp[idx].str, temp[idx].len), "/", 1);
513: if (cnt == 2)
514: {
515: add (1);
516: add (0);
517: }
518: else
519: {
520: n = 1 << (cnt - 1);
521: do
522: {
523: n -= 2;
524:
525: