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