db_rtld.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383
  1. /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
  2. /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
  3. /* Copyright (C) 2014 Stony Brook University
  4. This file is part of Graphene Library OS.
  5. Graphene Library OS is free software: you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public License
  7. as published by the Free Software Foundation, either version 3 of the
  8. License, or (at your option) any later version.
  9. Graphene Library OS is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. /*
  16. * db_rtld.c
  17. *
  18. * This file contains utilities to load ELF binaries into the memory
  19. * and link them against each other.
  20. * The source code in this file is imported and modified from the GNU C
  21. * Library.
  22. */
  23. #include "pal_defs.h"
  24. #include "pal.h"
  25. #include "pal_internal.h"
  26. #include "pal_debug.h"
  27. #include "pal_error.h"
  28. #include "pal_rtld.h"
  29. #include "api.h"
  30. #include <sysdeps/generic/ldsodefs.h>
  31. #include <elf/elf.h>
  32. struct link_map * loaded_maps = NULL;
  33. struct link_map * exec_map = NULL;
  34. struct link_map * lookup_symbol (const char *undef_name, ElfW(Sym) **ref);
  35. #ifdef assert
  36. /* This function can be used as a breakpoint to debug assertion */
  37. void __attribute_noinline __assert (void)
  38. {
  39. BREAK();
  40. }
  41. #endif
  42. /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
  43. static struct link_map * resolve_map (const char **strtab, ElfW(Sym) ** ref)
  44. {
  45. if (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL) {
  46. struct link_map * l = lookup_symbol((*strtab) + (*ref)->st_name, ref);
  47. if (l) {
  48. *strtab = (const void *) D_PTR (l->l_info[DT_STRTAB]);
  49. return l;
  50. }
  51. }
  52. return 0;
  53. }
  54. extern ElfW(Addr) resolve_rtld (const char * sym_name);
  55. #define RESOLVE_RTLD(sym_name) resolve_rtld(sym_name)
  56. #define RESOLVE_MAP(strtab, ref) resolve_map(strtab, ref)
  57. #include "dynamic_link.h"
  58. #include "dl-machine-x86_64.h"
  59. /* Allocate a `struct link_map' for a new object being loaded,
  60. and enter it into the _dl_loaded list. */
  61. struct link_map *
  62. new_elf_object (const char * realname, enum object_type type)
  63. {
  64. struct link_map *new;
  65. new = (struct link_map *) malloc(sizeof (struct link_map));
  66. if (new == NULL)
  67. return NULL;
  68. /* We apparently expect this to be zeroed. */
  69. memset(new, 0, sizeof(struct link_map));
  70. new->l_name = realname ?
  71. remalloc(realname, strlen(realname) + 1) :
  72. NULL;
  73. new->l_type = type;
  74. return new;
  75. }
  76. /* Cache the location of MAP's hash table. */
  77. void setup_elf_hash (struct link_map *map)
  78. {
  79. Elf_Symndx * hash;
  80. if (__builtin_expect (map->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM
  81. + DT_THISPROCNUM + DT_VERSIONTAGNUM
  82. + DT_EXTRANUM + DT_VALNUM] != NULL, 1)) {
  83. Elf32_Word *hash32
  84. = (void *) D_PTR (map->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM
  85. + DT_THISPROCNUM + DT_VERSIONTAGNUM
  86. + DT_EXTRANUM + DT_VALNUM]);
  87. map->l_nbuckets = *hash32++;
  88. Elf32_Word symbias = *hash32++;
  89. Elf32_Word bitmask_nwords = *hash32++;
  90. /* Must be a power of two. */
  91. assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0);
  92. map->l_gnu_bitmask_idxbits = bitmask_nwords - 1;
  93. map->l_gnu_shift = *hash32++;
  94. map->l_gnu_bitmask = (ElfW(Addr) *) hash32;
  95. hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords;
  96. map->l_gnu_buckets = hash32;
  97. hash32 += map->l_nbuckets;
  98. map->l_gnu_chain_zero = hash32 - symbias;
  99. return;
  100. }
  101. if (!map->l_info[DT_HASH])
  102. return;
  103. hash = (void *) D_PTR (map->l_info[DT_HASH]);
  104. /* Structure of DT_HASH:
  105. The bucket array forms the hast table itself. The entries in the
  106. chain array parallel the symbol table.
  107. [ nbucket ]
  108. [ nchain ]
  109. [ bucket[0] ]
  110. [ ... ]
  111. [ bucket[nbucket-1] ]
  112. [ chain[0] ]
  113. [ ... ]
  114. [ chain[nchain-1] ] */
  115. map->l_nbuckets = *hash++;
  116. hash++;
  117. map->l_buckets = hash;
  118. hash += map->l_nbuckets;
  119. map->l_chain = hash;
  120. }
  121. /* Map in the shared object NAME, actually located in REALNAME, and already
  122. opened on FD */
  123. struct link_map *
  124. map_elf_object_by_handle (PAL_HANDLE handle, enum object_type type,
  125. void * fbp, int fbp_len,
  126. bool do_copy_dyn)
  127. {
  128. struct link_map * l = new_elf_object(_DkStreamRealpath(handle), type);
  129. const char * errstring = NULL;
  130. int errval = 0;
  131. int ret;
  132. if (handle == NULL) {
  133. errstring = "cannot stat shared object";
  134. errval = PAL_ERROR_INVAL;
  135. call_lose:
  136. printf("%s (%s)\n", errstring, PAL_STRERROR(errval));
  137. return NULL;
  138. }
  139. /* This is the ELF header. We read it in `open_verify'. */
  140. const ElfW(Ehdr) * header = (void *) fbp;
  141. /* Extract the remaining details we need from the ELF header
  142. and then read in the program header table. */
  143. int e_type = header->e_type;
  144. l->l_entry = header->e_entry;
  145. l->l_phnum = header->e_phnum;
  146. int maplength = header->e_phnum * sizeof (ElfW(Phdr));
  147. ElfW(Phdr) * phdr;
  148. if (header->e_phoff + maplength <= (int) fbp_len) {
  149. phdr = (void *) ((char *) fbp + header->e_phoff);
  150. } else {
  151. phdr = (ElfW(Phdr) *) malloc (maplength);
  152. if ((ret = _DkStreamRead(handle, header->e_phoff, maplength, phdr,
  153. NULL, 0)) < 0) {
  154. errstring = "cannot read file data";
  155. errval = ret;
  156. goto call_lose;
  157. }
  158. }
  159. /* Presumed absent PT_GNU_STACK. */
  160. //uint_fast16_t stack_flags = PF_R|PF_W|PF_X;
  161. /* Scan the program header table, collecting its load commands. */
  162. struct loadcmd {
  163. ElfW(Addr) mapstart, mapend, dataend, allocend;
  164. unsigned int mapoff;
  165. int prot;
  166. } * loadcmds, *c;
  167. loadcmds = __alloca(sizeof(struct loadcmd) * l->l_phnum);
  168. int nloadcmds = 0;
  169. bool has_holes = false;
  170. /* The struct is initialized to zero so this is not necessary:
  171. l->l_ld = 0;
  172. l->l_phdr = 0;
  173. l->l_addr = 0; */
  174. const ElfW(Phdr) * ph;
  175. for (ph = phdr; ph < &phdr[l->l_phnum]; ++ph)
  176. switch (ph->p_type)
  177. {
  178. /* These entries tell us where to find things once the file's
  179. segments are mapped in. We record the addresses it says
  180. verbatim, and later correct for the run-time load address. */
  181. case PT_DYNAMIC:
  182. l->l_ld = (void *) ph->p_vaddr;
  183. l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
  184. break;
  185. case PT_PHDR:
  186. l->l_phdr = (void *) ph->p_vaddr;
  187. break;
  188. case PT_LOAD:
  189. /* A load command tells us to map in part of the file.
  190. We record the load commands and process them all later. */
  191. if (__builtin_expect (!ALLOC_ALIGNED(ph->p_align), 0)) {
  192. errstring = "ELF load command alignment not aligned";
  193. errval = PAL_ERROR_NOMEM;
  194. goto call_lose;
  195. }
  196. if (__builtin_expect (((ph->p_vaddr - ph->p_offset)
  197. & (ph->p_align - 1)) != 0, 0)) {
  198. errstring = "\
  199. ELF load command address/offset not properly aligned";
  200. errval = PAL_ERROR_NOMEM;
  201. goto call_lose;
  202. }
  203. c = &loadcmds[nloadcmds++];
  204. c->mapstart = ALLOC_ALIGNDOWN(ph->p_vaddr);
  205. c->mapend = ALLOC_ALIGNUP(ph->p_vaddr + ph->p_filesz);
  206. c->dataend = ph->p_vaddr + ph->p_filesz;
  207. c->allocend = ph->p_vaddr + ph->p_memsz;
  208. c->mapoff = ALLOC_ALIGNDOWN(ph->p_offset);
  209. /* Determine whether there is a gap between the last segment
  210. and this one. */
  211. if (nloadcmds > 1 && c[-1].mapend != c->mapstart)
  212. has_holes = true;
  213. /* Optimize a common case. */
  214. c->prot = 0;
  215. if (ph->p_flags & PF_R)
  216. c->prot |= PAL_PROT_READ;
  217. if (ph->p_flags & PF_W)
  218. c->prot |= PAL_PROT_WRITE;
  219. if (ph->p_flags & PF_X)
  220. c->prot |= PAL_PROT_EXEC;
  221. break;
  222. case PT_TLS:
  223. if (ph->p_memsz == 0)
  224. /* Nothing to do for an empty segment. */
  225. break;
  226. case PT_GNU_STACK:
  227. //stack_flags = ph->p_flags;
  228. break;
  229. case PT_GNU_RELRO:
  230. l->l_relro_addr = ph->p_vaddr;
  231. l->l_relro_size = ph->p_memsz;
  232. break;
  233. }
  234. if (__builtin_expect (nloadcmds == 0, 0)) {
  235. /* This only happens for a bogus object that will be caught with
  236. another error below. But we don't want to go through the
  237. calculations below using NLOADCMDS - 1. */
  238. errstring = "object file has no loadable segments";
  239. goto call_lose;
  240. }
  241. /* Now process the load commands and map segments into memory. */
  242. c = loadcmds;
  243. /* Length of the sections to be loaded. */
  244. maplength = loadcmds[nloadcmds - 1].allocend - c->mapstart;
  245. #define APPEND_WRITECOPY(prot) ((prot)|PAL_PROT_WRITECOPY)
  246. if (__builtin_expect (e_type, ET_DYN) == ET_DYN) {
  247. /* This is a position-independent shared object. We can let the
  248. kernel map it anywhere it likes, but we must have space for all
  249. the segments in their specified positions relative to the first.
  250. So we map the first segment without MAP_FIXED, but with its
  251. extent increased to cover all the segments. Then we remove
  252. access from excess portion, and there is known sufficient space
  253. there to remap from the later segments.
  254. As a refinement, sometimes we have an address that we would
  255. prefer to map such objects at; but this is only a preference,
  256. the OS can do whatever it likes. */
  257. void * mapaddr = NULL;
  258. /* Remember which part of the address space this object uses. */
  259. errval = _DkStreamMap(handle, (void **) &mapaddr,
  260. APPEND_WRITECOPY(c->prot), c->mapoff,
  261. maplength);
  262. if (__builtin_expect (errval < 0, 0)) {
  263. errval = -errval;
  264. map_error:
  265. errstring = "failed to map segment from shared object";
  266. goto call_lose;
  267. }
  268. l->l_map_start = (ElfW(Addr)) mapaddr;
  269. l->l_map_end = (ElfW(Addr)) mapaddr + maplength;
  270. l->l_addr = l->l_map_start - c->mapstart;
  271. if (has_holes)
  272. /* Change protection on the excess portion to disallow all access;
  273. the portions we do not remap later will be inaccessible as if
  274. unallocated. Then jump into the normal segment-mapping loop to
  275. handle the portion of the segment past the end of the file
  276. mapping. */
  277. _DkVirtualMemoryProtect((void *) (l->l_addr + c->mapend),
  278. loadcmds[nloadcmds - 1].mapstart - c->mapend,
  279. PAL_PROT_NONE);
  280. goto postmap;
  281. }
  282. /* Remember which part of the address space this object uses. */
  283. l->l_map_start = c->mapstart + l->l_addr;
  284. l->l_map_end = l->l_map_start + maplength;
  285. while (c < &loadcmds[nloadcmds]) {
  286. if (c->mapend > c->mapstart) {
  287. /* Map the segment contents from the file. */
  288. void * mapaddr = (void *) (l->l_addr + c->mapstart);
  289. int rv;
  290. if ((rv = _DkStreamMap(handle, &mapaddr, APPEND_WRITECOPY(c->prot),
  291. c->mapoff, c->mapend - c->mapstart)) < 0) {
  292. goto map_error;
  293. }
  294. }
  295. postmap:
  296. if (l->l_phdr == 0
  297. && (ElfW(Off)) c->mapoff <= header->e_phoff
  298. && ((int) (c->mapend - c->mapstart + c->mapoff)
  299. >= header->e_phoff + header->e_phnum * sizeof (ElfW(Phdr))))
  300. /* Found the program header in this segment. */
  301. l->l_phdr = (void *) (c->mapstart + header->e_phoff - c->mapoff);
  302. if (c->allocend > c->dataend) {
  303. /* Extra zero pages should appear at the end of this segment,
  304. after the data mapped from the file. */
  305. ElfW(Addr) zero, zeroend, zerosec;
  306. zero = l->l_addr + c->dataend;
  307. zeroend = ALLOC_ALIGNUP(l->l_addr + c->allocend);
  308. zerosec = ALLOC_ALIGNUP(zero);
  309. if (zeroend < zerosec)
  310. /* All the extra data is in the last section of the segment.
  311. We can just zero it. */
  312. zerosec = zeroend;
  313. if (zerosec > zero) {
  314. /* Zero the final part of the last section of the segment. */
  315. if (__builtin_expect ((c->prot & PAL_PROT_WRITE) == 0, 0))
  316. {
  317. /* Dag nab it. */
  318. if (_DkVirtualMemoryProtect((void *) ALLOC_ALIGNDOWN(zero),
  319. pal_state.alloc_align,
  320. c->prot | PAL_PROT_WRITE) < 0) {
  321. errstring = "cannot change memory protections";
  322. goto call_lose;
  323. }
  324. }
  325. memset ((void *) zero, '\0', zerosec - zero);
  326. if (__builtin_expect ((c->prot & PAL_PROT_WRITE) == 0, 0))
  327. _DkVirtualMemoryProtect((void *) ALLOC_ALIGNDOWN(zero),
  328. pal_state.alloc_align, c->prot);
  329. }
  330. if (zeroend > zerosec) {
  331. /* Map the remaining zero pages in from the zero fill FD. */
  332. void * mapat = (void *) zerosec;
  333. errval = _DkVirtualMemoryAlloc(&mapat, zeroend - zerosec,
  334. 0, c->prot);
  335. if (__builtin_expect (errval < 0, 0)) {
  336. errstring = "cannot map zero-fill allocation";
  337. goto call_lose;
  338. }
  339. }
  340. }
  341. ++c;
  342. }
  343. if (l->l_ld == 0) {
  344. if (__builtin_expect (e_type == ET_DYN, 0)) {
  345. errstring = "object file has no dynamic section";
  346. goto call_lose;
  347. }
  348. } else {
  349. l->l_real_ld = l->l_ld =
  350. (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr);
  351. if (do_copy_dyn)
  352. l->l_ld = remalloc(l->l_ld, sizeof(ElfW(Dyn)) * l->l_ldnum);
  353. }
  354. elf_get_dynamic_info(l->l_ld, l->l_info, l->l_addr);
  355. if (l->l_phdr == NULL) {
  356. /* The program header is not contained in any of the segments.
  357. We have to allocate memory ourself and copy it over from out
  358. temporary place. */
  359. ElfW(Phdr) * newp = (ElfW(Phdr) *) malloc (header->e_phnum
  360. * sizeof (ElfW(Phdr)));
  361. if (!newp) {
  362. errstring = "cannot allocate memory for program header";
  363. goto call_lose;
  364. }
  365. l->l_phdr = memcpy(newp, phdr,
  366. header->e_phnum * sizeof (ElfW(Phdr)));
  367. } else {
  368. /* Adjust the PT_PHDR value by the runtime load address. */
  369. l->l_phdr = (ElfW(Phdr) *) ((ElfW(Addr)) l->l_phdr + l->l_addr);
  370. }
  371. l->l_entry += l->l_addr;
  372. /* Set up the symbol hash table. */
  373. setup_elf_hash (l);
  374. return l;
  375. }
  376. int check_elf_object (PAL_HANDLE handle)
  377. {
  378. #define ELF_MAGIC_SIZE EI_CLASS
  379. unsigned char buffer[ELF_MAGIC_SIZE];
  380. int len = _DkStreamRead(handle, 0, ELF_MAGIC_SIZE, buffer, NULL, 0);
  381. if (__builtin_expect (len < 0, 0))
  382. return -len;
  383. if (__builtin_expect (len < ELF_MAGIC_SIZE, 0))
  384. return -PAL_ERROR_INVAL;
  385. ElfW(Ehdr) * ehdr = (ElfW(Ehdr) *) buffer;
  386. static const unsigned char expected[EI_CLASS] =
  387. {
  388. [EI_MAG0] = ELFMAG0,
  389. [EI_MAG1] = ELFMAG1,
  390. [EI_MAG2] = ELFMAG2,
  391. [EI_MAG3] = ELFMAG3,
  392. };
  393. /* See whether the ELF header is what we expect. */
  394. if (__builtin_expect(memcmp(ehdr->e_ident, expected, ELF_MAGIC_SIZE) !=
  395. 0, 0))
  396. return -PAL_ERROR_INVAL;
  397. return 0;
  398. }
  399. void free_elf_object (struct link_map * map)
  400. {
  401. _DkVirtualMemoryFree((void *) map->l_map_start,
  402. map->l_map_end - map->l_map_start);
  403. if (map->l_prev)
  404. map->l_prev->l_next = map->l_next;
  405. if (map->l_next)
  406. map->l_next->l_prev = map->l_prev;
  407. #ifdef DEBUG
  408. _DkDebugDelMap(map);
  409. #endif
  410. if (loaded_maps == map)
  411. loaded_maps = map->l_next;
  412. free(map);
  413. }
  414. /* Map in the shared object file loaded from URI. */
  415. int load_elf_object (const char * uri, enum object_type type)
  416. {
  417. PAL_HANDLE handle;
  418. /* First we open the file by uri, as the regular file handles */
  419. int ret = _DkStreamOpen(&handle, uri, PAL_ACCESS_RDONLY,
  420. 0, 0, 0);
  421. if (ret < 0)
  422. return ret;
  423. ret = load_elf_object_by_handle(handle, type);
  424. _DkObjectClose(handle);
  425. return ret;
  426. }
  427. int add_elf_object(void * addr, PAL_HANDLE handle, int type)
  428. {
  429. struct link_map * map = new_elf_object(_DkStreamRealpath(handle), type);
  430. const ElfW(Ehdr) * header = (void *) addr;
  431. const ElfW(Phdr) * ph, * phdr =
  432. (ElfW(Phdr) *) ((char *) addr + header->e_phoff);
  433. map->l_phdr = (void *) header->e_phoff;
  434. map->l_phnum = header->e_phnum;
  435. ElfW(Addr) mapstart = 0, mapend = 0;
  436. for (ph = phdr; ph < &phdr[map->l_phnum]; ++ph)
  437. switch (ph->p_type) {
  438. case PT_DYNAMIC:
  439. map->l_ld = (void *) ph->p_vaddr;
  440. map->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
  441. break;
  442. case PT_LOAD: {
  443. ElfW(Addr) start = (ElfW(Addr))
  444. ALLOC_ALIGNDOWN(map->l_addr + ph->p_vaddr);
  445. ElfW(Addr) end = (ElfW(Addr))
  446. ALLOC_ALIGNUP(map->l_addr + ph->p_vaddr + ph->p_memsz);
  447. if (!mapstart || start < mapstart)
  448. mapstart = start;
  449. if (!mapend || end > mapend)
  450. mapend = end;
  451. }
  452. }
  453. map->l_addr = (ElfW(Addr)) addr - mapstart;
  454. map->l_entry = header->e_entry;
  455. map->l_map_start = (ElfW(Addr)) addr;
  456. map->l_map_end = (ElfW(Addr)) addr + (mapend - mapstart);
  457. map->l_real_ld = (ElfW(Dyn) *)
  458. ((char *) map->l_addr + (unsigned long) map->l_ld);
  459. map->l_ld = remalloc(map->l_real_ld, sizeof(ElfW(Dyn)) * map->l_ldnum);
  460. elf_get_dynamic_info(map->l_ld, map->l_info, map->l_addr);
  461. setup_elf_hash(map);
  462. ELF_DYNAMIC_RELOCATE(map);
  463. struct link_map * prev = loaded_maps;
  464. while (prev->l_next)
  465. prev = prev->l_next;
  466. map->l_prev = prev;
  467. map->l_next = NULL;
  468. prev->l_next = map;
  469. if (type == OBJECT_EXEC)
  470. exec_map = map;
  471. #ifdef DEBUG
  472. _DkDebugAddMap(map);
  473. #endif
  474. return 0;
  475. }
  476. static int relocate_elf_object (struct link_map *l);
  477. #if CACHE_LOADED_BINARIES == 1
  478. #define MAX_CACHED_LOADCMDS 32
  479. struct cached_elf_object {
  480. PAL_NUM instance_id;
  481. void * loader_addr; /* get the address of DkStreamOpen */
  482. struct link_map map;
  483. char map_name[80];
  484. struct cached_loadcmd {
  485. void * mapstart;
  486. unsigned long mapsize;
  487. unsigned long mapoff;
  488. int mapprot;
  489. } loadcmds[MAX_CACHED_LOADCMDS];
  490. int nloadcmds;
  491. ElfW(Dyn) dyn[];
  492. };
  493. void cache_elf_object (PAL_HANDLE handle, struct link_map * map)
  494. {
  495. char uri[URI_MAX];
  496. unsigned long cached_size = 0;
  497. int ret = _DkStreamGetName(handle, uri, URI_MAX);
  498. if (ret < 0)
  499. return;
  500. strcpy_static(uri + ret, ".cached", URI_MAX - ret);
  501. PAL_HANDLE cached_file;
  502. while (1) {
  503. ret = _DkStreamOpen(&cached_file, uri,
  504. PAL_ACCESS_RDWR,
  505. PAL_SHARE_OWNER_W|PAL_SHARE_OWNER_R,
  506. PAL_CREAT_TRY|PAL_CREAT_ALWAYS, 0);
  507. if (ret != -PAL_ERROR_STREAMEXIST)
  508. break;
  509. if (_DkStreamOpen(&cached_file, uri, PAL_ACCESS_RDWR, 0, 0, 0) < 0)
  510. return;
  511. ret = _DkStreamDelete(cached_file, 0);
  512. _DkObjectClose(cached_file);
  513. if (ret < 0)
  514. return;
  515. }
  516. if (ret < 0)
  517. return;
  518. struct cached_elf_object * obj = NULL;
  519. unsigned long obj_size = sizeof(struct cached_elf_object);
  520. if (map->l_ld != map->l_real_ld)
  521. obj_size += sizeof(ElfW(Dyn)) * map->l_ldnum;
  522. obj_size = ALLOC_ALIGNUP(obj_size);
  523. cached_size = obj_size;
  524. ret = _DkStreamSetLength(cached_file, obj_size);
  525. if (ret < 0)
  526. goto out;
  527. ret = _DkStreamMap(cached_file, (void **) &obj,
  528. PAL_PROT_READ|PAL_PROT_WRITE, 0, obj_size);
  529. if (ret < 0)
  530. goto out;
  531. obj->instance_id = pal_state.instance_id;
  532. obj->loader_addr = (void *) DkStreamOpen;
  533. memcpy(&obj->map, map, sizeof(struct link_map));
  534. if (map->l_ld != map->l_real_ld) {
  535. obj->map.l_ld = NULL;
  536. memcpy(obj->dyn, map->l_ld, sizeof(ElfW(Dyn)) * map->l_ldnum);
  537. for (int i = 0 ;
  538. i < sizeof(obj->map.l_info) / sizeof(obj->map.l_info[0]) ;
  539. i++)
  540. if (obj->map.l_info[i])
  541. obj->map.l_info[i] =
  542. (void *) obj->map.l_info[i] - (unsigned long) map->l_ld;
  543. }
  544. obj->map.l_name = NULL;
  545. memcpy(obj->map_name, map->l_name, sizeof(obj->map_name));
  546. obj->nloadcmds = 0;
  547. const ElfW(Ehdr) * header = (void *) map->l_map_start;
  548. const ElfW(Phdr) * phdr = (void *) header + header->e_phoff, * ph;
  549. for (ph = phdr ; ph < &phdr[header->e_phnum] ; ph++)
  550. if (ph->p_type == PT_LOAD) {
  551. assert(obj->nloadcmds < MAX_CACHED_LOADCMDS);
  552. void * mapstart = (void *)
  553. ALLOC_ALIGNDOWN(map->l_addr + ph->p_vaddr);
  554. void * mapend = (void *)
  555. ALLOC_ALIGNUP(map->l_addr + ph->p_vaddr + ph->p_memsz);
  556. unsigned long mapsize = mapend - mapstart;
  557. int mapprot = 0;
  558. void * cache_addr = NULL;
  559. if (ph->p_flags & PF_R)
  560. mapprot |= PAL_PROT_READ;
  561. if (ph->p_flags & PF_W)
  562. mapprot |= PAL_PROT_WRITE;
  563. if (ph->p_flags & PF_X)
  564. mapprot |= PAL_PROT_EXEC;
  565. ret = _DkStreamSetLength(cached_file, cached_size + mapsize);
  566. if (ret < 0)
  567. goto out_mapped;
  568. ret = _DkStreamMap(cached_file, &cache_addr,
  569. PAL_PROT_READ|PAL_PROT_WRITE, cached_size,
  570. mapsize);
  571. if (ret < 0)
  572. goto out_mapped;
  573. obj->loadcmds[obj->nloadcmds].mapstart = mapstart;
  574. obj->loadcmds[obj->nloadcmds].mapsize = mapsize;
  575. obj->loadcmds[obj->nloadcmds].mapprot = mapprot;
  576. obj->loadcmds[obj->nloadcmds].mapoff = cached_size;
  577. obj->nloadcmds++;
  578. cached_size += mapsize;
  579. memcpy(cache_addr, mapstart, mapsize);
  580. ret = _DkStreamUnmap(cache_addr, mapsize);
  581. if (ret < 0)
  582. goto out_mapped;
  583. }
  584. ret = _DkStreamUnmap(obj, obj_size);
  585. if (ret < 0)
  586. return;
  587. _DkObjectClose(cached_file);
  588. return;
  589. out_mapped:
  590. _DkStreamUnmap(obj, obj_size);
  591. out:
  592. _DkStreamDelete(cached_file, 0);
  593. _DkObjectClose(cached_file);
  594. }
  595. struct link_map * check_cached_elf_object (PAL_HANDLE handle)
  596. {
  597. char uri[URI_MAX];
  598. int ret = _DkStreamGetName(handle, uri, URI_MAX);
  599. if (ret < 0)
  600. return NULL;
  601. strcpy_static(uri + ret, ".cached", URI_MAX - ret);
  602. PAL_HANDLE cached_file;
  603. ret = _DkStreamOpen(&cached_file, uri, PAL_ACCESS_RDWR, 0, 0, 0);
  604. if (ret < 0)
  605. return NULL;
  606. struct cached_elf_object * obj = NULL;
  607. unsigned long obj_size = ALLOC_ALIGNUP(sizeof(struct cached_elf_object));
  608. ret = _DkStreamMap(cached_file, (void **) &obj,
  609. PAL_PROT_READ|PAL_PROT_WRITE|PAL_PROT_WRITECOPY,
  610. 0, obj_size);
  611. if (ret < 0)
  612. goto out;
  613. /* we want to check if there is a previously cached one, but if the
  614. * process is the first one, force to update the cached binary. */
  615. if (pal_state.instance_id != obj->instance_id)
  616. goto out_mapped;
  617. if (!obj->map.l_ld) {
  618. obj->map.l_ld = obj->dyn;
  619. for (int i = 0 ;
  620. i < sizeof(obj->map.l_info) / sizeof(obj->map.l_info[0]) ;
  621. i++)
  622. if (obj->map.l_info[i])
  623. obj->map.l_info[i] =
  624. (void *) obj->map.l_info[i] + (unsigned long) obj->map.l_ld;
  625. }
  626. struct cached_loadcmd * l = obj->loadcmds;
  627. struct cached_loadcmd * last = &obj->loadcmds[obj->nloadcmds - 1];
  628. if (l < last) {
  629. ret = _DkStreamMap(cached_file, &l->mapstart,
  630. l->mapprot|PAL_PROT_WRITECOPY,
  631. l->mapoff,
  632. last->mapstart + last->mapsize - l->mapstart);
  633. if (ret < 0)
  634. goto out_more_mapped;
  635. ret = _DkVirtualMemoryProtect(l->mapstart + l->mapsize,
  636. last->mapstart - (l->mapstart + l->mapsize),
  637. PAL_PROT_NONE);
  638. if (ret < 0)
  639. goto out_more_mapped;
  640. l++;
  641. goto map_next;
  642. }
  643. for ( ; l <= last ; l++) {
  644. map_next:
  645. ret = _DkStreamMap(cached_file, &l->mapstart,
  646. l->mapprot|PAL_PROT_WRITECOPY,
  647. l->mapoff,
  648. l->mapsize);
  649. if (ret < 0)
  650. goto out_more_mapped;
  651. }
  652. if ((void *) DkStreamOpen != obj->loader_addr) {
  653. for (int i = 0 ; i < obj->map.nrelocs ; i++)
  654. *obj->map.relocs[i] += (void *) DkStreamOpen - obj->loader_addr;
  655. }
  656. obj->map.l_name = obj->map_name;
  657. return &obj->map;
  658. out_more_mapped:
  659. _DkStreamUnmap(obj->loadcmds[0].mapstart,
  660. last->mapstart + last->mapsize - obj->loadcmds[0].mapstart);
  661. out_mapped:
  662. _DkStreamUnmap(obj, obj_size);
  663. out:
  664. _DkObjectClose(cached_file);
  665. return NULL;
  666. }
  667. #endif /* CACHE_LOADED_BINARIES == 1 */
  668. int load_elf_object_by_handle (PAL_HANDLE handle, enum object_type type)
  669. {
  670. struct link_map * map = NULL;
  671. char fb[FILEBUF_SIZE], * errstring;
  672. int ret = 0;
  673. #if CACHE_LOADED_BINARIES == 1
  674. map = check_cached_elf_object(handle);
  675. if (map)
  676. goto done;
  677. #endif
  678. /* Now we will start verify the file as a ELF header. This part of code
  679. is borrow from open_verify() */
  680. ElfW(Ehdr) * ehdr = (ElfW(Ehdr) *) &fb;
  681. ElfW(Phdr) * phdr = NULL;
  682. int phdr_malloced = 0;
  683. int len = _DkStreamRead(handle, 0, FILEBUF_SIZE, &fb, NULL, 0);
  684. if (__builtin_expect (len < sizeof(ElfW(Ehdr)), 0)) {
  685. errstring = "ELF file with a strange size";
  686. goto verify_failed;
  687. }
  688. #define ELF32_CLASS ELFCLASS32
  689. #define ELF64_CLASS ELFCLASS64
  690. static const unsigned char expected[EI_NIDENT] =
  691. {
  692. [EI_MAG0] = ELFMAG0,
  693. [EI_MAG1] = ELFMAG1,
  694. [EI_MAG2] = ELFMAG2,
  695. [EI_MAG3] = ELFMAG3,
  696. [EI_CLASS] = ELFW(CLASS),
  697. [EI_DATA] = byteorder,
  698. [EI_VERSION] = EV_CURRENT,
  699. [EI_OSABI] = 0,
  700. };
  701. #define ELFOSABI_LINUX 3 /* Linux. */
  702. /* See whether the ELF header is what we expect. */
  703. if (__builtin_expect(
  704. memcmp(ehdr->e_ident, expected, EI_OSABI) != 0 || (
  705. ehdr->e_ident[EI_OSABI] != ELFOSABI_SYSV &&
  706. ehdr->e_ident[EI_OSABI] != ELFOSABI_LINUX), 0)) {
  707. errstring = "ELF file with invalid header";
  708. goto verify_failed;
  709. }
  710. /* Chia-Che 11/23/13: Removing other checks, comparing the header
  711. should be enough */
  712. int maplength = ehdr->e_phnum * sizeof (ElfW(Phdr));
  713. /* if e_phoff + maplength is smaller than the data read */
  714. if (ehdr->e_phoff + maplength <= (int) len) {
  715. phdr = (void *) (&fb + ehdr->e_phoff);
  716. } else {
  717. /* ...otherwise, we have to read again */
  718. phdr = malloc (maplength);
  719. phdr_malloced = 1;
  720. ret = _DkStreamRead(handle, ehdr->e_phoff, maplength, phdr, NULL, 0);
  721. if (ret < 0 || ret != maplength) {
  722. errstring = "cannot read file data";
  723. goto verify_failed;
  724. }
  725. }
  726. if (!(map = map_elf_object_by_handle(handle, type, &fb, len, true))) {
  727. errstring = "unexpected failure";
  728. goto verify_failed;
  729. }
  730. relocate_elf_object(map);
  731. #if CACHE_LOADED_BINARIES == 1
  732. cache_elf_object(handle, map);
  733. done:
  734. #endif
  735. if (loaded_maps)
  736. loaded_maps->l_prev = map;
  737. map->l_next = loaded_maps;
  738. map->l_prev = NULL;
  739. loaded_maps = map;
  740. if (map->l_type == OBJECT_EXEC)
  741. exec_map = map;
  742. #ifdef DEBUG
  743. _DkDebugAddMap(map);
  744. #endif
  745. return 0;
  746. verify_failed:
  747. if (phdr && phdr_malloced)
  748. free(phdr);
  749. printf("%s\n", errstring);
  750. return ret;
  751. }
  752. struct sym_val {
  753. ElfW(Sym) *s;
  754. struct link_map *m;
  755. };
  756. /* This is the hashing function specified by the ELF ABI. In the
  757. first five operations no overflow is possible so we optimized it a
  758. bit. */
  759. unsigned long int elf_hash (const char *name_arg)
  760. {
  761. const unsigned char *name = (const unsigned char *) name_arg;
  762. unsigned long int hash = 0;
  763. if (*name == '\0')
  764. return hash;
  765. hash = *name++;
  766. if (*name == '\0')
  767. return hash;
  768. hash = (hash << 4) + *name++;
  769. if (*name == '\0')
  770. return hash;
  771. hash = (hash << 4) + *name++;
  772. if (*name == '\0')
  773. return hash;
  774. hash = (hash << 4) + *name++;
  775. if (*name == '\0')
  776. return hash;
  777. hash = (hash << 4) + *name++;
  778. while (*name != '\0') {
  779. unsigned long int hi;
  780. hash = (hash << 4) + *name++;
  781. hi = hash & 0xf0000000;
  782. /*
  783. * The algorithm specified in the ELF ABI is as follows:
  784. * if (hi != 0)
  785. * hash ^= hi >> 24;
  786. * hash &= ~hi;
  787. * But the following is equivalent and a lot faster, especially on
  788. * modern processors.
  789. */
  790. hash ^= hi;
  791. hash ^= hi >> 24;
  792. }
  793. return hash;
  794. }
  795. /* Nested routine to check whether the symbol matches. */
  796. static inline __attribute_always_inline
  797. ElfW(Sym) * check_match(ElfW(Sym) * sym, ElfW(Sym) * ref, const char * undef_name,
  798. const char * strtab)
  799. {
  800. unsigned int stt = ELFW(ST_TYPE) (sym->st_info);
  801. assert(ELF_RTYPE_CLASS_PLT == 1);
  802. if (__builtin_expect((sym->st_value == 0 /* No value. */
  803. && stt != STT_TLS)
  804. || sym->st_shndx == SHN_UNDEF, 0))
  805. return NULL;
  806. /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC,
  807. STT_COMMON, STT_TLS, and STT_GNU_IFUNC since these are no
  808. code/data definitions. */
  809. #define ALLOWED_STT \
  810. ((1 << STT_NOTYPE) | (1 << STT_OBJECT) | (1 << STT_FUNC) \
  811. | (1 << STT_COMMON) | (1 << STT_TLS) | (1 << STT_GNU_IFUNC))
  812. if (__builtin_expect(((1 << stt) & ALLOWED_STT) == 0, 0))
  813. return NULL;
  814. if (sym != ref && memcmp(strtab + sym->st_name, undef_name,
  815. strlen(undef_name)))
  816. /* Not the symbol we are looking for. */
  817. return NULL;
  818. /* There cannot be another entry for this symbol so stop here. */
  819. return sym;
  820. }
  821. ElfW(Sym) *
  822. do_lookup_map (ElfW(Sym) * ref, const char * undef_name,
  823. const uint_fast32_t hash, unsigned long int elf_hash,
  824. const struct link_map * map)
  825. {
  826. /* These variables are used in the nested function. */
  827. Elf_Symndx symidx;
  828. ElfW(Sym) * sym;
  829. /* The tables for this map. */
  830. ElfW(Sym) * symtab = (void *) D_PTR (map->l_info[DT_SYMTAB]);
  831. const char * strtab = (const void *) D_PTR (map->l_info[DT_STRTAB]);
  832. const ElfW(Addr) * bitmask = map->l_gnu_bitmask;
  833. if (__builtin_expect (bitmask != NULL, 1)) {
  834. ElfW(Addr) bitmask_word = bitmask[(hash / __ELF_NATIVE_CLASS)
  835. & map->l_gnu_bitmask_idxbits];
  836. unsigned int hashbit1 = hash & (__ELF_NATIVE_CLASS - 1);
  837. unsigned int hashbit2 = (hash >> map->l_gnu_shift)
  838. & (__ELF_NATIVE_CLASS - 1);
  839. if (__builtin_expect ((bitmask_word >> hashbit1)
  840. & (bitmask_word >> hashbit2) & 1, 0)) {
  841. Elf32_Word bucket = map->l_gnu_buckets
  842. [hash % map->l_nbuckets];
  843. if (bucket != 0) {
  844. const Elf32_Word *hasharr = &map->l_gnu_chain_zero[bucket];
  845. do
  846. if (((*hasharr ^ hash) >> 1) == 0) {
  847. symidx = hasharr - map->l_gnu_chain_zero;
  848. sym = check_match (&symtab[symidx], ref, undef_name, strtab);
  849. if (sym != NULL)
  850. return sym;
  851. }
  852. while ((*hasharr++ & 1u) == 0);
  853. }
  854. }
  855. /* No symbol found. */
  856. symidx = SHN_UNDEF;
  857. } else {
  858. /* Use the old SysV-style hash table. Search the appropriate
  859. hash bucket in this object's symbol table for a definition
  860. for the same symbol name. */
  861. for (symidx = map->l_buckets[elf_hash % map->l_nbuckets];
  862. symidx != STN_UNDEF;
  863. symidx = map->l_chain[symidx]) {
  864. sym = check_match (&symtab[symidx], ref, undef_name, strtab);
  865. if (sym != NULL)
  866. return sym;
  867. }
  868. }
  869. return NULL;
  870. }
  871. /* Inner part of the lookup functions. We return a value > 0 if we
  872. found the symbol, the value 0 if nothing is found and < 0 if
  873. something bad happened. */
  874. static int do_lookup (const char * undef_name, ElfW(Sym) * ref,
  875. struct sym_val * result)
  876. {
  877. const uint_fast32_t fast_hash = elf_fast_hash(undef_name);
  878. const long int hash = elf_hash(undef_name);
  879. ElfW(Sym) * sym;
  880. struct link_map * map = loaded_maps;
  881. struct sym_val weak_result = { .s = NULL, .m = NULL };
  882. for (; map ; map = map->l_next) {
  883. sym = do_lookup_map(ref, undef_name, fast_hash, hash, map);
  884. if (!sym)
  885. continue;
  886. switch (__builtin_expect (ELFW(ST_BIND) (sym->st_info), STB_GLOBAL)) {
  887. case STB_WEAK:
  888. /* Weak definition. Use this value if we don't find another. */
  889. if (!weak_result.s) {
  890. weak_result.s = sym;
  891. weak_result.m = (struct link_map *) map;
  892. }
  893. break;
  894. /* FALLTHROUGH */
  895. case STB_GLOBAL:
  896. case STB_GNU_UNIQUE:
  897. /* success: */
  898. /* Global definition. Just what we need. */
  899. result->s = sym;
  900. result->m = (struct link_map *) map;
  901. return 1;
  902. default:
  903. /* Local symbols are ignored. */
  904. break;
  905. }
  906. }
  907. if (weak_result.s) {
  908. *result = weak_result;
  909. return 1;
  910. }
  911. /* We have not found anything until now. */
  912. return 0;
  913. }
  914. /* Search loaded objects' symbol tables for a definition of the symbol
  915. UNDEF_NAME, perhaps with a requested version for the symbol.
  916. We must never have calls to the audit functions inside this function
  917. or in any function which gets called. If this would happen the audit
  918. code might create a thread which can throw off all the scope locking. */
  919. struct link_map * lookup_symbol (const char * undef_name, ElfW(Sym) ** ref)
  920. {
  921. struct sym_val current_value = { NULL, NULL };
  922. do_lookup(undef_name, *ref, &current_value);
  923. if (__builtin_expect (current_value.s == NULL, 0)) {
  924. *ref = NULL;
  925. return NULL;
  926. }
  927. *ref = current_value.s;
  928. return current_value.m;
  929. }
  930. static int protect_relro (struct link_map * l)
  931. {
  932. ElfW(Addr) start = ALLOC_ALIGNDOWN(l->l_addr + l->l_relro_addr);
  933. ElfW(Addr) end = ALLOC_ALIGNUP(l->l_addr + l->l_relro_addr +
  934. l->l_relro_size);
  935. if (start != end)
  936. _DkVirtualMemoryProtect((void *) start, end - start, PAL_PROT_READ);
  937. return 0;
  938. }
  939. static int relocate_elf_object (struct link_map * l)
  940. {
  941. struct textrels {
  942. ElfW(Addr) start;
  943. ElfW(Addr) len;
  944. int prot;
  945. struct textrels * next;
  946. } * textrels = NULL;
  947. int ret;
  948. const ElfW(Phdr) * ph;
  949. for (ph = l->l_phdr ; ph < &l->l_phdr[l->l_phnum] ; ph++)
  950. if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0) {
  951. struct textrels * r = malloc(sizeof(struct textrels));
  952. r->start = ALLOC_ALIGNDOWN(ph->p_vaddr) + l->l_addr;
  953. r->len = ALLOC_ALIGNUP(ph->p_vaddr + ph->p_memsz)
  954. - ALLOC_ALIGNDOWN(ph->p_vaddr);
  955. ret = _DkVirtualMemoryProtect((void *) r->start, r->len,
  956. PAL_PROT_READ|PAL_PROT_WRITE);
  957. if (ret < 0)
  958. return ret;
  959. r->prot = 0;
  960. if (ph->p_flags & PF_R)
  961. r->prot |= PAL_PROT_READ;
  962. if (ph->p_flags & PF_W)
  963. r->prot |= PAL_PROT_WRITE;
  964. if (ph->p_flags & PF_X)
  965. r->prot |= PAL_PROT_EXEC;
  966. r->next = textrels;
  967. textrels = r;
  968. }
  969. #if PROFILING == 1
  970. unsigned long before_relocate = _DkSystemTimeQuery();
  971. #endif
  972. /* Do the actual relocation of the object's GOT and other data. */
  973. ELF_DYNAMIC_RELOCATE(l);
  974. #if PROFILING == 1
  975. pal_state.relocation_time += _DkSystemTimeQuery() - before_relocate;
  976. #endif
  977. while (textrels) {
  978. ret = _DkVirtualMemoryProtect((void *) textrels->start, textrels->len,
  979. textrels->prot);
  980. if (ret < 0)
  981. return ret;
  982. struct textrels * next = textrels->next;
  983. free(textrels);
  984. textrels = next;
  985. }
  986. /* In case we can protect the data now that the relocations are
  987. done, do it. */
  988. if (l->l_type != OBJECT_EXEC && l->l_relro_size != 0)
  989. if ((ret = protect_relro(l)) < 0)
  990. return ret;
  991. return 0;
  992. }
  993. void DkDebugAttachBinary (PAL_STR uri, PAL_PTR start_addr)
  994. {
  995. #ifdef DEBUG
  996. if (!strpartcmp_static(uri, "file:"))
  997. return;
  998. const char * realname = uri + static_strlen("file:");
  999. struct link_map * l = new_elf_object(realname, OBJECT_EXTERNAL);
  1000. /* This is the ELF header. We read it in `open_verify'. */
  1001. const ElfW(Ehdr) * header = (ElfW(Ehdr) *) start_addr;
  1002. l->l_entry = header->e_entry;
  1003. l->l_phnum = header->e_phnum;
  1004. l->l_map_start = (ElfW(Addr)) start_addr;
  1005. ElfW(Phdr) * phdr = (void *) ((char *) start_addr + header->e_phoff);
  1006. const ElfW(Phdr) * ph;
  1007. ElfW(Addr) map_start = 0, map_end = 0;
  1008. for (ph = phdr; ph < &phdr[l->l_phnum]; ++ph)
  1009. if (ph->p_type == PT_PHDR) {
  1010. if (!map_start || ph->p_vaddr < map_start)
  1011. map_start = ph->p_vaddr;
  1012. if (!map_end || ph->p_vaddr + ph->p_memsz > map_end)
  1013. map_end = ph->p_vaddr + ph->p_memsz;
  1014. }
  1015. l->l_addr = l->l_map_start - map_start;
  1016. l->l_map_end = l->l_addr + map_end;
  1017. for (ph = phdr; ph < &phdr[l->l_phnum]; ++ph)
  1018. switch (ph->p_type) {
  1019. /* These entries tell us where to find things once the file's
  1020. segments are mapped in. We record the addresses it says
  1021. verbatim, and later correct for the run-time load address. */
  1022. case PT_DYNAMIC:
  1023. l->l_ld = l->l_real_ld = (ElfW(Dyn) *)
  1024. ((char *) l->l_addr + ph->p_vaddr);
  1025. l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
  1026. break;
  1027. case PT_PHDR:
  1028. l->l_phdr = (ElfW(Phdr) *) ((char *) l->l_addr + ph->p_vaddr);
  1029. break;
  1030. case PT_GNU_RELRO:
  1031. l->l_relro_addr = l->l_addr + ph->p_vaddr;
  1032. l->l_relro_size = ph->p_memsz;
  1033. break;
  1034. }
  1035. _DkDebugAddMap(l);
  1036. #endif
  1037. }
  1038. void DkDebugDetachBinary (PAL_PTR start_addr)
  1039. {
  1040. #ifdef DEBUG
  1041. for (struct link_map * l = loaded_maps; l; l = l->l_next)
  1042. if (l->l_map_start == (ElfW(Addr)) start_addr) {
  1043. _DkDebugDelMap(l);
  1044. if (l->l_type == OBJECT_EXTERNAL)
  1045. free_elf_object(l);
  1046. break;
  1047. }
  1048. #endif
  1049. }
  1050. #ifndef CALL_ENTRY
  1051. #ifdef __x86_64__
  1052. void * stack_before_call __attribute_unused = NULL;
  1053. #define CALL_ENTRY(l, cookies) \
  1054. ({ long ret; \
  1055. asm volatile("movq %%rsp, stack_before_call(%%rip)\r\n" \
  1056. "leaq 1f(%%rip), %%rdx\r\n" \
  1057. "movq %2, %%rsp\r\n" \
  1058. "jmp *%1\r\n" \
  1059. "1: movq stack_before_call(%%rip), %%rsp\r\n" \
  1060. \
  1061. : "=a"(ret) : "a"(l->l_entry), "b"(cookies) \
  1062. : "rcx", "rdx", "rdi", "rsi", "r8", "r9", \
  1063. "r10", "r11", "memory"); \
  1064. ret; })
  1065. #else
  1066. # error "unsupported architecture"
  1067. #endif
  1068. #endif /* !CALL_ENTRY */
  1069. void start_execution (const char * first_argument, const char ** arguments,
  1070. const char ** environs)
  1071. {
  1072. /* First we will try to run all the preloaded libraries which come with
  1073. entry points */
  1074. if (exec_map) {
  1075. __pal_control.executable_range.start = (PAL_PTR) exec_map->l_map_start;
  1076. __pal_control.executable_range.end = (PAL_PTR) exec_map->l_map_end;
  1077. }
  1078. #if PROFILING == 1
  1079. unsigned long before_tail = _DkSystemTimeQuery();
  1080. #endif
  1081. int narguments = 0;
  1082. if (first_argument)
  1083. narguments++;
  1084. for (const char ** a = arguments; *a ; a++, narguments++);
  1085. /* Let's count the number of cookies, first we will have argc & argv */
  1086. int ncookies = narguments + 3; /* 1 for argc, argc + 2 for argv */
  1087. /* Then we count envp */
  1088. for (const char ** e = environs; *e; e++)
  1089. ncookies++;
  1090. ncookies++; /* for NULL-end */
  1091. int cookiesz = sizeof(unsigned long int) * ncookies
  1092. + sizeof(ElfW(auxv_t)) * 6
  1093. + sizeof(void *) * 4 + 16;
  1094. unsigned long int * cookies = __alloca(cookiesz);
  1095. int cnt = 0;
  1096. /* Let's copy the cookies */
  1097. cookies[cnt++] = (unsigned long int) narguments;
  1098. if (first_argument)
  1099. cookies[cnt++] = (unsigned long int) first_argument;
  1100. for (int i = 0 ; arguments[i] ; i++)
  1101. cookies[cnt++] = (unsigned long int) arguments[i];
  1102. cookies[cnt++] = 0;
  1103. for (int i = 0 ; environs[i]; i++)
  1104. cookies[cnt++] = (unsigned long int) environs[i];
  1105. cookies[cnt++] = 0;
  1106. ElfW(auxv_t) * auxv = (ElfW(auxv_t) *) &cookies[cnt];
  1107. auxv[0].a_type = AT_PHDR;
  1108. auxv[0].a_un.a_val = exec_map ? (unsigned long) exec_map->l_phdr : 0;
  1109. auxv[1].a_type = AT_PHNUM;
  1110. auxv[1].a_un.a_val = exec_map ? exec_map->l_phnum : 0;
  1111. auxv[2].a_type = AT_PAGESZ;
  1112. auxv[2].a_un.a_val = __pal_control.pagesize;
  1113. auxv[3].a_type = AT_ENTRY;
  1114. auxv[3].a_un.a_val = exec_map ? exec_map->l_entry : 0;
  1115. auxv[4].a_type = AT_BASE;
  1116. auxv[4].a_un.a_val = exec_map ? exec_map->l_addr : 0;
  1117. auxv[5].a_type = AT_NULL;
  1118. *(void **) &auxv[6] = NULL;
  1119. #if PROFILING == 1
  1120. __pal_control.startup_time = _DkSystemTimeQuery() - pal_state.start_time;
  1121. __pal_control.tail_startup_time =
  1122. pal_state.tail_startup_time += _DkSystemTimeQuery() - before_tail;
  1123. #endif
  1124. struct link_map * l = loaded_maps;
  1125. /* run entry point in reverse order */
  1126. for (; l->l_next ; l = l->l_next);
  1127. for (; l ; l = l->l_prev)
  1128. if (l->l_type == OBJECT_PRELOAD && l->l_entry)
  1129. CALL_ENTRY(l, cookies);
  1130. if (exec_map)
  1131. CALL_ENTRY(exec_map, cookies);
  1132. _DkThreadExit();
  1133. }