1 #include <stdio.h>
2 #include <common.h>
3 #include <debug.h>
4 #include <libelf.h>
5 #include <libebl.h>
6 #ifdef ARM_SPECIFIC_HACKS
7 #include <libebl_arm.h>
8 #endif/*ARM_SPECIFIC_HACKS*/
9 #include <elf.h>
10 #include <gelf.h>
11 #include <string.h>
12 #include <errno.h>
13 #include <string.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18 #include <hash.h>
19 #include <apriori.h>
20 #include <source.h>
21 #include <tweak.h>
22 #include <rangesort.h>
23 #include <prelink_info.h>
24 #include <prelinkmap.h>
25 #include <libgen.h>
26
27 #ifndef ADJUST_ELF
28 #error "ADJUST_ELF must be defined!"
29 #endif
30
31 /* When this macro is defined, apriori sets to ZERO those relocation values for
32 which it canot find the appropriate referent.
33 */
34 #define PERMISSIVE
35 #define COPY_SECTION_DATA_BUFFER (0)
36 /* When this macro is set to a nonzero value, we replace calls to elf_strptr()
37 on the target ELF handle with code that extracts the strings directly from
38 the data buffers of that ELF handle. In this case, elf_strptr() does not
39 work as expected, as it tries to read the data buffer of the associated
40 string section directly from the file, and that buffer does not exist yet
41 in the file, since we haven't committed our changes yet.
42 */
43 #define ELF_STRPTR_IS_BROKEN (1)
44
45 /* When the macro below is defined, apriori does not mark for removal those
46 relocation sections that it fully handles. Instead, apriori just sets their
47 sizes to zero. This is more for debugging than of any actual use.
48
49 This macro is meaningful only when ADJUST_ELF!=0
50 */
51 #define REMOVE_HANDLED_SECTIONS
52
53 extern int verbose_flag;
54
55 static source_t *sources = NULL;
56
57 #if defined(DEBUG) && 0
58
print_shdr(source_t * source,Elf_Scn * scn)59 static void print_shdr(source_t *source, Elf_Scn *scn)
60 {
61 GElf_Shdr shdr_mem, *shdr;
62 shdr = gelf_getshdr(scn, &shdr_mem);
63 Elf_Data *data = elf_getdata(scn, NULL);
64 INFO("\t%02d: data = %p, hdr = { offset = %8lld, size = %lld }, "
65 "data->d_buf = %p data->d_off = %lld, data->d_size = %d\n",
66 elf_ndxscn(scn),
67 data,
68 shdr->sh_offset, shdr->sh_size,
69 data->d_buf, data->d_off, data->d_size);
70 }
71
print_shdr_idx(source_t * source,Elf * elf,int idx)72 static void print_shdr_idx(source_t *source, Elf *elf, int idx)
73 {
74 print_shdr(source, elf_getscn(elf, idx));
75 }
76
print_shdrs(source_t * source)77 static void print_shdrs(source_t *source) {
78 Elf_Scn *scn = NULL;
79 INFO("section offset dump for new ELF\n");
80 while ((scn = elf_nextscn (source->elf, scn)) != NULL)
81 print_shdr(source, scn);
82
83 INFO("\nsection offset dump for original ELF\n");
84 while ((scn = elf_nextscn (source->oldelf, scn)) != NULL)
85 print_shdr(source, scn);
86
87 #if 0
88 {
89 INFO("section offset dump for new ELF\n");
90 int i = 0;
91 for (i = 0; i < source->shnum; i++) {
92 scn = elf_getscn(source->elf, i);
93 print_shdr(source, scn);
94 }
95 }
96 #endif
97 }
98
99 #endif /* DEBUG */
100
101 static char * find_file(const char *libname,
102 char **lib_lookup_dirs,
103 int num_lib_lookup_dirs);
104
find_source(const char * name,char ** lib_lookup_dirs,int num_lib_lookup_dirs)105 static inline source_t* find_source(const char *name,
106 char **lib_lookup_dirs,
107 int num_lib_lookup_dirs) {
108 char *full = find_file(name, lib_lookup_dirs, num_lib_lookup_dirs);
109 if (full) {
110 source_t *trav = sources;
111 while (trav) {
112 if (!strcmp(trav->name, full))
113 break;
114 trav = trav->next;
115 }
116 free(full);
117 return trav;
118 }
119 return NULL;
120 }
121
add_to_sources(source_t * src)122 static inline void add_to_sources(source_t *src) {
123 src->next = sources;
124 sources = src;
125 }
126
handle_range_error(range_error_t err,range_t * left,range_t * right)127 static void handle_range_error(range_error_t err,
128 range_t *left, range_t *right) {
129 switch (err) {
130 case ERROR_CONTAINS:
131 ERROR("ERROR: section (%lld, %lld bytes) contains "
132 "section (%lld, %lld bytes)\n",
133 left->start, left->length,
134 right->start, right->length);
135 break;
136 case ERROR_OVERLAPS:
137 ERROR("ERROR: Section (%lld, %lld bytes) intersects "
138 "section (%lld, %lld bytes)\n",
139 left->start, left->length,
140 right->start, right->length);
141 break;
142 default:
143 ASSERT(!"Unknown range error code!");
144 }
145
146 FAILIF(1, "Range error.\n");
147 }
148
create_elf_sections(source_t * source,Elf * elf)149 static void create_elf_sections(source_t *source, Elf *elf)
150 {
151 INFO("Creating new ELF sections.\n");
152 ASSERT(elf == NULL || source->elf == NULL || source->elf == elf);
153 if (elf == NULL) {
154 ASSERT(source->elf != NULL);
155 elf = source->elf;
156 }
157
158 int cnt = 1;
159 Elf_Scn *oldscn = NULL, *scn;
160 while ((oldscn = elf_nextscn (source->oldelf, oldscn)) != NULL) {
161 GElf_Shdr *oldshdr, oldshdr_mem;
162
163 scn = elf_newscn(elf);
164 FAILIF_LIBELF(NULL == scn, elf_newscn);
165
166 oldshdr = gelf_getshdr(oldscn, &oldshdr_mem);
167 FAILIF_LIBELF(NULL == oldshdr, gelf_getshdr);
168 /* Set the section header of the new section to be the same as the
169 headset of the old section by default. */
170 gelf_update_shdr(scn, oldshdr);
171
172 /* Copy the section data */
173 Elf_Data *olddata = elf_getdata(oldscn, NULL);
174 FAILIF_LIBELF(NULL == olddata, elf_getdata);
175
176 Elf_Data *data = elf_newdata(scn);
177 FAILIF_LIBELF(NULL == data, elf_newdata);
178 *data = *olddata;
179 #if COPY_SECTION_DATA_BUFFER
180 if (olddata->d_buf != NULL) {
181 data->d_buf = MALLOC(data->d_size);
182 memcpy(data->d_buf, olddata->d_buf, olddata->d_size);
183 }
184 #endif
185
186 INFO("\tsection %02d: [%-30s] created\n",
187 cnt,
188 elf_strptr(source->oldelf,
189 source->shstrndx,
190 oldshdr->sh_name));
191
192 if (ADJUST_ELF) {
193 ASSERT(source->shdr_info != NULL);
194 /* Create a new section. */
195 source->shdr_info[cnt].idx = cnt;
196 source->shdr_info[cnt].newscn = scn;
197 source->shdr_info[cnt].data = data;
198 source->shdr_info[cnt].
199 use_old_shdr_for_relocation_calculations = 1;
200 INFO("\tsection [%s] (old offset %lld, old size %lld) "
201 "will have index %d (was %d).\n",
202 source->shdr_info[cnt].name,
203 source->shdr_info[cnt].old_shdr.sh_offset,
204 source->shdr_info[cnt].old_shdr.sh_size,
205 source->shdr_info[cnt].idx,
206 elf_ndxscn(source->shdr_info[cnt].scn));
207 /* Same as the next assert */
208 ASSERT(elf_ndxscn (source->shdr_info[cnt].newscn) ==
209 source->shdr_info[cnt].idx);
210 }
211
212 ASSERT(elf_ndxscn(scn) == (size_t)cnt);
213 cnt++;
214 }
215 }
216
217 /* This function sets up the shdr_info[] array of a source_t. We call it only
218 when ADJUST_ELF is non-zero (i.e., support for adjusting an ELF file for
219 changes in sizes and numbers of relocation sections is compiled in. Note
220 that setup_shdr_info() depends only on the information in source->oldelf,
221 not on source->elf.
222 */
223
setup_shdr_info(source_t * source)224 static void setup_shdr_info(source_t *source)
225 {
226 if (ADJUST_ELF)
227 {
228 /* Allocate the section-header-info buffer. */
229 INFO("Allocating section-header info structure (%d) bytes...\n",
230 source->shnum * sizeof (shdr_info_t));
231
232 source->shdr_info = (shdr_info_t *)CALLOC(source->shnum,
233 sizeof (shdr_info_t));
234
235 /* Mark the SHT_NULL section as handled. */
236 source->shdr_info[0].idx = 2;
237
238 int cnt = 1;
239 Elf_Scn *oldscn = NULL;
240 while ((oldscn = elf_nextscn (source->oldelf, oldscn)) != NULL) {
241 /* Copy the section header */
242 ASSERT(elf_ndxscn(oldscn) == (size_t)cnt);
243
244 /* Initialized the corresponding shdr_info entry */
245 {
246 /* Mark the section with a non-zero index. Later, when we
247 decide to drop a section, we will set its idx to zero, and
248 assign section numbers to the remaining sections.
249 */
250 source->shdr_info[cnt].idx = 1;
251
252 source->shdr_info[cnt].scn = oldscn;
253
254 /* NOTE: Here we pupulate the section-headset struct with the
255 same values as the original section's. After the
256 first run of prelink(), we will update the sh_size
257 fields of those sections that need resizing.
258 */
259 FAILIF_LIBELF(NULL ==
260 gelf_getshdr(oldscn,
261 &source->shdr_info[cnt].shdr),
262 gelf_getshdr);
263
264 /* Get the name of the section. */
265 source->shdr_info[cnt].name =
266 elf_strptr (source->oldelf, source->shstrndx,
267 source->shdr_info[cnt].shdr.sh_name);
268
269 INFO("\tname: %s\n", source->shdr_info[cnt].name);
270 FAILIF(source->shdr_info[cnt].name == NULL,
271 "Malformed file: section %d name is null\n",
272 cnt);
273
274 /* Remember the shdr.sh_link value. We need to remember this
275 value for those sections that refer to other sections. For
276 example, we need to remember it for relocation-entry
277 sections, because if we modify the symbol table that a
278 relocation-entry section is relative to, then we need to
279 patch the relocation section. By the time we get to
280 deciding whether we need to patch the relocation section, we
281 will have overwritten its header's sh_link field with a new
282 value.
283 */
284 source->shdr_info[cnt].old_shdr = source->shdr_info[cnt].shdr;
285 INFO("\t\toriginal sh_link: %08d\n",
286 source->shdr_info[cnt].old_shdr.sh_link);
287 INFO("\t\toriginal sh_addr: %lld\n",
288 source->shdr_info[cnt].old_shdr.sh_addr);
289 INFO("\t\toriginal sh_offset: %lld\n",
290 source->shdr_info[cnt].old_shdr.sh_offset);
291 INFO("\t\toriginal sh_size: %lld\n",
292 source->shdr_info[cnt].old_shdr.sh_size);
293
294 FAILIF(source->shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX,
295 "Cannot handle sh_type SHT_SYMTAB_SHNDX!\n");
296 FAILIF(source->shdr_info[cnt].shdr.sh_type == SHT_GROUP,
297 "Cannot handle sh_type SHT_GROUP!\n");
298 FAILIF(source->shdr_info[cnt].shdr.sh_type == SHT_GNU_versym,
299 "Cannot handle sh_type SHT_GNU_versym!\n");
300 }
301
302 cnt++;
303 } /* for each section */
304 } /* if (ADJUST_ELF) */
305 }
306
init_elf(source_t * source,bool create_new_sections)307 static Elf * init_elf(source_t *source, bool create_new_sections)
308 {
309 Elf *elf;
310 if (source->output != NULL) {
311 if (source->output_is_dir) {
312 source->output_is_dir++;
313 char *dir = source->output;
314 int dirlen = strlen(dir);
315 /* The main() function maintains a pointer to source->output; it
316 frees the buffer after apriori() returns.
317 */
318 source->output = MALLOC(dirlen +
319 1 + /* slash */
320 strlen(source->name) +
321 1); /* null terminator */
322 strcpy(source->output, dir);
323 source->output[dirlen] = '/';
324 strcpy(source->output + dirlen + 1,
325 basename(source->name));
326 }
327
328 source->newelf_fd = open(source->output,
329 O_RDWR | O_CREAT,
330 0666);
331 FAILIF(source->newelf_fd < 0, "open(%s): %s (%d)\n",
332 source->output,
333 strerror(errno),
334 errno);
335 elf = elf_begin(source->newelf_fd, ELF_C_WRITE, NULL);
336 FAILIF_LIBELF(elf == NULL, elf_begin);
337 } else {
338 elf = elf_clone(source->oldelf, ELF_C_EMPTY);
339 FAILIF_LIBELF(elf == NULL, elf_clone);
340 }
341
342 GElf_Ehdr *oldehdr = gelf_getehdr(source->oldelf, &source->old_ehdr_mem);
343 FAILIF_LIBELF(NULL == oldehdr, gelf_getehdr);
344
345 /* Create new ELF and program headers for the elf file */
346 INFO("Creating empty ELF and program headers...\n");
347 FAILIF_LIBELF(gelf_newehdr (elf, gelf_getclass (source->oldelf)) == 0,
348 gelf_newehdr);
349 FAILIF_LIBELF(oldehdr->e_type != ET_REL
350 && gelf_newphdr (elf,
351 oldehdr->e_phnum) == 0,
352 gelf_newphdr);
353
354 /* Copy the elf header */
355 INFO("Copying ELF header...\n");
356 GElf_Ehdr *ehdr = gelf_getehdr(elf, &source->ehdr_mem);
357 FAILIF_LIBELF(NULL == ehdr, gelf_getehdr);
358 memcpy(ehdr, oldehdr, sizeof(GElf_Ehdr));
359 FAILIF_LIBELF(!gelf_update_ehdr(elf, ehdr), gelf_update_ehdr);
360
361 /* Copy out the old program header: notice that if the ELF file does not
362 have a program header, this loop won't execute.
363 */
364 INFO("Copying ELF program header...\n");
365 {
366 int cnt;
367 source->phdr_info = (GElf_Phdr *)CALLOC(ehdr->e_phnum,
368 sizeof(GElf_Phdr));
369 for (cnt = 0; cnt < ehdr->e_phnum; ++cnt) {
370 INFO("\tRetrieving entry %d\n", cnt);
371 FAILIF_LIBELF(NULL ==
372 gelf_getphdr(source->oldelf, cnt,
373 source->phdr_info + cnt),
374 gelf_getphdr);
375 FAILIF_LIBELF(gelf_update_phdr (elf, cnt,
376 source->phdr_info + cnt) == 0,
377 gelf_update_phdr);
378 }
379 }
380
381 /* Copy the sections and the section headers. */
382 if (create_new_sections)
383 {
384 create_elf_sections(source, elf);
385 }
386
387 /* The ELF library better follows our layout when this is not a
388 relocatable object file. */
389 elf_flagelf (elf, ELF_C_SET, (ehdr->e_type != ET_REL ? ELF_F_LAYOUT : 0));
390
391 return elf;
392 }
393
lookup_shdr_info_by_new_section(source_t * source,const char * sname,Elf_Scn * newscn)394 static shdr_info_t *lookup_shdr_info_by_new_section(
395 source_t *source,
396 const char *sname,
397 Elf_Scn *newscn)
398 {
399 if (source->shdr_info == NULL) return NULL;
400 int cnt;
401 for (cnt = 0; cnt < source->shnum; cnt++) {
402 if (source->shdr_info[cnt].newscn == newscn) {
403 INFO("\t\tnew section at %p matches shdr_info[%d], "
404 "section [%s]!\n",
405 newscn,
406 cnt,
407 source->shdr_info[cnt].name);
408 FAILIF(strcmp(sname, source->shdr_info[cnt].name),
409 "Matched section's name [%s] does not match "
410 "looked-up section's name [%s]!\n",
411 source->shdr_info[cnt].name,
412 sname);
413 return source->shdr_info + cnt;
414 }
415 }
416 return NULL;
417 }
418
do_init_source(source_t * source,unsigned base)419 static bool do_init_source(source_t *source, unsigned base)
420 {
421 /* Find various sections. */
422 size_t scnidx;
423 Elf_Scn *scn;
424 GElf_Shdr *shdr, shdr_mem;
425 source->sorted_sections = init_range_list();
426 INFO("Processing [%s]'s sections...\n", source->name);
427 for (scnidx = 1; scnidx < (size_t)source->shnum; scnidx++) {
428 INFO("\tGetting section index %d...\n", scnidx);
429 scn = elf_getscn(source->elf, scnidx);
430 if (NULL == scn) {
431 /* If we get an error from elf_getscn(), it means that a section
432 at the requested index does not exist. This may happen when
433 we remove sections. Since we do not update source->shnum
434 (we can't, since we need to know the original number of sections
435 to know source->shdr_info[]'s length), we will attempt to
436 retrieve a section for an index that no longer exists in the
437 new ELF file. */
438 INFO("\tThere is no section at index %d anymore, continuing.\n",
439 scnidx);
440 continue;
441 }
442 shdr = gelf_getshdr(scn, &shdr_mem);
443 FAILIF_LIBELF(NULL == shdr, gelf_getshdr);
444
445 /* We haven't modified the shstrtab section, and so shdr->sh_name
446 has the same value as before. Thus we look up the name based
447 on the old ELF handle. We cannot use shstrndx on the new ELF
448 handle because the index of the shstrtab section may have
449 changed (and calling elf_getshstrndx() returns the same section
450 index, so libelf can't handle thise ither).
451 */
452 const char *sname =
453 elf_strptr(source->oldelf, source->shstrndx, shdr->sh_name);
454 ASSERT(sname);
455
456 INFO("\tAdding [%s] (%lld, %lld)...\n",
457 sname,
458 shdr->sh_addr,
459 shdr->sh_addr + shdr->sh_size);
460 if ((shdr->sh_flags & SHF_ALLOC) == SHF_ALLOC) {
461 add_unique_range_nosort(source->sorted_sections,
462 shdr->sh_addr,
463 shdr->sh_size,
464 scn,
465 handle_range_error,
466 NULL); /* no user-data destructor */
467 }
468
469 if (shdr->sh_type == SHT_DYNSYM) {
470 source->symtab.scn = scn;
471 source->symtab.data = elf_getdata(scn, NULL);
472 FAILIF_LIBELF(NULL == source->symtab.data, elf_getdata);
473 memcpy(&source->symtab.shdr, shdr, sizeof(GElf_Shdr));
474 source->symtab.info = lookup_shdr_info_by_new_section(
475 source, sname, scn);
476 ASSERT(source->shdr_info == NULL || source->symtab.info != NULL);
477
478 /* The sh_link field of the section header of the symbol table
479 contains the index of the associated strings table. */
480 source->strtab.scn = elf_getscn(source->elf,
481 source->symtab.shdr.sh_link);
482 FAILIF_LIBELF(NULL == source->strtab.scn, elf_getscn);
483 FAILIF_LIBELF(NULL == gelf_getshdr(source->strtab.scn,
484 &source->strtab.shdr),
485 gelf_getshdr);
486 source->strtab.data = elf_getdata(source->strtab.scn, NULL);
487 FAILIF_LIBELF(NULL == source->strtab.data, elf_getdata);
488 source->strtab.info = lookup_shdr_info_by_new_section(
489 source,
490 elf_strptr(source->oldelf, source->shstrndx,
491 source->strtab.shdr.sh_name),
492 source->strtab.scn);
493 ASSERT(source->shdr_info == NULL || source->strtab.info != NULL);
494 } else if (shdr->sh_type == SHT_DYNAMIC) {
495 source->dynamic.scn = scn;
496 source->dynamic.data = elf_getdata(scn, NULL);
497 FAILIF_LIBELF(NULL == source->dynamic.data, elf_getdata);
498 memcpy(&source->dynamic.shdr, shdr, sizeof(GElf_Shdr));
499 source->dynamic.info = lookup_shdr_info_by_new_section(
500 source, sname, scn);
501 ASSERT(source->shdr_info == NULL || source->dynamic.info != NULL);
502 } else if (shdr->sh_type == SHT_HASH) {
503 source->hash.scn = scn;
504 source->hash.data = elf_getdata(scn, NULL);
505 FAILIF_LIBELF(NULL == source->hash.data, elf_getdata);
506 memcpy(&source->hash.shdr, shdr, sizeof(GElf_Shdr));
507 source->hash.info = lookup_shdr_info_by_new_section(
508 source, sname, scn);
509 ASSERT(source->shdr_info == NULL || source->hash.info != NULL);
510 } else if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) {
511 if (source->num_relocation_sections ==
512 source->relocation_sections_size) {
513 source->relocation_sections_size += 5;
514 source->relocation_sections =
515 (section_info_t *)REALLOC(source->relocation_sections,
516 source->relocation_sections_size *
517 sizeof(section_info_t));
518 }
519 section_info_t *reloc =
520 source->relocation_sections + source->num_relocation_sections;
521 reloc->scn = scn;
522 reloc->info = lookup_shdr_info_by_new_section(source, sname, scn);
523 ASSERT(source->shdr_info == NULL || reloc->info != NULL);
524 reloc->data = elf_getdata(scn, NULL);
525 FAILIF_LIBELF(NULL == reloc->data, elf_getdata);
526 memcpy(&reloc->shdr, shdr, sizeof(GElf_Shdr));
527 source->num_relocation_sections++;
528 } else if (!strcmp(sname, ".bss")) {
529 source->bss.scn = scn;
530 source->bss.data = elf_getdata(scn, NULL);
531 source->bss.info = lookup_shdr_info_by_new_section(
532 source, sname, scn);
533 ASSERT(source->shdr_info == NULL || source->bss.info != NULL);
534 /* The BSS section occupies no space in the ELF file. */
535 FAILIF_LIBELF(NULL == source->bss.data, elf_getdata)
536 FAILIF(NULL != source->bss.data->d_buf,
537 "Enexpected: section [%s] has data!",
538 sname);
539 memcpy(&source->bss.shdr, shdr, sizeof(GElf_Shdr));
540 }
541 }
542 sort_ranges(source->sorted_sections);
543
544 source->unfinished =
545 (unfinished_relocation_t *)CALLOC(source->num_relocation_sections,
546 sizeof(unfinished_relocation_t));
547
548 if (source->dynamic.scn == NULL) {
549 INFO("File [%s] does not have a dynamic section!\n", source->name);
550 /* If this is a static executable, we won't update anything. */
551 source->dry_run = 1;
552 return false;
553 }
554
555 FAILIF(source->symtab.scn == NULL,
556 "File [%s] does not have a dynamic symbol table!\n",
557 source->name);
558 FAILIF(source->hash.scn == NULL,
559 "File [%s] does not have a hash table!\n",
560 source->name);
561 FAILIF(source->hash.shdr.sh_link != elf_ndxscn(source->symtab.scn),
562 "Hash points to section %d, not to %d as expected!\n",
563 source->hash.shdr.sh_link,
564 elf_ndxscn(source->symtab.scn));
565
566 /* Now, find out how many symbols we have and allocate the array of
567 satisfied symbols.
568
569 NOTE: We don't count the number of undefined symbols here; we will
570 iterate over the symbol table later, and count them then, when it is
571 more convenient.
572 */
573 size_t symsize = gelf_fsize (source->elf,
574 ELF_T_SYM,
575 1, source->elf_hdr.e_version);
576 ASSERT(symsize);
577
578 source->num_syms = source->symtab.data->d_size / symsize;
579 source->base = (source->oldelf_hdr.e_type == ET_DYN) ? base : 0;
580 INFO("Relink base for [%s]: 0x%lx\n", source->name, source->base);
581 FAILIF(source->base == -1,
582 "Can't prelink [%s]: it's a shared library and you did not "
583 "provide a prelink address!\n",
584 source->name);
585 #ifdef SUPPORT_ANDROID_PRELINK_TAGS
586 FAILIF(source->prelinked && source->base != source->prelink_base,
587 "ERROR: file [%s] has already been prelinked for 0x%08lx. "
588 "Cannot change to 0x%08lx!\n",
589 source->name,
590 source->prelink_base,
591 source->base);
592 #endif/*SUPPORT_ANDROID_PRELINK_TAGS*/
593
594 return true;
595 }
596
init_source(const char * full_path,const char * output,int is_file,int base,int dry_run)597 static source_t* init_source(const char *full_path,
598 const char *output, int is_file,
599 int base, int dry_run)
600 {
601 source_t *source = (source_t *)CALLOC(1, sizeof(source_t));
602
603 ASSERT(full_path);
604 source->name = full_path;
605 source->output = output;
606 source->output_is_dir = !is_file;
607
608 source->newelf_fd = -1;
609 source->elf_fd = -1;
610 INFO("Opening %s...\n", full_path);
611 source->elf_fd =
612 open(full_path, ((dry_run || output != NULL) ? O_RDONLY : O_RDWR));
613 FAILIF(source->elf_fd < 0, "open(%s): %s (%d)\n",
614 full_path,
615 strerror(errno),
616 errno);
617
618 FAILIF(fstat(source->elf_fd, &source->elf_file_info) < 0,
619 "fstat(%s(fd %d)): %s (%d)\n",
620 source->name,
621 source->elf_fd,
622 strerror(errno),
623 errno);
624 INFO("File [%s]'s size is %lld bytes!\n",
625 source->name,
626 source->elf_file_info.st_size);
627
628 INFO("Calling elf_begin(%s)...\n", full_path);
629
630 source->oldelf =
631 elf_begin(source->elf_fd,
632 (dry_run || output != NULL) ? ELF_C_READ : ELF_C_RDWR,
633 NULL);
634 FAILIF_LIBELF(source->oldelf == NULL, elf_begin);
635
636 /* libelf can recognize COFF and A.OUT formats, but we handle only ELF. */
637 if(elf_kind(source->oldelf) != ELF_K_ELF) {
638 ERROR("Input file %s is not in ELF format!\n", full_path);
639 return NULL;
640 }
641
642 /* Make sure this is a shared library or an executable. */
643 {
644 INFO("Making sure %s is a shared library or an executable...\n",
645 full_path);
646 FAILIF_LIBELF(0 == gelf_getehdr(source->oldelf, &source->oldelf_hdr),
647 gelf_getehdr);
648 FAILIF(source->oldelf_hdr.e_type != ET_DYN &&
649 source->oldelf_hdr.e_type != ET_EXEC,
650 "%s must be a shared library (elf type is %d, expecting %d).\n",
651 full_path,
652 source->oldelf_hdr.e_type,
653 ET_DYN);
654 }
655
656 #ifdef SUPPORT_ANDROID_PRELINK_TAGS
657 /* First, check to see if the file has been prelinked. */
658 source->prelinked =
659 check_prelinked(source->name,
660 source->oldelf_hdr.e_ident[EI_DATA] == ELFDATA2LSB,
661 &source->prelink_base);
662 /* Note that in the INFO() below we need to use oldelf_hdr because we
663 haven't cloned the ELF file yet, and source->elf_hdr is not defined. */
664 if (source->prelinked) {
665 PRINT("%s [%s] is already prelinked at 0x%08lx!\n",
666 (source->oldelf_hdr.e_type == ET_EXEC ?
667 "Executable" : "Shared library"),
668 source->name,
669 source->prelink_base);
670 /* Force a dry run when the file has already been prelinked */
671 source->dry_run = dry_run = 1;
672 }
673 else {
674 INFO("%s [%s] is not prelinked!\n",
675 (source->oldelf_hdr.e_type == ET_EXEC ?
676 "Executable" : "Shared library"),
677 source->name);
678 source->dry_run = dry_run;
679 }
680 #endif/*SUPPORT_ANDROID_PRELINK_TAGS*/
681
682 /* Get the index of the section-header-strings-table section. */
683 FAILIF_LIBELF(elf_getshstrndx (source->oldelf, &source->shstrndx) < 0,
684 elf_getshstrndx);
685
686 FAILIF_LIBELF(elf_getshnum (source->oldelf, (size_t *)&source->shnum) < 0,
687 elf_getshnum);
688
689 /* When we have a dry run, or when ADJUST_ELF is enabled, we use
690 source->oldelf for source->elf, because the former is mmapped privately,
691 so changes to it have no effect. With ADJUST_ELF, the first run of
692 prelink() is a dry run. We will reopen the elf file for write access
693 after that dry run, before we call adjust_elf. */
694
695 source->elf = (ADJUST_ELF || source->dry_run) ?
696 source->oldelf : init_elf(source, ADJUST_ELF == 0);
697
698 FAILIF_LIBELF(0 == gelf_getehdr(source->elf, &source->elf_hdr),
699 gelf_getehdr);
700 #ifdef DEBUG
701 ASSERT(!memcmp(&source->oldelf_hdr,
702 &source->elf_hdr,
703 sizeof(source->elf_hdr)));
704 #endif
705
706 /* Get the EBL handling. The -g option is currently the only reason
707 we need EBL so dont open the backend unless necessary. */
708 source->ebl = ebl_openbackend (source->elf);
709 FAILIF_LIBELF(NULL == source->ebl, ebl_openbackend);
710 #ifdef ARM_SPECIFIC_HACKS
711 FAILIF_LIBELF(0 != arm_init(source->elf, source->elf_hdr.e_machine,
712 source->ebl, sizeof(Ebl)),
713 arm_init);
714 #endif/*ARM_SPECIFIC_HACKS*/
715
716 add_to_sources(source);
717 if (do_init_source(source, base) == false) return NULL;
718 return source;
719 }
720
721 /* complements do_init_source() */
do_destroy_source(source_t * source)722 static void do_destroy_source(source_t *source)
723 {
724 int cnt;
725 destroy_range_list(source->sorted_sections);
726 source->sorted_sections = NULL;
727 for (cnt = 0; cnt < source->num_relocation_sections; cnt++) {
728 FREEIF(source->unfinished[cnt].rels);
729 source->unfinished[cnt].rels = NULL;
730 source->unfinished[cnt].num_rels = 0;
731 source->unfinished[cnt].rels_size = 0;
732 }
733 if (source->jmprel.sections != NULL) {
734 destroy_range_list(source->jmprel.sections);
735 source->jmprel.sections = NULL;
736 }
737 if (source->rel.sections != NULL) {
738 destroy_range_list(source->rel.sections);
739 source->rel.sections = NULL;
740 }
741 FREE(source->unfinished); /* do_init_source() */
742 source->unfinished = NULL;
743 FREE(source->relocation_sections); /* do_init_source() */
744 source->relocation_sections = NULL;
745 source->num_relocation_sections = source->relocation_sections_size = 0;
746 }
747
destroy_source(source_t * source)748 static void destroy_source(source_t *source)
749 {
750 /* Is this a little-endian ELF file? */
751 if (source->oldelf != source->elf) {
752 /* If it's a dynamic executable, this must not be a dry run. */
753 if (!source->dry_run && source->dynamic.scn != NULL)
754 {
755 FAILIF_LIBELF(elf_update(source->elf, ELF_C_WRITE) == -1,
756 elf_update);
757 }
758 FAILIF_LIBELF(elf_end(source->oldelf), elf_end);
759 }
760 ebl_closebackend(source->ebl);
761 FAILIF_LIBELF(elf_end(source->elf), elf_end);
762 FAILIF(close(source->elf_fd) < 0, "Could not close file %s: %s (%d)!\n",
763 source->name, strerror(errno), errno);
764 FAILIF((source->newelf_fd >= 0) && (close(source->newelf_fd) < 0),
765 "Could not close output file: %s (%d)!\n", strerror(errno), errno);
766
767 #ifdef SUPPORT_ANDROID_PRELINK_TAGS
768 if (!source->dry_run) {
769 if (source->dynamic.scn != NULL &&
770 source->elf_hdr.e_type != ET_EXEC)
771 {
772 /* For some reason, trying to write directly to source->elf_fd
773 causes a "bad file descriptor" error because of something libelf
774 does. We just close the file descriptor and open a new one in
775 function setup_prelink_info() below. */
776 INFO("%s: setting up prelink tag at end of file.\n",
777 source->output ? source->output : source->name);
778 setup_prelink_info(source->output ? source->output : source->name,
779 source->elf_hdr.e_ident[EI_DATA] == ELFDATA2LSB,
780 source->base);
781 }
782 else INFO("%s: executable, NOT setting up prelink tag.\n",
783 source->name);
784 }
785 #endif/*SUPPORT_ANDROID_PRELINK_TAGS*/
786
787 do_destroy_source(source);
788
789 if (source->shstrtab_data != NULL)
790 FREEIF(source->shstrtab_data->d_buf); /* adjust_elf */
791
792 FREE(source->lib_deps); /* list of library dependencies (process_file()) */
793 FREEIF(source->shdr_info); /* setup_shdr_info() */
794 FREEIF(source->phdr_info); /* init_elf() */
795 FREE(source->name); /* assigned to by init_source() */
796 /* If the output is a directory, in init_elf() we allocate a buffer where
797 we copy the directory, a slash, and the file name. Here we free that
798 buffer.
799 */
800 if (source->output_is_dir > 1) {
801 FREE(source->output);
802 }
803 FREE(source); /* init_source() */
804 }
805
reinit_source(source_t * source)806 static void reinit_source(source_t *source)
807 {
808 do_destroy_source(source);
809 do_init_source(source, source->base);
810
811 {
812 /* We've gathered all the DT_DYNAMIC entries; now we need to figure
813 out which relocation sections fit in which range as described by
814 the entries. Before we do so, however, we will populate the
815 jmprel and rel members of source, as well as their sizes.
816 */
817
818 size_t dynidx, numdyn;
819 GElf_Dyn *dyn, dyn_mem;
820
821 numdyn = source->dynamic.shdr.sh_size /
822 source->dynamic.shdr.sh_entsize;
823
824 source->rel.idx = source->rel.sz_idx = -1;
825 source->jmprel.idx = source->jmprel.sz_idx = -1;
826 for (dynidx = 0; dynidx < numdyn; dynidx++) {
827 dyn = gelf_getdyn (source->dynamic.data,
828 dynidx,
829 &dyn_mem);
830 FAILIF_LIBELF(NULL == dyn, gelf_getdyn);
831 switch (dyn->d_tag)
832 {
833 case DT_NEEDED:
834 break;
835 case DT_JMPREL:
836 INFO("reinit_source: DT_JMPREL is at index %d, 0x%08llx.\n",
837 dynidx, dyn->d_un.d_ptr);
838 source->jmprel.idx = dynidx;
839 source->jmprel.addr = dyn->d_un.d_ptr;
840 break;
841 case DT_PLTRELSZ:
842 INFO("reinit_source: DT_PLTRELSZ is at index %d, 0x%08llx.\n",
843 dynidx, dyn->d_un.d_val);
844 source->jmprel.sz_idx = dynidx;
845 source->jmprel.size = dyn->d_un.d_val;
846 break;
847 case DT_REL:
848 INFO("reinit_source: DT_REL is at index %d, 0x%08llx.\n",
849 dynidx, dyn->d_un.d_ptr);
850 source->rel.idx = dynidx;
851 source->rel.addr = dyn->d_un.d_ptr;
852 break;
853 case DT_RELSZ:
854 INFO("reinit_source: DT_RELSZ is at index %d, 0x%08llx.\n",
855 dynidx, dyn->d_un.d_val);
856 source->rel.sz_idx = dynidx;
857 source->rel.size = dyn->d_un.d_val;
858 break;
859 case DT_RELA:
860 case DT_RELASZ:
861 FAILIF(1, "Can't handle DT_RELA and DT_RELASZ entries!\n");
862 break;
863 } /* switch */
864 } /* for each dynamic entry... */
865 }
866 }
867
hash_lookup_global_or_weak_symbol(source_t * lib,const char * symname,GElf_Sym * lib_sym_mem)868 static GElf_Sym *hash_lookup_global_or_weak_symbol(source_t *lib,
869 const char *symname,
870 GElf_Sym *lib_sym_mem)
871 {
872 int lib_symidx = hash_lookup(lib->elf,
873 lib->hash.data,
874 lib->symtab.data,
875 lib->strtab.data,
876 symname);
877
878 GElf_Sym sym_mem;
879 if (SHN_UNDEF != lib_symidx) {
880 /* We found the symbol--now check to see if it is global
881 or weak. If this is the case, then the symbol satisfies
882 the dependency. */
883 GElf_Sym *lib_sym = gelf_getsymshndx(lib->symtab.data,
884 NULL,
885 lib_symidx,
886 &sym_mem,
887 NULL);
888 FAILIF_LIBELF(NULL == lib_sym, gelf_getsymshndx);
889 #if ELF_STRPTR_IS_BROKEN
890 ASSERT(!strcmp(
891 symname,
892 ((char *)elf_getdata(elf_getscn(lib->elf,
893 lib->symtab.shdr.sh_link),
894 NULL)->d_buf) +
895 lib_sym->st_name));
896 #else
897 ASSERT(!strcmp(
898 symname,
899 elf_strptr(lib->elf, lib->symtab.shdr.sh_link,
900 lib_sym->st_name)));
901 #endif
902 if (lib_sym->st_shndx != SHN_UNDEF &&
903 (GELF_ST_BIND(lib_sym->st_info) == STB_GLOBAL ||
904 GELF_ST_BIND(lib_sym->st_info) == STB_WEAK)) {
905 memcpy(lib_sym_mem, &sym_mem, sizeof(GElf_Sym));
906 return lib_sym;
907 }
908 }
909
910 return NULL;
911 }
912
lookup_symbol_in_dependencies(source_t * source,const char * symname,GElf_Sym * found_sym)913 static source_t *lookup_symbol_in_dependencies(source_t *source,
914 const char *symname,
915 GElf_Sym *found_sym)
916 {
917 source_t *sym_source = NULL; /* return value */
918
919 /* This is an undefined symbol. Go over the list of libraries
920 and look it up. */
921 size_t libidx;
922 int found = 0;
923 source_t *last_found = NULL;
924 for (libidx = 0; libidx < (size_t)source->num_lib_deps; libidx++) {
925 source_t *lib = source->lib_deps[libidx];
926 if (hash_lookup_global_or_weak_symbol(lib, symname, found_sym) != NULL)
927 {
928 sym_source = lib;
929 if (found) {
930 if (found == 1) {
931 found++;
932 ERROR("ERROR: multiple definitions found for [%s:%s]!\n",
933 source->name, symname);
934 ERROR("\tthis definition [%s]\n", lib->name);
935 }
936 ERROR("\tprevious definition [%s]\n", last_found->name);
937 }
938 last_found = lib;
939 if (!found) found = 1;
940 }
941 }
942
943 #if ELF_STRPTR_IS_BROKEN
944 ASSERT(!sym_source ||
945 !strcmp(symname,
946 (char *)(elf_getdata(elf_getscn(
947 sym_source->elf,
948 sym_source->symtab.shdr.sh_link),
949 NULL)->d_buf) +
950 found_sym->st_name));
951 #else
952 ASSERT(!sym_source ||
953 !strcmp(symname,
954 elf_strptr(sym_source->elf,
955 sym_source->symtab.shdr.sh_link,
956 found_sym->st_name)));
957 #endif
958
959 return sym_source;
960 }
961
do_prelink(source_t * source,Elf_Data * reloc_scn_data,int reloc_scn_entry_size,unfinished_relocation_t * unfinished,int locals_only,bool dry_run,char ** lib_lookup_dirs,int num_lib_lookup_dirs,char ** default_libs,int num_default_libs,int * num_unfinished_relocs)962 static int do_prelink(source_t *source,
963 Elf_Data *reloc_scn_data,
964 int reloc_scn_entry_size,
965 unfinished_relocation_t *unfinished,
966 int locals_only,
967 bool dry_run,
968 char **lib_lookup_dirs, int num_lib_lookup_dirs,
969 char **default_libs, int num_default_libs,
970 int *num_unfinished_relocs)
971 {
972 int num_relocations = 0;
973
974 size_t num_rels;
975 num_rels = reloc_scn_data->d_size / reloc_scn_entry_size;
976
977 INFO("\tThere are %d relocations.\n", num_rels);
978
979 int rel_idx;
980 for (rel_idx = 0; rel_idx < (size_t)num_rels; rel_idx++) {
981 GElf_Rel *rel, rel_mem;
982
983 //INFO("\tHandling relocation %d/%d\n", rel_idx, num_rels);
984
985 rel = gelf_getrel(reloc_scn_data, rel_idx, &rel_mem);
986 FAILIF_LIBELF(rel == NULL, gelf_getrel);
987 GElf_Sym *sym = NULL, sym_mem;
988 unsigned sym_idx = GELF_R_SYM(rel->r_info);
989 source_t *sym_source = NULL;
990 /* found_sym points to found_sym_mem, when sym_source != NULL, and
991 to sym, when the sybmol is locally defined. If the symbol is
992 not locally defined and sym_source == NULL, then sym is not
993 defined either. */
994 GElf_Sym *found_sym = NULL, found_sym_mem;
995 const char *symname = NULL;
996 int sym_is_local = 1;
997 if (sym_idx) {
998 sym = gelf_getsymshndx(source->symtab.data,
999 NULL,
1000 sym_idx,
1001 &sym_mem,
1002 NULL);
1003 FAILIF_LIBELF(NULL == sym, gelf_getsymshndx);
1004 #if ELF_STRPTR_IS_BROKEN
1005 symname =
1006 ((char *)source->strtab.data->d_buf) +
1007 sym->st_name;
1008 #else
1009 symname = elf_strptr(source->elf,
1010 elf_ndxscn(source->strtab.scn),
1011 sym->st_name);
1012 #endif
1013
1014 /* If the symbol is defined and is either not in the BSS
1015 section, or if it is in the BSS then the relocation is
1016 not a copy relocation, then the symbol's source is this
1017 library (i.e., it is locally-defined). Otherwise, the
1018 symbol is imported.
1019 */
1020
1021 sym_is_local = 0;
1022 if (sym->st_shndx != SHN_UNDEF &&
1023 (source->bss.scn == NULL ||
1024 sym->st_shndx != elf_ndxscn(source->bss.scn) ||
1025 #ifdef ARM_SPECIFIC_HACKS
1026 GELF_R_TYPE(rel->r_info) != R_ARM_COPY
1027 #else
1028 1
1029 #endif
1030 ))
1031 {
1032 sym_is_local = 1;
1033 }
1034
1035 if (sym_is_local) {
1036 INFO("\t\tSymbol [%s:%s] is defined locally.\n",
1037 source->name,
1038 symname);
1039 sym_source = source;
1040 found_sym = sym;
1041 }
1042 else if (!locals_only) {
1043 sym_source = lookup_symbol_in_dependencies(source,
1044 symname,
1045 &found_sym_mem);
1046
1047 /* The symbol was not in the list of dependencies, which by
1048 itself is an error: it means either that the symbol does
1049 not exist anywhere, or that the library which has the symbol
1050 has not been listed as a dependency in this library or
1051 executable. It could also mean (for a library) that the
1052 symbol is defined in the executable that links agsinst it,
1053 which is obviously not a good thing. These are bad things,
1054 but they do happen, which is why we have the ability to
1055 provide a list of default dependencies, including
1056 executables. Here we check to see if the symbol has been
1057 defined in any of them.
1058 */
1059 if (NULL == sym_source) {
1060 INFO("\t\tChecking default dependencies...\n");
1061 int i;
1062 source_t *lib, *old_sym_source = NULL;
1063 int printed_initial_error = 0;
1064 for (i = 0; i < num_default_libs; i++) {
1065 INFO("\tChecking in [%s].\n", default_libs[i]);
1066 lib = find_source(default_libs[i],
1067 lib_lookup_dirs,
1068 num_lib_lookup_dirs);
1069 FAILIF(NULL == lib,
1070 "Can't find default library [%s]!\n",
1071 default_libs[i]);
1072 if (hash_lookup_global_or_weak_symbol(lib,
1073 symname,
1074 &found_sym_mem)) {
1075 found_sym = &found_sym_mem;
1076 sym_source = lib;
1077 #if ELF_STRPTR_IS_BROKEN
1078 ASSERT(!strcmp(symname,
1079 (char *)(elf_getdata(
1080 elf_getscn(
1081 sym_source->elf,
1082 sym_source->symtab.
1083 shdr.sh_link),
1084 NULL)->d_buf) +
1085 found_sym->st_name));
1086 #else
1087 ASSERT(!strcmp(symname,
1088 elf_strptr(sym_source->elf,
1089 sym_source->symtab.shdr.sh_link,
1090 found_sym->st_name)));
1091
1092 #endif
1093 INFO("\tFound symbol [%s] in [%s]!\n",
1094 symname, lib->name);
1095 if (old_sym_source) {
1096 if (printed_initial_error == 0) {
1097 printed_initial_error = 1;
1098 ERROR("Multiple definition of [%s]:\n"
1099 "\t[%s]\n",
1100 symname,
1101 old_sym_source->name);
1102 }
1103 ERROR("\t[%s]\n", sym_source->name);
1104 }
1105 old_sym_source = sym_source;
1106 } else {
1107 INFO("\tCould not find symbol [%s] in default "
1108 "lib [%s]!\n", symname, lib->name);
1109 }
1110 }
1111 if (sym_source) {
1112 ERROR("ERROR: Could not find [%s:%s] in dependent "
1113 "libraries (but found in default [%s])!\n",
1114 source->name,
1115 symname,
1116 sym_source->name);
1117 }
1118 } else {
1119 found_sym = &found_sym_mem;
1120 /* We found the symbol in a dependency library. */
1121 INFO("\t\tSymbol [%s:%s, value %lld] is imported from [%s]\n",
1122 source->name,
1123 symname,
1124 found_sym->st_value,
1125 sym_source->name);
1126 }
1127 } /* if symbol is defined in this library... */
1128
1129 if (!locals_only) {
1130 /* If a symbol is weak and we haven't found it, then report
1131 an error. We really need to find a way to set its value
1132 to zero. The problem is that it needs to refer to some
1133 section. */
1134
1135 FAILIF(NULL == sym_source &&
1136 GELF_ST_BIND(sym->st_info) == STB_WEAK,
1137 "Cannot handle weak symbols yet (%s:%s <- %s).\n",
1138 source->name,
1139 symname,
1140 sym_source->name);
1141 #ifdef PERMISSIVE
1142 if (GELF_ST_BIND(sym->st_info) != STB_WEAK &&
1143 NULL == sym_source) {
1144 ERROR("ERROR: Can't find symbol [%s:%s] in dependent or "
1145 "default libraries!\n", source->name, symname);
1146 }
1147 #else
1148 FAILIF(GELF_ST_BIND(sym->st_info) != STB_WEAK &&
1149 NULL == sym_source,
1150 "Can't find symbol [%s:%s] in dependent or default "
1151 "libraries!\n",
1152 source->name,
1153 symname);
1154 #endif
1155 } /* if (!locals_only) */
1156 }
1157 #if 0 // too chatty
1158 else
1159 INFO("\t\tno symbol is associated with this relocation\n");
1160 #endif
1161
1162
1163 // We prelink only local symbols when locals_only == 1.
1164
1165 bool can_relocate = true;
1166 if (!sym_is_local &&
1167 (symname[0] == 'd' && symname[1] == 'l' && symname[2] != '\0' &&
1168 (!strcmp(symname + 2, "open") ||
1169 !strcmp(symname + 2, "close") ||
1170 !strcmp(symname + 2, "sym") ||
1171 !strcmp(symname + 2, "error")))) {
1172 INFO("********* NOT RELOCATING LIBDL SYMBOL [%s]\n", symname);
1173 can_relocate = false;
1174 }
1175
1176 if (can_relocate && (sym_is_local || !locals_only))
1177 {
1178 GElf_Shdr shdr_mem; Elf_Scn *scn; Elf_Data *data;
1179 find_section(source, rel->r_offset, &scn, &shdr_mem, &data);
1180 unsigned *dest =
1181 (unsigned*)(((char *)data->d_buf) +
1182 (rel->r_offset - shdr_mem.sh_addr));
1183 unsigned rel_type = GELF_R_TYPE(rel->r_info);
1184 char buf[64];
1185 INFO("\t\t%-15s ",
1186 ebl_reloc_type_name(source->ebl,
1187 GELF_R_TYPE(rel->r_info),
1188 buf,
1189 sizeof(buf)));
1190
1191 /* Section-name offsets do not change, so we use oldelf to get the
1192 strings. This makes a difference in the second pass of the
1193 perlinker, after the call to adjust_elf, because
1194 source->shstrndx no longer contains the index of the
1195 section-header-strings table.
1196 */
1197 const char *sname = elf_strptr(
1198 source->oldelf, source->shstrndx, shdr_mem.sh_name);
1199
1200 switch (rel_type) {
1201 case R_ARM_JUMP_SLOT:
1202 case R_ARM_GLOB_DAT:
1203 case R_ARM_ABS32:
1204 ASSERT(data->d_buf != NULL);
1205 ASSERT(data->d_size >= rel->r_offset - shdr_mem.sh_addr);
1206 #ifdef PERMISSIVE
1207 if (sym_source == NULL) {
1208 ERROR("ERROR: Permissive relocation "
1209 "[%-15s] [%s:%s]: [0x%llx] = ZERO\n",
1210 ebl_reloc_type_name(source->ebl,
1211 GELF_R_TYPE(rel->r_info),
1212 buf,
1213 sizeof(buf)),
1214 sname,
1215 symname,
1216 rel->r_offset);
1217 if (!dry_run)
1218 *dest = 0;
1219 } else
1220 #endif
1221 {
1222 ASSERT(sym_source);
1223 INFO("[%s:%s]: [0x%llx] = 0x%llx + 0x%lx\n",
1224 sname,
1225 symname,
1226 rel->r_offset,
1227 found_sym->st_value,
1228 sym_source->base);
1229 if (!dry_run)
1230 *dest = found_sym->st_value + sym_source->base;
1231 }
1232 num_relocations++;
1233 break;
1234 case R_ARM_RELATIVE:
1235 ASSERT(data->d_buf != NULL);
1236 ASSERT(data->d_size >= rel->r_offset - shdr_mem.sh_addr);
1237 FAILIF(sym != NULL,
1238 "Unsupported RELATIVE form (symbol != 0)...\n");
1239 INFO("[%s:%s]: [0x%llx] = 0x%x + 0x%lx\n",
1240 sname,
1241 symname ?: "(symbol has no name)",
1242 rel->r_offset, *dest, source->base);
1243 if (!dry_run)
1244 *dest += source->base;
1245 num_relocations++;
1246 break;
1247 case R_ARM_COPY:
1248 #ifdef PERMISSIVE
1249 if (sym_source == NULL) {
1250 ERROR("ERROR: Permissive relocation "
1251 "[%-15s] [%s:%s]: NOT PERFORMING\n",
1252 ebl_reloc_type_name(source->ebl,
1253 GELF_R_TYPE(rel->r_info),
1254 buf,
1255 sizeof(buf)),
1256 sname,
1257 symname);
1258 } else
1259 #endif
1260 {
1261 ASSERT(sym);
1262 ASSERT(sym_source);
1263 GElf_Shdr src_shdr_mem;
1264 Elf_Scn *src_scn;
1265 Elf_Data *src_data;
1266 find_section(sym_source, found_sym->st_value,
1267 &src_scn,
1268 &src_shdr_mem,
1269 &src_data);
1270 INFO("Found [%s:%s (%lld)] in section [%s] .\n",
1271 sym_source->name,
1272 symname,
1273 found_sym->st_value,
1274 #if ELF_STRPTR_IS_BROKEN
1275 (((char *)elf_getdata(
1276 elf_getscn(sym_source->elf,
1277 sym_source->shstrndx),
1278 NULL)->d_buf) + src_shdr_mem.sh_name)
1279 #else
1280 elf_strptr(sym_source->elf,
1281 sym_source->shstrndx,
1282 src_shdr_mem.sh_name)
1283 #endif
1284 );
1285
1286 unsigned *src = NULL;
1287 if (src_data->d_buf == NULL)
1288 {
1289 #ifdef PERMISSIVE
1290 if (sym_source->bss.scn == NULL ||
1291 elf_ndxscn(src_scn) !=
1292 elf_ndxscn(sym_source->bss.scn)) {
1293 ERROR("ERROR: Permissive relocation (NULL source "
1294 "not from .bss) [%-15s] [%s:%s]: "
1295 "NOT PERFORMING\n",
1296 ebl_reloc_type_name(source->ebl,
1297 GELF_R_TYPE(rel->r_info),
1298 buf,
1299 sizeof(buf)),
1300 sname,
1301 symname);
1302 }
1303 #endif
1304 }
1305 else {
1306 ASSERT(src_data->d_size >=
1307 found_sym->st_value - src_shdr_mem.sh_addr);
1308 src = (unsigned*)(((char *)src_data->d_buf) +
1309 (found_sym->st_value -
1310 src_shdr_mem.sh_addr));
1311 }
1312 ASSERT(symname);
1313 INFO("[%s:%s]: [0x%llx] <- [0x%llx] size %lld\n",
1314 sname,
1315 symname, rel->r_offset,
1316 found_sym->st_value,
1317 found_sym->st_size);
1318
1319 #ifdef PERMISSIVE
1320 if (src_data->d_buf != NULL ||
1321 (sym_source->bss.scn != NULL &&
1322 elf_ndxscn(src_scn) ==
1323 elf_ndxscn(sym_source->bss.scn)))
1324 #endif/*PERMISSIVE*/
1325 {
1326 if (data->d_buf == NULL) {
1327 INFO("Incomplete relocation [%-15s] of [%s:%s].\n",
1328 ebl_reloc_type_name(source->ebl,
1329 GELF_R_TYPE(rel->r_info),
1330 buf,
1331 sizeof(buf)),
1332 sname,
1333 symname);
1334 FAILIF(unfinished == NULL,
1335 "You passed unfinished as NULL expecting "
1336 "to handle all relocations, "
1337 "but at least one cannot be handled!\n");
1338 if (unfinished->num_rels == unfinished->rels_size) {
1339 unfinished->rels_size += 10;
1340 unfinished->rels = (GElf_Rel *)REALLOC(
1341 unfinished->rels,
1342 unfinished->rels_size *
1343 sizeof(GElf_Rel));
1344 }
1345 unfinished->rels[unfinished->num_rels++] = *rel;
1346 num_relocations--;
1347 (*num_unfinished_relocs)++;
1348 }
1349 else {
1350 if (src_data->d_buf != NULL)
1351 {
1352 ASSERT(data->d_buf != NULL);
1353 ASSERT(data->d_size >= rel->r_offset -
1354 shdr_mem.sh_addr);
1355 if (!dry_run)
1356 memcpy(dest, src, found_sym->st_size);
1357 }
1358 else {
1359 ASSERT(src == NULL);
1360 ASSERT(elf_ndxscn(src_scn) ==
1361 elf_ndxscn(sym_source->bss.scn));
1362 if (!dry_run)
1363 memset(dest, 0, found_sym->st_size);
1364 }
1365 }
1366 }
1367 num_relocations++;
1368 }
1369 break;
1370 default:
1371 FAILIF(1, "Unknown relocation type %d!\n", rel_type);
1372 } // switch
1373 } // relocate
1374 else {
1375 INFO("\t\tNot relocating symbol [%s]%s\n",
1376 symname,
1377 (can_relocate ? ", relocating only locals" :
1378 ", which is a libdl symbol"));
1379 FAILIF(unfinished == NULL,
1380 "You passed unfinished as NULL expecting to handle all "
1381 "relocations, but at least one cannot be handled!\n");
1382 if (unfinished->num_rels == unfinished->rels_size) {
1383 unfinished->rels_size += 10;
1384 unfinished->rels = (GElf_Rel *)REALLOC(
1385 unfinished->rels,
1386 unfinished->rels_size *
1387 sizeof(GElf_Rel));
1388 }
1389 unfinished->rels[unfinished->num_rels++] = *rel;
1390 (*num_unfinished_relocs)++;
1391 }
1392 } // for each relocation entry
1393
1394 return num_relocations;
1395 }
1396
prelink(source_t * source,int locals_only,bool dry_run,char ** lib_lookup_dirs,int num_lib_lookup_dirs,char ** default_libs,int num_default_libs,int * num_unfinished_relocs)1397 static int prelink(source_t *source,
1398 int locals_only,
1399 bool dry_run,
1400 char **lib_lookup_dirs, int num_lib_lookup_dirs,
1401 char **default_libs, int num_default_libs,
1402 int *num_unfinished_relocs)
1403 {
1404 INFO("Prelinking [%s] (number of relocation sections: %d)%s...\n",
1405 source->name, source->num_relocation_sections,
1406 (dry_run ? " (dry run)" : ""));
1407 int num_relocations = 0;
1408 int rel_scn_idx;
1409 for (rel_scn_idx = 0; rel_scn_idx < source->num_relocation_sections;
1410 rel_scn_idx++)
1411 {
1412 section_info_t *reloc_scn = source->relocation_sections + rel_scn_idx;
1413 unfinished_relocation_t *unfinished = source->unfinished + rel_scn_idx;
1414
1415 /* We haven't modified the shstrtab section, and so shdr->sh_name has
1416 the same value as before. Thus we look up the name based on the old
1417 ELF handle. We cannot use shstrndx on the new ELF handle because
1418 the index of the shstrtab section may have changed (and calling
1419 elf_getshstrndx() returns the same section index, so libelf can't
1420 handle thise ither).
1421
1422 If reloc_scn->info is available, we can assert that the
1423 section-name has not changed. If this assertion fails,
1424 then we cannot use the elf_strptr() trick below to get
1425 the section name. One solution would be to save it in
1426 the section_info_t structure.
1427 */
1428 ASSERT(reloc_scn->info == NULL ||
1429 reloc_scn->shdr.sh_name == reloc_scn->info->old_shdr.sh_name);
1430 const char *sname =
1431 elf_strptr(source->oldelf,
1432 source->shstrndx,
1433 reloc_scn->shdr.sh_name);
1434 ASSERT(sname != NULL);
1435
1436 INFO("\n\tIterating relocation section [%s]...\n", sname);
1437
1438 /* In general, the new size of the section differs from the original
1439 size of the section, because we can handle some of the relocations.
1440 This was communicated to adjust_elf, which modified the ELF file
1441 according to the new section sizes. Now, when prelink() does the
1442 actual work of prelinking, it needs to know the original size of the
1443 relocation section so that it can see all of the original relocation
1444 entries!
1445 */
1446 size_t d_size = reloc_scn->data->d_size;
1447 if (reloc_scn->info != NULL &&
1448 reloc_scn->data->d_size != reloc_scn->info->old_shdr.sh_size)
1449 {
1450 INFO("Setting size of section [%s] to from new size %d to old "
1451 "size %lld temporarily (so prelinker can see all "
1452 "relocations).\n",
1453 reloc_scn->info->name,
1454 d_size,
1455 reloc_scn->info->old_shdr.sh_size);
1456 reloc_scn->data->d_size = reloc_scn->info->old_shdr.sh_size;
1457 }
1458
1459 num_relocations +=
1460 do_prelink(source,
1461 reloc_scn->data, reloc_scn->shdr.sh_entsize,
1462 unfinished,
1463 locals_only, dry_run,
1464 lib_lookup_dirs, num_lib_lookup_dirs,
1465 default_libs, num_default_libs,
1466 num_unfinished_relocs);
1467
1468 if (reloc_scn->data->d_size != d_size)
1469 {
1470 ASSERT(reloc_scn->info != NULL);
1471 INFO("Resetting size of section [%s] to %d\n",
1472 reloc_scn->info->name,
1473 d_size);
1474 reloc_scn->data->d_size = d_size;
1475 }
1476 }
1477
1478 /* Now prelink those relocation sections which were fully handled, and
1479 therefore removed. They are not a part of the
1480 source->relocation_sections[] array anymore, but we can find them by
1481 scanning source->shdr_info[] and looking for sections with idx == 0.
1482 */
1483
1484 if (ADJUST_ELF && source->shdr_info != NULL) {
1485 /* Walk over the shdr_info[] array to see if we've removed any
1486 relocation sections. prelink() those sections as well.
1487 */
1488 int i;
1489 for (i = 0; i < source->shnum; i++) {
1490 shdr_info_t *info = source->shdr_info + i;
1491 if (info->idx == 0 &&
1492 (info->shdr.sh_type == SHT_REL ||
1493 info->shdr.sh_type == SHT_RELA)) {
1494
1495 Elf_Data *data = elf_getdata(info->scn, NULL);
1496 ASSERT(data->d_size == 0);
1497 data->d_size = info->old_shdr.sh_size;
1498
1499 INFO("\n\tIterating relocation section [%s], which was "
1500 "discarded (size %d, entry size %lld).\n",
1501 info->name,
1502 data->d_size,
1503 info->old_shdr.sh_entsize);
1504
1505 num_relocations +=
1506 do_prelink(source,
1507 data, info->old_shdr.sh_entsize,
1508 NULL, /* the section was fully handled */
1509 locals_only, dry_run,
1510 lib_lookup_dirs, num_lib_lookup_dirs,
1511 default_libs, num_default_libs,
1512 num_unfinished_relocs);
1513
1514 data->d_size = 0;
1515 }
1516 }
1517 }
1518 return num_relocations;
1519 }
1520
find_file(const char * libname,char ** lib_lookup_dirs,int num_lib_lookup_dirs)1521 static char * find_file(const char *libname,
1522 char **lib_lookup_dirs,
1523 int num_lib_lookup_dirs) {
1524 if (libname[0] == '/') {
1525 /* This is an absolute path name--just return it. */
1526 /* INFO("ABSOLUTE PATH: [%s].\n", libname); */
1527 return strdup(libname);
1528 } else {
1529 /* First try the working directory. */
1530 int fd;
1531 if ((fd = open(libname, O_RDONLY)) > 0) {
1532 close(fd);
1533 /* INFO("FOUND IN CURRENT DIR: [%s].\n", libname); */
1534 return strdup(libname);
1535 } else {
1536 /* Iterate over all library paths. For each path, append the file
1537 name and see if there is a file at that place. If that fails,
1538 bail out. */
1539
1540 char *name;
1541 while (num_lib_lookup_dirs--) {
1542 size_t lib_len = strlen(*lib_lookup_dirs);
1543 /* one extra character for the slash, and another for the
1544 terminating NULL. */
1545 name = (char *)MALLOC(lib_len + strlen(libname) + 2);
1546 strcpy(name, *lib_lookup_dirs);
1547 name[lib_len] = '/';
1548 strcpy(name + lib_len + 1, libname);
1549 if ((fd = open(name, O_RDONLY)) > 0) {
1550 close(fd);
1551 /* INFO("FOUND: [%s] in [%s].\n", libname, name); */
1552 return name;
1553 }
1554 INFO("NOT FOUND: [%s] in [%s].\n", libname, name);
1555 free(name);
1556 }
1557 }
1558 }
1559 return NULL;
1560 }
1561
adjust_dynamic_segment_entry_size(source_t * source,dt_rel_info_t * dyn)1562 static void adjust_dynamic_segment_entry_size(source_t *source,
1563 dt_rel_info_t *dyn)
1564 {
1565 /* Update the size entry in the DT_DYNAMIC segment. */
1566 GElf_Dyn *dyn_entry, dyn_entry_mem;
1567 dyn_entry = gelf_getdyn(source->dynamic.data,
1568 dyn->sz_idx,
1569 &dyn_entry_mem);
1570 FAILIF_LIBELF(NULL == dyn_entry, gelf_getdyn);
1571 /* If we are calling this function to adjust the size of the dynamic entry,
1572 then there should be some unfinished relocations remaining. If there
1573 are none, then we should remove the entry from the dynamic section
1574 altogether.
1575 */
1576 ASSERT(dyn->num_unfinished_relocs);
1577
1578 size_t relsize = gelf_fsize(source->elf,
1579 ELF_T_REL,
1580 1,
1581 source->elf_hdr.e_version);
1582
1583 if (unlikely(verbose_flag)) {
1584 char buf[64];
1585 INFO("Updating entry %d: [%-10s], %08llx --> %08x\n",
1586 dyn->sz_idx,
1587 ebl_dynamic_tag_name (source->ebl, dyn_entry->d_tag,
1588 buf, sizeof (buf)),
1589 dyn_entry->d_un.d_val,
1590 dyn->num_unfinished_relocs * relsize);
1591 }
1592
1593 dyn_entry->d_un.d_val = dyn->num_unfinished_relocs * relsize;
1594
1595 FAILIF_LIBELF(!gelf_update_dyn(source->dynamic.data,
1596 dyn->sz_idx,
1597 dyn_entry),
1598 gelf_update_dyn);
1599 }
1600
adjust_dynamic_segment_entries(source_t * source)1601 static void adjust_dynamic_segment_entries(source_t *source)
1602 {
1603 /* This function many remove entries from the dynamic segment, but it won't
1604 resize the relevant section. It'll just fill the remainted with empty
1605 DT entries.
1606
1607 FIXME: This is not guaranteed right now. If a dynamic segment does not
1608 end with null DT entries, I think this will break.
1609 */
1610 FAILIF(source->rel.processed,
1611 "More than one section matches DT_REL entry in dynamic segment!\n");
1612 FAILIF(source->jmprel.processed,
1613 "More than one section matches DT_JMPREL entry in "
1614 "dynamic segment!\n");
1615 source->rel.processed =
1616 source->jmprel.processed = 1;
1617
1618 if (source->rel.num_unfinished_relocs > 0)
1619 adjust_dynamic_segment_entry_size(source, &source->rel);
1620
1621 if (source->jmprel.num_unfinished_relocs > 0)
1622 adjust_dynamic_segment_entry_size(source, &source->jmprel);
1623
1624 /* If at least one of the entries is empty, then we need to remove it. We
1625 have already adjusted the size of the other.
1626 */
1627 if (source->rel.num_unfinished_relocs == 0 ||
1628 source->jmprel.num_unfinished_relocs == 0)
1629 {
1630 /* We need to delete the DT_REL/DT_RELSZ and DT_PLTREL/DT_PLTRELSZ
1631 entries from the dynamic segment. */
1632
1633 GElf_Dyn *dyn_entry, dyn_entry_mem;
1634 size_t dynidx, updateidx;
1635
1636 size_t numdyn =
1637 source->dynamic.shdr.sh_size /
1638 source->dynamic.shdr.sh_entsize;
1639
1640 for (updateidx = dynidx = 0; dynidx < numdyn; dynidx++)
1641 {
1642 dyn_entry = gelf_getdyn(source->dynamic.data,
1643 dynidx,
1644 &dyn_entry_mem);
1645 FAILIF_LIBELF(NULL == dyn_entry, gelf_getdyn);
1646 if ((source->rel.num_unfinished_relocs == 0 &&
1647 (dynidx == source->rel.idx ||
1648 dynidx == source->rel.sz_idx)) ||
1649 (source->jmprel.num_unfinished_relocs == 0 &&
1650 (dynidx == source->jmprel.idx ||
1651 dynidx == source->jmprel.sz_idx)))
1652 {
1653 if (unlikely(verbose_flag)) {
1654 char buf[64];
1655 INFO("\t(!)\tRemoving entry %02d: [%-10s], %08llx\n",
1656 dynidx,
1657 ebl_dynamic_tag_name (source->ebl, dyn_entry->d_tag,
1658 buf, sizeof (buf)),
1659 dyn_entry->d_un.d_val);
1660 }
1661 continue;
1662 }
1663
1664 if (unlikely(verbose_flag)) {
1665 char buf[64];
1666 INFO("\t\tKeeping entry %02d: [%-10s], %08llx\n",
1667 dynidx,
1668 ebl_dynamic_tag_name (source->ebl, dyn_entry->d_tag,
1669 buf, sizeof (buf)),
1670 dyn_entry->d_un.d_val);
1671 }
1672
1673 gelf_update_dyn(source->dynamic.data,
1674 updateidx,
1675 &dyn_entry_mem);
1676 updateidx++;
1677 }
1678 }
1679 } /* adjust_dynamic_segment_entries */
1680
adjust_dynamic_segment_for(source_t * source,dt_rel_info_t * dyn,bool adjust_section_size_only)1681 static bool adjust_dynamic_segment_for(source_t *source,
1682 dt_rel_info_t *dyn,
1683 bool adjust_section_size_only)
1684 {
1685 bool dropped_sections = false;
1686
1687 /* Go over the sections that belong to this dynamic range. */
1688 dyn->num_unfinished_relocs = 0;
1689 if (dyn->sections) {
1690 int num_scns, idx;
1691 range_t *scns = get_sorted_ranges(dyn->sections, &num_scns);
1692
1693 INFO("\tdynamic range %s:[%lld, %lld) contains %d sections.\n",
1694 source->name,
1695 dyn->addr,
1696 dyn->addr + dyn->size,
1697 num_scns);
1698
1699 ASSERT(scns);
1700 int next_idx = 0, next_rel_off = 0;
1701 /* The total number of unfinished relocations for this dynamic
1702 * entry. */
1703 section_info_t *next = (section_info_t *)scns[next_idx].user;
1704 section_info_t *first = next;
1705 ASSERT(first);
1706 for (idx = 0; idx < num_scns; idx++) {
1707 section_info_t *reloc_scn = (section_info_t *)scns[idx].user;
1708 size_t rel_scn_idx = reloc_scn - source->relocation_sections;
1709 ASSERT(rel_scn_idx < (size_t)source->num_relocation_sections);
1710 unfinished_relocation_t *unfinished =
1711 &source->unfinished[rel_scn_idx];
1712 int unf_idx;
1713
1714 ASSERT(reloc_scn->info == NULL ||
1715 reloc_scn->shdr.sh_name ==
1716 reloc_scn->info->old_shdr.sh_name);
1717 const char *sname =
1718 elf_strptr(source->oldelf,
1719 source->shstrndx,
1720 reloc_scn->shdr.sh_name);
1721
1722 INFO("\tsection [%s] contains %d unfinished relocs.\n",
1723 sname,
1724 unfinished->num_rels);
1725
1726 for (unf_idx = 0; unf_idx < unfinished->num_rels; unf_idx++)
1727 {
1728 /* There are unfinished relocations. Copy them forward to the
1729 lowest section we can. */
1730
1731 while (next_rel_off ==
1732 (int)(next->shdr.sh_size/next->shdr.sh_entsize))
1733 {
1734 INFO("\tsection [%s] has filled up with %d unfinished "
1735 "relocs.\n",
1736 sname,
1737 next_rel_off);
1738
1739 next_idx++;
1740 ASSERT(next_idx <= idx);
1741 next = (section_info_t *)scns[next_idx].user;
1742 next_rel_off = 0;
1743 }
1744
1745 if (!adjust_section_size_only) {
1746 INFO("\t\tmoving unfinished relocation %2d to [%s:%d]\n",
1747 unf_idx,
1748 sname,
1749 next_rel_off);
1750 FAILIF_LIBELF(0 ==
1751 gelf_update_rel(next->data,
1752 next_rel_off,
1753 &unfinished->rels[unf_idx]),
1754 gelf_update_rel);
1755 }
1756
1757 next_rel_off++;
1758 dyn->num_unfinished_relocs++;
1759 }
1760 } /* for */
1761
1762 /* Set the size of the last section, and mark all subsequent
1763 sections for removal. At this point, next is the section
1764 to which we last wrote data, next_rel_off is the offset before
1765 which we wrote the last relocation, and so next_rel_off *
1766 relsize is the new size of the section.
1767 */
1768
1769 bool adjust_file = ADJUST_ELF && source->elf_hdr.e_type != ET_EXEC;
1770 if (adjust_file && !source->dry_run)
1771 {
1772 size_t relsize = gelf_fsize(source->elf,
1773 ELF_T_REL,
1774 1,
1775 source->elf_hdr.e_version);
1776
1777 ASSERT(next->info == NULL ||
1778 next->shdr.sh_name == next->info->old_shdr.sh_name);
1779 const char *sname =
1780 elf_strptr(source->oldelf,
1781 source->shstrndx,
1782 next->shdr.sh_name);
1783
1784 INFO("\tsection [%s] (index %d) has %d unfinished relocs, "
1785 "changing its size to %ld bytes (from %ld bytes).\n",
1786 sname,
1787 elf_ndxscn(next->scn),
1788 next_rel_off,
1789 (long)(next_rel_off * relsize),
1790 (long)(next->shdr.sh_size));
1791
1792 /* source->shdr_info[] must be allocated prior to calling this
1793 function. This is in fact done in process_file(), by calling
1794 setup_shdr_info() just before we call adjust_dynamic_segment().
1795 */
1796 ASSERT(source->shdr_info != NULL);
1797
1798 /* We do not update the data field of shdr_info[], because it does
1799 not exist yet (with ADJUST_ELF != 0). We create the new section
1800 and section data after the first call to prelink(). For now, we
1801 save the results of our analysis by modifying the sh_size field
1802 of the section header. When we create the new sections' data,
1803 we set the size of the data from the sh_size fields of the
1804 section headers.
1805
1806 NOTE: The assertion applies only to the first call of
1807 adjust_dynamic_segment (which calls this function). By
1808 the second call, we've already created the data for the
1809 new sections. The only sections for which we haven't
1810 created data are the relocation sections we are removing.
1811 */
1812 #ifdef DEBUG
1813 ASSERT((!adjust_section_size_only &&
1814 (source->shdr_info[elf_ndxscn(next->scn)].idx > 0)) ||
1815 source->shdr_info[elf_ndxscn(next->scn)].data == NULL);
1816 #endif
1817
1818 //FIXME: what else do we need to do here? Do we need to update
1819 // another copy of the shdr so that it's picked up when we
1820 // commit the file?
1821 next->shdr.sh_size = next_rel_off * relsize;
1822 source->shdr_info[elf_ndxscn(next->scn)].shdr.sh_size =
1823 next->shdr.sh_size;
1824 if (next_rel_off * relsize == 0) {
1825 #ifdef REMOVE_HANDLED_SECTIONS
1826 INFO("\tsection [%s] (index %d) is now empty, marking for "
1827 "removal.\n",
1828 sname,
1829 elf_ndxscn(next->scn));
1830 source->shdr_info[elf_ndxscn(next->scn)].idx = 0;
1831 dropped_sections = true;
1832 #endif
1833 }
1834
1835 while (++next_idx < num_scns) {
1836 next = (section_info_t *)scns[next_idx].user;
1837 #ifdef REMOVE_HANDLED_SECTIONS
1838 ASSERT(next->info == NULL ||
1839 next->shdr.sh_name == next->info->old_shdr.sh_name);
1840 const char *sname =
1841 elf_strptr(source->oldelf,
1842 source->shstrndx,
1843 next->shdr.sh_name);
1844 INFO("\tsection [%s] (index %d) is now empty, marking for "
1845 "removal.\n",
1846 sname,
1847 elf_ndxscn(next->scn));
1848 /* mark for removal */
1849 source->shdr_info[elf_ndxscn(next->scn)].idx = 0;
1850 dropped_sections = true;
1851 #endif
1852 }
1853 }
1854
1855 } /* if (dyn->sections) */
1856 else {
1857 /* The dynamic entry won't have any sections when it itself doesn't
1858 exist. This could happen when we remove all relocation sections
1859 from a dynamic entry because we have managed to handle all
1860 relocations in them.
1861 */
1862 INFO("\tNo section for dynamic entry!\n");
1863 }
1864
1865 return dropped_sections;
1866 }
1867
adjust_dynamic_segment(source_t * source,bool adjust_section_size_only)1868 static bool adjust_dynamic_segment(source_t *source,
1869 bool adjust_section_size_only)
1870 {
1871 bool dropped_section;
1872 INFO("Adjusting dynamic segment%s.\n",
1873 (adjust_section_size_only ? " (section sizes only)" : ""));
1874 INFO("\tadjusting dynamic segment REL.\n");
1875 dropped_section =
1876 adjust_dynamic_segment_for(source, &source->rel,
1877 adjust_section_size_only);
1878 INFO("\tadjusting dynamic segment JMPREL.\n");
1879 dropped_section =
1880 adjust_dynamic_segment_for(source, &source->jmprel,
1881 adjust_section_size_only) ||
1882 dropped_section;
1883 if (!adjust_section_size_only)
1884 adjust_dynamic_segment_entries(source);
1885 return dropped_section;
1886 }
1887
match_relocation_sections_to_dynamic_ranges(source_t * source)1888 static void match_relocation_sections_to_dynamic_ranges(source_t *source)
1889 {
1890 /* We've gathered all the DT_DYNAMIC entries; now we need to figure out
1891 which relocation sections fit in which range as described by the
1892 entries.
1893 */
1894
1895 int relidx;
1896 for (relidx = 0; relidx < source->num_relocation_sections; relidx++) {
1897 section_info_t *reloc_scn = &source->relocation_sections[relidx];
1898
1899 int index = elf_ndxscn(reloc_scn->scn);
1900
1901 ASSERT(reloc_scn->info == NULL ||
1902 reloc_scn->shdr.sh_name == reloc_scn->info->old_shdr.sh_name);
1903 const char *sname =
1904 elf_strptr(source->oldelf,
1905 source->shstrndx,
1906 reloc_scn->shdr.sh_name);
1907
1908 INFO("Checking section [%s], index %d, for match to dynamic ranges\n",
1909 sname, index);
1910 if (source->shdr_info == NULL || reloc_scn->info->idx > 0) {
1911 if (source->rel.addr &&
1912 source->rel.addr <= reloc_scn->shdr.sh_addr &&
1913 reloc_scn->shdr.sh_addr < source->rel.addr + source->rel.size)
1914 {
1915 /* The entire section must fit in the dynamic range. */
1916 if((reloc_scn->shdr.sh_addr + reloc_scn->shdr.sh_size) >
1917 (source->rel.addr + source->rel.size))
1918 {
1919 PRINT("WARNING: In [%s], section %s:[%lld,%lld) "
1920 "is not fully contained in dynamic range "
1921 "[%lld,%lld)!\n",
1922 source->name,
1923 sname,
1924 reloc_scn->shdr.sh_addr,
1925 reloc_scn->shdr.sh_addr +
1926 reloc_scn->shdr.sh_size,
1927 source->rel.addr,
1928 source->rel.addr + source->rel.size);
1929 }
1930
1931 if (NULL == source->rel.sections) {
1932 source->rel.sections = init_range_list();
1933 ASSERT(source->rel.sections);
1934 }
1935 add_unique_range_nosort(source->rel.sections,
1936 reloc_scn->shdr.sh_addr,
1937 reloc_scn->shdr.sh_size,
1938 reloc_scn,
1939 NULL,
1940 NULL);
1941 INFO("\tSection [%s] matches dynamic range REL.\n",
1942 sname);
1943 }
1944 else if (source->jmprel.addr &&
1945 source->jmprel.addr <= reloc_scn->shdr.sh_addr &&
1946 reloc_scn->shdr.sh_addr <= source->jmprel.addr +
1947 source->jmprel.size)
1948 {
1949 if((reloc_scn->shdr.sh_addr + reloc_scn->shdr.sh_size) >
1950 (source->jmprel.addr + source->jmprel.size))
1951 {
1952 PRINT("WARNING: In [%s], section %s:[%lld,%lld) "
1953 "is not fully "
1954 "contained in dynamic range [%lld,%lld)!\n",
1955 source->name,
1956 sname,
1957 reloc_scn->shdr.sh_addr,
1958 reloc_scn->shdr.sh_addr +
1959 reloc_scn->shdr.sh_size,
1960 source->jmprel.addr,
1961 source->jmprel.addr + source->jmprel.size);
1962 }
1963
1964 if (NULL == source->jmprel.sections) {
1965 source->jmprel.sections = init_range_list();
1966 ASSERT(source->jmprel.sections);
1967 }
1968 add_unique_range_nosort(source->jmprel.sections,
1969 reloc_scn->shdr.sh_addr,
1970 reloc_scn->shdr.sh_size,
1971 reloc_scn,
1972 NULL,
1973 NULL);
1974 INFO("\tSection [%s] matches dynamic range JMPREL.\n",
1975 sname);
1976 }
1977 else
1978 PRINT("WARNING: Relocation section [%s:%s] does not match "
1979 "any DT_ entry.\n",
1980 source->name,
1981 sname);
1982 }
1983 else {
1984 INFO("Section [%s] was removed, not matching it to dynamic "
1985 "ranges.\n",
1986 sname);
1987 }
1988 } /* for ... */
1989
1990 if (source->rel.sections) sort_ranges(source->rel.sections);
1991 if (source->jmprel.sections) sort_ranges(source->jmprel.sections);
1992 }
1993
drop_sections(source_t * source)1994 static void drop_sections(source_t *source)
1995 {
1996 INFO("We are dropping some sections from [%s]--creating section entries "
1997 "only for remaining sections.\n",
1998 source->name);
1999 /* Renumber the sections. The numbers for the sections after those we are
2000 dropping will be shifted back by the number of dropped sections. */
2001 int cnt, idx;
2002 for (cnt = idx = 1; cnt < source->shnum; ++cnt) {
2003 if (source->shdr_info[cnt].idx > 0) {
2004 source->shdr_info[cnt].idx = idx++;
2005
2006 /* Create a new section. */
2007 FAILIF_LIBELF((source->shdr_info[cnt].newscn =
2008 elf_newscn(source->elf)) == NULL, elf_newscn);
2009 ASSERT(elf_ndxscn (source->shdr_info[cnt].newscn) ==
2010 source->shdr_info[cnt].idx);
2011
2012 /* Copy the section data */
2013 Elf_Data *olddata =
2014 elf_getdata(source->shdr_info[cnt].scn, // old section
2015 NULL);
2016 FAILIF_LIBELF(NULL == olddata, elf_getdata);
2017 Elf_Data *data =
2018 elf_newdata(source->shdr_info[cnt].newscn);
2019 FAILIF_LIBELF(NULL == data, elf_newdata);
2020 *data = *olddata;
2021 #if COPY_SECTION_DATA_BUFFER
2022 if (olddata->d_buf != NULL) {
2023 data->d_buf = MALLOC(data->d_size);
2024 memcpy(data->d_buf, olddata->d_buf, olddata->d_size);
2025 }
2026 #endif
2027 source->shdr_info[cnt].data = data;
2028
2029 if (data->d_size !=
2030 source->shdr_info[cnt].shdr.sh_size) {
2031 INFO("Trimming new-section data from %d to %lld bytes "
2032 "(as calculated by adjust_dynamic_segment()).\n",
2033 data->d_size,
2034 source->shdr_info[cnt].shdr.sh_size);
2035 data->d_size =
2036 source->shdr_info[cnt].shdr.sh_size;
2037 }
2038
2039 INFO("\tsection [%s] (old offset %lld, old size %lld) "
2040 "will have index %d (was %d), new size %d\n",
2041 source->shdr_info[cnt].name,
2042 source->shdr_info[cnt].old_shdr.sh_offset,
2043 source->shdr_info[cnt].old_shdr.sh_size,
2044 source->shdr_info[cnt].idx,
2045 elf_ndxscn(source->shdr_info[cnt].scn),
2046 data->d_size);
2047 } else {
2048 INFO("\tIgnoring section [%s] (offset %lld, size %lld, index %d), "
2049 "it will be discarded.\n",
2050 source->shdr_info[cnt].name,
2051 source->shdr_info[cnt].shdr.sh_offset,
2052 source->shdr_info[cnt].shdr.sh_size,
2053 elf_ndxscn(source->shdr_info[cnt].scn));
2054 }
2055
2056 /* NOTE: We mark use_old_shdr_for_relocation_calculations even for the
2057 sections we are removing. adjust_elf has an assertion that makes
2058 sure that if the values for the size of a section according to its
2059 header and its data structure differ, then we are using explicitly
2060 the old section header for calculations, and that the section in
2061 question is a relocation section.
2062 */
2063 source->shdr_info[cnt].use_old_shdr_for_relocation_calculations = true;
2064 } /* for */
2065 }
2066
process_file(const char * filename,const char * output,int is_file,void (* report_library_size_in_memory)(const char * name,off_t fsize),unsigned (* get_next_link_address)(const char * name),int locals_only,char ** lib_lookup_dirs,int num_lib_lookup_dirs,char ** default_libs,int num_default_libs,int dry_run,int * total_num_handled_relocs,int * total_num_unhandled_relocs)2067 static source_t* process_file(const char *filename,
2068 const char *output, int is_file,
2069 void (*report_library_size_in_memory)(
2070 const char *name, off_t fsize),
2071 unsigned (*get_next_link_address)(
2072 const char *name),
2073 int locals_only,
2074 char **lib_lookup_dirs,
2075 int num_lib_lookup_dirs,
2076 char **default_libs,
2077 int num_default_libs,
2078 int dry_run,
2079 int *total_num_handled_relocs,
2080 int *total_num_unhandled_relocs)
2081 {
2082 /* Look up the file in the list of already-handles files, which are
2083 represented by source_t structs. If we do not find the file, then we
2084 haven't prelinked it yet. If we find it, then we have, so we do
2085 nothing. Keep in mind that apriori operates on an entire collection
2086 of files, and if application A used library L, and so does application
2087 B, if we process A first, then by the time we get to B we will have
2088 prelinked L already; that's why we check first to see if a library has
2089 been prelinked.
2090 */
2091 source_t *source =
2092 find_source(filename, lib_lookup_dirs, num_lib_lookup_dirs);
2093 if (NULL == source) {
2094 /* If we could not find the source, then it hasn't been processed yet,
2095 so we go ahead and process it! */
2096 INFO("Processing [%s].\n", filename);
2097 char *full = find_file(filename, lib_lookup_dirs, num_lib_lookup_dirs);
2098 FAILIF(NULL == full,
2099 "Could not find [%s] in the current directory or in any of "
2100 "the search paths!\n", filename);
2101
2102 unsigned base = get_next_link_address(full);
2103
2104 source = init_source(full, output, is_file, base, dry_run);
2105
2106 if (source == NULL) {
2107 INFO("File [%s] is a static executable.\n", filename);
2108 return NULL;
2109 }
2110 ASSERT(source->dynamic.scn != NULL);
2111
2112 /* We need to increment the next prelink address only when the file we
2113 are currently handing is a shared library. Executables do not need
2114 to be prelinked at a different address, they are always at address
2115 zero.
2116
2117 Also, if we are prelinking locals only, then we are handling a
2118 single file per invokation of apriori, so there is no need to
2119 increment the prelink address unless there is a global prelink map,
2120 in which case we do need to check to see if the library isn't
2121 running into its neighbouts in the prelink map.
2122 */
2123 if (source->oldelf_hdr.e_type != ET_EXEC &&
2124 (!locals_only ||
2125 report_library_size_in_memory ==
2126 pm_report_library_size_in_memory)) {
2127 /* This sets the next link address only if an increment was not
2128 specified by the user. If an address increment was specified,
2129 then we just check to make sure that the file size is less than
2130 the increment.
2131
2132 NOTE: The file size is the absolute highest number of bytes that
2133 the file may occupy in memory, if the entire file is loaded, but
2134 this is almost next the case. A file will often have sections
2135 which are not loaded, which could add a lot of size. That's why
2136 we start off with the file size and then subtract the size of
2137 the biggest sections that will not get loaded, which are the
2138 varios DWARF sections, all of which of which are named starting
2139 with ".debug_".
2140
2141 We could do better than this (by caculating exactly how many
2142 bytes from that file will be loaded), but that's an overkill.
2143 Unless the prelink-address increment becomes too small, the file
2144 size after subtracting the sizes of the DWARF section will be a
2145 good-enough upper bound.
2146 */
2147
2148 unsigned long fsize = source->elf_file_info.st_size;
2149 INFO("Calculating loadable file size for next link address. "
2150 "Starting with %ld.\n", fsize);
2151 if (true) {
2152 Elf_Scn *scn = NULL;
2153 GElf_Shdr shdr_mem, *shdr;
2154 const char *scn_name;
2155 while ((scn = elf_nextscn (source->oldelf, scn)) != NULL) {
2156 shdr = gelf_getshdr(scn, &shdr_mem);
2157 FAILIF_LIBELF(NULL == shdr, gelf_getshdr);
2158 scn_name = elf_strptr (source->oldelf,
2159 source->shstrndx, shdr->sh_name);
2160 ASSERT(scn_name != NULL);
2161
2162 if (!(shdr->sh_flags & SHF_ALLOC)) {
2163 INFO("\tDecrementing by %lld on account of section "
2164 "[%s].\n",
2165 shdr->sh_size,
2166 scn_name);
2167 fsize -= shdr->sh_size;
2168 }
2169 }
2170 }
2171 INFO("Done calculating loadable file size for next link address: "
2172 "Final value is %ld.\n", fsize);
2173 report_library_size_in_memory(source->name, fsize);
2174 }
2175
2176 /* Identify the dynamic segment and process it. Specifically, we find
2177 out what dependencies, if any, this file has. Whenever we encounter
2178 such a dependency, we process it recursively; we find out where the
2179 various relocation information sections are stored. */
2180
2181 size_t dynidx;
2182 GElf_Dyn *dyn, dyn_mem;
2183 size_t numdyn =
2184 source->dynamic.shdr.sh_size /
2185 source->dynamic.shdr.sh_entsize;
2186 ASSERT(source->dynamic.shdr.sh_size == source->dynamic.data->d_size);
2187
2188 source->rel.idx = source->rel.sz_idx = -1;
2189 source->jmprel.idx = source->jmprel.sz_idx = -1;
2190
2191 for (dynidx = 0; dynidx < numdyn; dynidx++) {
2192 dyn = gelf_getdyn (source->dynamic.data,
2193 dynidx,
2194 &dyn_mem);
2195 FAILIF_LIBELF(NULL == dyn, gelf_getdyn);
2196 /* When we are processing only the local relocations in a file,
2197 we don't need to handle any of the dependencies. It won't
2198 hurt if we do, but we will be doing unnecessary work.
2199 */
2200 switch (dyn->d_tag)
2201 {
2202 case DT_NEEDED:
2203 if (!locals_only) {
2204 /* Process the needed library recursively.
2205 */
2206 const char *dep_lib =
2207 #if ELF_STRPTR_IS_BROKEN
2208 (((char *)elf_getdata(
2209 elf_getscn(source->elf,
2210 source->dynamic.shdr.sh_link),
2211 NULL)->d_buf) + dyn->d_un.d_val);
2212 #else
2213 elf_strptr (source->elf,
2214 source->dynamic.shdr.sh_link,
2215 dyn->d_un.d_val);
2216 #endif
2217 ASSERT(dep_lib != NULL);
2218 INFO("[%s] depends on [%s].\n", filename, dep_lib);
2219 ASSERT(output == NULL || is_file == 0);
2220 source_t *dep = process_file(dep_lib,
2221 output, is_file,
2222 report_library_size_in_memory,
2223 get_next_link_address,
2224 locals_only,
2225 lib_lookup_dirs,
2226 num_lib_lookup_dirs,
2227 default_libs,
2228 num_default_libs,
2229 dry_run,
2230 total_num_handled_relocs,
2231 total_num_unhandled_relocs);
2232
2233 /* Add the library to the dependency list. */
2234 if (source->num_lib_deps == source->lib_deps_size) {
2235 source->lib_deps_size += 10;
2236 source->lib_deps = REALLOC(source->lib_deps,
2237 source->lib_deps_size *
2238 sizeof(source_t *));
2239 }
2240 source->lib_deps[source->num_lib_deps++] = dep;
2241 }
2242 break;
2243 case DT_JMPREL:
2244 source->jmprel.idx = dynidx;
2245 source->jmprel.addr = dyn->d_un.d_ptr;
2246 break;
2247 case DT_PLTRELSZ:
2248 source->jmprel.sz_idx = dynidx;
2249 source->jmprel.size = dyn->d_un.d_val;
2250 break;
2251 case DT_REL:
2252 source->rel.idx = dynidx;
2253 source->rel.addr = dyn->d_un.d_ptr;
2254 break;
2255 case DT_RELSZ:
2256 source->rel.sz_idx = dynidx;
2257 source->rel.size = dyn->d_un.d_val;
2258 break;
2259 case DT_RELA:
2260 case DT_RELASZ:
2261 FAILIF(1, "Can't handle DT_RELA and DT_RELASZ entries!\n");
2262 break;
2263 } /* switch */
2264 } /* for each dynamic entry... */
2265
2266 INFO("Handling [%s].\n", filename);
2267
2268 #ifdef SUPPORT_ANDROID_PRELINK_TAGS
2269 if (!source->prelinked)
2270 #endif
2271 {
2272 /* When ADJUST_ELF is defined, this call to prelink is a dry run
2273 intended to calculate the number of relocations that could not
2274 be handled. This, in turn, allows us to calculate the amount by
2275 which we can shrink the various relocation sections before we
2276 call adjust_elf. After we've adjusted the sections, we will
2277 call prelink() one more time to do the actual work.
2278
2279 NOTE: Even when ADJUST_ELF != 0, we cannot adjust an ELF file
2280 that is an executabe, because an executable is not PIC.
2281 */
2282
2283 int num_unfinished_relocs = 0;
2284 bool adjust_file = ADJUST_ELF && source->elf_hdr.e_type != ET_EXEC;
2285 INFO("\n\n\tPRELINKING %s\n\n",
2286 adjust_file ?
2287 "(CALCULATE NUMBER OF HANDLED RELOCATIONS)" :
2288 "(ACTUAL)");
2289 int num_relocs = prelink(source, locals_only,
2290 adjust_file || dry_run,
2291 lib_lookup_dirs, num_lib_lookup_dirs,
2292 default_libs, num_default_libs,
2293 &num_unfinished_relocs);
2294 INFO("[%s]: (calculate changes) handled %d, could not handle %d "
2295 "relocations.\n",
2296 source->name,
2297 num_relocs,
2298 num_unfinished_relocs);
2299
2300 if (adjust_file && !dry_run)
2301 {
2302 /* Find out the new section sizes of the relocation sections,
2303 but do not move any relocations around, because adjust_elf
2304 needs to know about all relocations in order to adjust the
2305 file correctly.
2306 */
2307 match_relocation_sections_to_dynamic_ranges(source);
2308
2309 /* We haven't set up source->shdr_info[] yet, so we do it now.
2310
2311 NOTE: setup_shdr_info() depends only on source->oldelf, not
2312 on source->elf! source->elf is not even defined yet. We
2313 initialize source->shdr_info[] based on the section
2314 information of the unmodified ELF file, and then make our
2315 modifications in the call to adjust_dynamic_segment() based
2316 on this information. adjust_dynamic_segment() will
2317 rearrange the unhandled relocations in the beginning of
2318 their relocation sections, and adjust the size of those
2319 relocation sections. In the case when a relocation section
2320 is completely handled, adjust_dynamic_segment() will mark it
2321 for removal by function adjust_elf.
2322 */
2323
2324 ASSERT(source->elf == source->oldelf);
2325 ASSERT(source->shdr_info == NULL);
2326 setup_shdr_info(source);
2327 ASSERT(source->shdr_info != NULL);
2328
2329 INFO("\n\n\tADJUSTING DYNAMIC SEGMENT "
2330 "(CALCULATE CHANGES)\n\n");
2331 bool drop_some_sections = adjust_dynamic_segment(source, true);
2332
2333 /* Reopen the elf file! Note that we are not doing a dry run
2334 (the if statement above makes sure of that.)
2335
2336 NOTE: We call init_elf() after we called
2337 adjust_dynamic_segment() in order to have
2338 adjust_dynamic_segment() refer to source->oldelf when
2339 it refers to source->elf. Since
2340 adjust_dynamic_segment doesn't actually write to the
2341 ELF file, this is OK. adjust_dynamic_segment()
2342 updates the sh_size fields of saved section headers
2343 and optionally marks sections for removal.
2344
2345 Having adjust_dynamic_segment() refer to
2346 source->oldelf means that we'll have access to
2347 section-name strings so we can print them out in our
2348 logging and debug output.
2349 */
2350 source->elf = init_elf(source, false);
2351
2352 /* This is the same code as in init_source() after the call to
2353 * init_elf(). */
2354 ASSERT(source->elf != source->oldelf);
2355 ebl_closebackend(source->ebl);
2356 source->ebl = ebl_openbackend (source->elf);
2357 FAILIF_LIBELF(NULL == source->ebl, ebl_openbackend);
2358 #ifdef ARM_SPECIFIC_HACKS
2359 FAILIF_LIBELF(0 != arm_init(source->elf,
2360 source->elf_hdr.e_machine,
2361 source->ebl, sizeof(Ebl)),
2362 arm_init);
2363 #endif/*ARM_SPECIFIC_HACKS*/
2364
2365 if (drop_some_sections)
2366 drop_sections(source);
2367 else {
2368 INFO("All sections remain in [%s]--we are changing at "
2369 "most section sizes.\n", source->name);
2370 create_elf_sections(source, NULL);
2371 int cnt, idx;
2372 for (cnt = idx = 1; cnt < source->shnum; ++cnt) {
2373 Elf_Data *data = elf_getdata(
2374 source->shdr_info[cnt].newscn, // new section
2375 NULL);
2376 if (data->d_size !=
2377 source->shdr_info[cnt].shdr.sh_size) {
2378 INFO("Trimming new-section data from %d to %lld "
2379 "bytes (as calculated by "
2380 "adjust_dynamic_segment()).\n",
2381 data->d_size,
2382 source->shdr_info[cnt].shdr.sh_size);
2383 data->d_size = source->shdr_info[cnt].shdr.sh_size;
2384 }
2385 }
2386 }
2387
2388 /* Shrink it! */
2389 INFO("\n\n\tADJUSTING ELF\n\n");
2390 adjust_elf(
2391 source->oldelf, source->name,
2392 source->elf, source->name,
2393 source->ebl,
2394 &source->old_ehdr_mem,
2395 NULL, 0, // no symbol filter
2396 source->shdr_info, // information on how to adjust the ELF
2397 source->shnum, // length of source->shdr_info[]
2398 source->phdr_info, // program-header info
2399 source->shnum, // irrelevant--we're not rebuilding shstrtab
2400 source->shnum, // number of sections in file
2401 source->shstrndx, // index of shstrtab (both in
2402 // shdr_info[] and as a section index)
2403 NULL, // irrelevant, since we are not rebuilding shstrtab
2404 drop_some_sections, // some sections are being dropped
2405 elf_ndxscn(source->dynamic.scn), // index of .dynamic
2406 elf_ndxscn(source->symtab.scn), // index of .dynsym
2407 1, // allow shady business
2408 &source->shstrtab_data,
2409 true,
2410 false); // do not rebuild shstrtab
2411
2412 INFO("\n\n\tREINITIALIZING STRUCTURES "
2413 "(TO CONTAIN ADJUSTMENTS)\n\n");
2414 reinit_source(source);
2415
2416 INFO("\n\n\tPRELINKING (ACTUAL)\n\n");
2417 #ifdef DEBUG
2418 int old_num_unfinished_relocs = num_unfinished_relocs;
2419 #endif
2420 num_unfinished_relocs = 0;
2421 #ifdef DEBUG
2422 int num_relocs_take_two =
2423 #endif
2424 prelink(source, locals_only,
2425 false, /* not a dry run */
2426 lib_lookup_dirs, num_lib_lookup_dirs,
2427 default_libs, num_default_libs,
2428 &num_unfinished_relocs);
2429
2430 /* The numbers for the total number of relocations and the
2431 number of unhandled relocations between the first and second
2432 invokationof prelink() must be the same! The first time we
2433 ran prelink() just to calculate the numbers so that we could
2434 calculate the adjustments to pass to adjust_elf, and the
2435 second time we actually carry out the prelinking; the
2436 numbers must stay the same!
2437 */
2438 ASSERT(num_relocs == num_relocs_take_two);
2439 ASSERT(old_num_unfinished_relocs == num_unfinished_relocs);
2440
2441 INFO("[%s]: (actual prelink) handled %d, could not "
2442 "handle %d relocations.\n",
2443 source->name,
2444 num_relocs,
2445 num_unfinished_relocs);
2446 } /* if (adjust_elf && !dry_run) */
2447
2448 *total_num_handled_relocs += num_relocs;
2449 *total_num_unhandled_relocs += num_unfinished_relocs;
2450
2451 if(num_unfinished_relocs != 0 &&
2452 source->elf_hdr.e_type != ET_EXEC &&
2453 !locals_only)
2454 {
2455 /* One reason you could have unfinished relocations in an
2456 executable file is if this file used dlopen() and friends.
2457 We do not adjust relocation entries to those symbols,
2458 because libdl is a dummy only--the real functions are
2459 provided for by the dynamic linker itsef.
2460
2461 NOTE FIXME HACK: This is specific to the Android dynamic
2462 linker, and may not be true in other cases.
2463 */
2464 PRINT("WARNING: Expecting to have unhandled relocations only "
2465 "for executables (%s is not an executable)!\n",
2466 source->name);
2467 }
2468
2469 match_relocation_sections_to_dynamic_ranges(source);
2470
2471 /* Now, for each relocation section, check to see if its address
2472 matches one of the DT_DYNAMIC relocation pointers. If so, then
2473 if the section has no unhandled relocations, simply set the
2474 associated DT_DYNAMIC entry's size to zero. If the section does
2475 have unhandled entries, then lump them all together at the front
2476 of the respective section and update the size of the respective
2477 DT_DYNAMIC entry to the new size of the section. A better
2478 approach would be do delete a relocation section if it has been
2479 fully relocated and to remove its entry from the DT_DYNAMIC
2480 array, and for relocation entries that still have some
2481 relocations in them, we should shrink the section if that won't
2482 violate relative offsets. This is more work, however, and for
2483 the speed improvement we expect from a prelinker, just patching
2484 up DT_DYNAMIC will suffice.
2485
2486 Note: adjust_dynamic_segment() will modify source->shdr_info[]
2487 to denote any change in a relocation section's size. This
2488 will be picked up by adjust_elf, which will rearrange the
2489 file to eliminate the gap created by the decrease in size
2490 of the relocation section. We do not need to do this, but
2491 the relocation section could be large, and reduced
2492 drastically by the prelinking process, so it pays to
2493 adjust the file.
2494 */
2495
2496 INFO("\n\n\tADJUSTING DYNAMIC SEGMENT (ACTUAL)\n\n");
2497 adjust_dynamic_segment(source, false);
2498 }
2499 #ifdef SUPPORT_ANDROID_PRELINK_TAGS
2500 else INFO("[%s] is already prelinked at 0x%08lx.\n",
2501 filename,
2502 source->prelink_base);
2503 #endif
2504 } else INFO("[%s] has been processed already.\n", filename);
2505
2506 return source;
2507 }
2508
apriori(char ** execs,int num_execs,char * output,void (* report_library_size_in_memory)(const char * name,off_t fsize),int (* get_next_link_address)(const char * name),int locals_only,int dry_run,char ** lib_lookup_dirs,int num_lib_lookup_dirs,char ** default_libs,int num_default_libs,char * mapfile)2509 void apriori(char **execs, int num_execs,
2510 char *output,
2511 void (*report_library_size_in_memory)(
2512 const char *name, off_t fsize),
2513 int (*get_next_link_address)(const char *name),
2514 int locals_only,
2515 int dry_run,
2516 char **lib_lookup_dirs, int num_lib_lookup_dirs,
2517 char **default_libs, int num_default_libs,
2518 char *mapfile)
2519 {
2520 source_t *source; /* for general usage */
2521 int input_idx;
2522
2523 ASSERT(report_library_size_in_memory != NULL);
2524 ASSERT(get_next_link_address != NULL);
2525
2526 /* Process and prelink each executable and object file. Function
2527 process_file() is called for each executable in the loop below.
2528 It calls itself recursively for each library. We prelink each library
2529 after prelinking its dependencies. */
2530 int total_num_handled_relocs = 0, total_num_unhandled_relocs = 0;
2531 for (input_idx = 0; input_idx < num_execs; input_idx++) {
2532 INFO("executable: [%s]\n", execs[input_idx]);
2533 /* Here process_file() is actually processing the top-level
2534 executable files. */
2535 process_file(execs[input_idx], output, num_execs == 1,
2536 report_library_size_in_memory,
2537 get_next_link_address, /* executables get a link address
2538 of zero, regardless of this
2539 value */
2540 locals_only,
2541 lib_lookup_dirs, num_lib_lookup_dirs,
2542 default_libs, num_default_libs,
2543 dry_run,
2544 &total_num_handled_relocs,
2545 &total_num_unhandled_relocs);
2546 /* if source is NULL, then the respective executable is static */
2547 /* Mark the source as an executable */
2548 } /* for each input executable... */
2549
2550 PRINT("Handled %d relocations.\n", total_num_handled_relocs);
2551 PRINT("Could not handle %d relocations.\n", total_num_unhandled_relocs);
2552
2553 /* We are done! Since the end result of our calculations is a set of
2554 symbols for each library that other libraries or executables link
2555 against, we iterate over the set of libraries one last time, and for
2556 each symbol that is marked as satisfying some dependence, we emit
2557 a line with the symbol's name to a text file derived from the library's
2558 name by appending the suffix .syms to it. */
2559
2560 if (mapfile != NULL) {
2561 const char *mapfile_name = mapfile;
2562 FILE *fp;
2563 if (*mapfile == '+') {
2564 mapfile_name = mapfile + 1;
2565 INFO("Opening map file %s for append/write.\n",
2566 mapfile_name);
2567 fp = fopen(mapfile_name, "a");
2568 }
2569 else fp = fopen(mapfile_name, "w");
2570
2571 FAILIF(fp == NULL, "Cannot open file [%s]: %s (%d)!\n",
2572 mapfile_name,
2573 strerror(errno),
2574 errno);
2575 source = sources;
2576 while (source) {
2577 /* If it's a library, print the results. */
2578 if (source->elf_hdr.e_type == ET_DYN) {
2579 /* Add to the memory map file. */
2580 fprintf(fp, "%s 0x%08lx %lld\n",
2581 basename(source->name),
2582 source->base,
2583 source->elf_file_info.st_size);
2584 }
2585 source = source->next;
2586 }
2587 fclose(fp);
2588 }
2589
2590 /* Free the resources--you can't do it in the loop above because function
2591 print_symbol_references() accesses nodes other than the one being
2592 iterated over.
2593 */
2594 source = sources;
2595 while (source) {
2596 source_t *old = source;
2597 source = source->next;
2598 /* Destroy the evidence. */
2599 destroy_source(old);
2600 }
2601 }
2602