1 /*-
2 * Copyright (c) 2007-2011,2014 Kai Wang
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/param.h>
28 #include <sys/stat.h>
29 #include <err.h>
30 #include <libgen.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include "elfcopy.h"
36
37 ELFTC_VCSID("$Id: sections.c 3646 2018-10-27 02:25:39Z emaste $");
38
39 static void add_gnu_debuglink(struct elfcopy *ecp);
40 static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc);
41 static void check_section_rename(struct elfcopy *ecp, struct section *s);
42 static void filter_reloc(struct elfcopy *ecp, struct section *s);
43 static int get_section_flags(struct elfcopy *ecp, const char *name);
44 static void insert_sections(struct elfcopy *ecp);
45 static int is_append_section(struct elfcopy *ecp, const char *name);
46 static int is_compress_section(struct elfcopy *ecp, const char *name);
47 static int is_debug_section(const char *name);
48 static int is_dwo_section(const char *name);
49 static int is_modify_section(struct elfcopy *ecp, const char *name);
50 static int is_print_section(struct elfcopy *ecp, const char *name);
51 static void modify_section(struct elfcopy *ecp, struct section *s);
52 static void pad_section(struct elfcopy *ecp, struct section *s);
53 static void print_data(const char *d, size_t sz);
54 static void print_section(struct section *s);
55 static void *read_section(struct section *s, size_t *size);
56 static void set_shstrtab(struct elfcopy *ecp);
57 static void update_reloc(struct elfcopy *ecp, struct section *s);
58 static void update_section_group(struct elfcopy *ecp, struct section *s);
59
60 int
is_remove_section(struct elfcopy * ecp,const char * name)61 is_remove_section(struct elfcopy *ecp, const char *name)
62 {
63
64 /* Always keep section name table */
65 if (strcmp(name, ".shstrtab") == 0)
66 return 0;
67 if (strcmp(name, ".symtab") == 0 ||
68 strcmp(name, ".strtab") == 0) {
69 if (ecp->strip == STRIP_ALL && lookup_symop_list(
70 ecp, NULL, SYMOP_KEEP) == NULL)
71 return (1);
72 else
73 return (0);
74 }
75
76 if (ecp->strip == STRIP_DWO && is_dwo_section(name))
77 return (1);
78 if (ecp->strip == STRIP_NONDWO && !is_dwo_section(name))
79 return (1);
80
81 if (is_debug_section(name)) {
82 if (ecp->strip == STRIP_ALL ||
83 ecp->strip == STRIP_DEBUG ||
84 ecp->strip == STRIP_UNNEEDED ||
85 (ecp->flags & DISCARD_LOCAL))
86 return (1);
87 if (ecp->strip == STRIP_NONDEBUG)
88 return (0);
89 }
90
91 if ((ecp->flags & SEC_REMOVE) || (ecp->flags & SEC_COPY)) {
92 struct sec_action *sac;
93
94 sac = lookup_sec_act(ecp, name, 0);
95 if ((ecp->flags & SEC_REMOVE) && sac != NULL && sac->remove)
96 return (1);
97 if ((ecp->flags & SEC_COPY) && (sac == NULL || !sac->copy))
98 return (1);
99 }
100
101 return (0);
102 }
103
104 /*
105 * Relocation section needs to be removed if the section it applies to
106 * will be removed.
107 */
108 int
is_remove_reloc_sec(struct elfcopy * ecp,uint32_t sh_info)109 is_remove_reloc_sec(struct elfcopy *ecp, uint32_t sh_info)
110 {
111 const char *name;
112 GElf_Shdr ish;
113 Elf_Scn *is;
114 size_t indx;
115 int elferr;
116
117 if (elf_getshstrndx(ecp->ein, &indx) == 0)
118 errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
119 elf_errmsg(-1));
120
121 is = elf_getscn(ecp->ein, sh_info);
122 if (is != NULL) {
123 if (gelf_getshdr(is, &ish) == NULL)
124 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
125 elf_errmsg(-1));
126 if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) ==
127 NULL)
128 errx(EXIT_FAILURE, "elf_strptr failed: %s",
129 elf_errmsg(-1));
130 if (is_remove_section(ecp, name))
131 return (1);
132 else
133 return (0);
134 }
135 elferr = elf_errno();
136 if (elferr != 0)
137 errx(EXIT_FAILURE, "elf_nextscn failed: %s",
138 elf_errmsg(elferr));
139
140 /* Remove reloc section if we can't find the target section. */
141 return (1);
142 }
143
144 static int
is_append_section(struct elfcopy * ecp,const char * name)145 is_append_section(struct elfcopy *ecp, const char *name)
146 {
147 struct sec_action *sac;
148
149 sac = lookup_sec_act(ecp, name, 0);
150 if (sac != NULL && sac->append != 0 && sac->string != NULL)
151 return (1);
152
153 return (0);
154 }
155
156 static int
is_compress_section(struct elfcopy * ecp,const char * name)157 is_compress_section(struct elfcopy *ecp, const char *name)
158 {
159 struct sec_action *sac;
160
161 sac = lookup_sec_act(ecp, name, 0);
162 if (sac != NULL && sac->compress != 0)
163 return (1);
164
165 return (0);
166 }
167
168 static void
check_section_rename(struct elfcopy * ecp,struct section * s)169 check_section_rename(struct elfcopy *ecp, struct section *s)
170 {
171 struct sec_action *sac;
172 char *prefix;
173 size_t namelen;
174
175 if (s->pseudo)
176 return;
177
178 sac = lookup_sec_act(ecp, s->name, 0);
179 if (sac != NULL && sac->rename)
180 s->name = sac->newname;
181
182 if (!strcmp(s->name, ".symtab") ||
183 !strcmp(s->name, ".strtab") ||
184 !strcmp(s->name, ".shstrtab"))
185 return;
186
187 prefix = NULL;
188 if (s->loadable && ecp->prefix_alloc != NULL)
189 prefix = ecp->prefix_alloc;
190 else if (ecp->prefix_sec != NULL)
191 prefix = ecp->prefix_sec;
192
193 if (prefix != NULL) {
194 namelen = strlen(s->name) + strlen(prefix) + 1;
195 if ((s->newname = malloc(namelen)) == NULL)
196 err(EXIT_FAILURE, "malloc failed");
197 snprintf(s->newname, namelen, "%s%s", prefix, s->name);
198 s->name = s->newname;
199 }
200 }
201
202 static int
get_section_flags(struct elfcopy * ecp,const char * name)203 get_section_flags(struct elfcopy *ecp, const char *name)
204 {
205 struct sec_action *sac;
206
207 sac = lookup_sec_act(ecp, name, 0);
208 if (sac != NULL && sac->flags)
209 return sac->flags;
210
211 return (0);
212 }
213
214 /*
215 * Determine whether the section are debugging section.
216 * According to libbfd, debugging sections are recognized
217 * only by name.
218 */
219 static int
is_debug_section(const char * name)220 is_debug_section(const char *name)
221 {
222 const char *dbg_sec[] = {
223 ".apple_",
224 ".debug",
225 ".gnu.linkonce.wi.",
226 ".line",
227 ".stab",
228 NULL
229 };
230 const char **p;
231
232 for(p = dbg_sec; *p; p++) {
233 if (strncmp(name, *p, strlen(*p)) == 0)
234 return (1);
235 }
236
237 return (0);
238 }
239
240 static int
is_dwo_section(const char * name)241 is_dwo_section(const char *name)
242 {
243 size_t len;
244
245 if ((len = strlen(name)) > 4 && strcmp(name + len - 4, ".dwo") == 0)
246 return (1);
247 return (0);
248 }
249
250 static int
is_print_section(struct elfcopy * ecp,const char * name)251 is_print_section(struct elfcopy *ecp, const char *name)
252 {
253 struct sec_action *sac;
254
255 sac = lookup_sec_act(ecp, name, 0);
256 if (sac != NULL && sac->print != 0)
257 return (1);
258
259 return (0);
260 }
261
262 static int
is_modify_section(struct elfcopy * ecp,const char * name)263 is_modify_section(struct elfcopy *ecp, const char *name)
264 {
265
266 if (is_append_section(ecp, name) ||
267 is_compress_section(ecp, name))
268 return (1);
269
270 return (0);
271 }
272
273 struct sec_action*
lookup_sec_act(struct elfcopy * ecp,const char * name,int add)274 lookup_sec_act(struct elfcopy *ecp, const char *name, int add)
275 {
276 struct sec_action *sac;
277
278 if (name == NULL)
279 return NULL;
280
281 STAILQ_FOREACH(sac, &ecp->v_sac, sac_list) {
282 if (strcmp(name, sac->name) == 0)
283 return sac;
284 }
285
286 if (add == 0)
287 return NULL;
288
289 if ((sac = malloc(sizeof(*sac))) == NULL)
290 errx(EXIT_FAILURE, "not enough memory");
291 memset(sac, 0, sizeof(*sac));
292 sac->name = name;
293 STAILQ_INSERT_TAIL(&ecp->v_sac, sac, sac_list);
294
295 return (sac);
296 }
297
298 void
free_sec_act(struct elfcopy * ecp)299 free_sec_act(struct elfcopy *ecp)
300 {
301 struct sec_action *sac, *sac_temp;
302
303 STAILQ_FOREACH_SAFE(sac, &ecp->v_sac, sac_list, sac_temp) {
304 STAILQ_REMOVE(&ecp->v_sac, sac, sec_action, sac_list);
305 free(sac);
306 }
307 }
308
309 void
insert_to_sec_list(struct elfcopy * ecp,struct section * sec,int tail)310 insert_to_sec_list(struct elfcopy *ecp, struct section *sec, int tail)
311 {
312 struct section *s;
313
314 if (tail || TAILQ_EMPTY(&ecp->v_sec) ||
315 TAILQ_LAST(&ecp->v_sec, sectionlist)->off <= sec->off) {
316 TAILQ_INSERT_TAIL(&ecp->v_sec, sec, sec_list);
317 } else {
318 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
319 if (sec->off < s->off) {
320 TAILQ_INSERT_BEFORE(s, sec, sec_list);
321 break;
322 }
323 }
324 }
325
326 if (sec->pseudo == 0)
327 ecp->nos++;
328 }
329
330 /*
331 * First step of section creation: create scn and internal section
332 * structure, discard sections to be removed.
333 */
334 void
create_scn(struct elfcopy * ecp)335 create_scn(struct elfcopy *ecp)
336 {
337 struct section *s;
338 const char *name;
339 Elf_Scn *is;
340 GElf_Shdr ish;
341 size_t indx;
342 uint64_t oldndx, newndx;
343 int elferr, sec_flags, reorder;
344
345 /*
346 * Insert a pseudo section that contains the ELF header
347 * and program header. Used as reference for section offset
348 * or load address adjustment.
349 */
350 if ((s = calloc(1, sizeof(*s))) == NULL)
351 err(EXIT_FAILURE, "calloc failed");
352 s->off = 0;
353 s->sz = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT) +
354 gelf_fsize(ecp->eout, ELF_T_PHDR, ecp->ophnum, EV_CURRENT);
355 s->align = 1;
356 s->pseudo = 1;
357 s->loadable = add_to_inseg_list(ecp, s);
358 insert_to_sec_list(ecp, s, 0);
359
360 /* Create internal .shstrtab section. */
361 init_shstrtab(ecp);
362
363 if (elf_getshstrndx(ecp->ein, &indx) == 0)
364 errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
365 elf_errmsg(-1));
366
367 reorder = 0;
368 is = NULL;
369 while ((is = elf_nextscn(ecp->ein, is)) != NULL) {
370 if (gelf_getshdr(is, &ish) == NULL)
371 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
372 elf_errmsg(-1));
373 if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == NULL)
374 errx(EXIT_FAILURE, "elf_strptr failed: %s",
375 elf_errmsg(-1));
376
377 /* Skip sections to be removed. */
378 if (is_remove_section(ecp, name))
379 continue;
380
381 /*
382 * Relocation section need to be remove if the section
383 * it applies will be removed.
384 */
385 if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA)
386 if (ish.sh_info != 0 &&
387 is_remove_reloc_sec(ecp, ish.sh_info))
388 continue;
389
390 /*
391 * Section groups should be removed if symbol table will
392 * be removed. (section group's signature stored in symbol
393 * table)
394 */
395 if (ish.sh_type == SHT_GROUP && ecp->strip == STRIP_ALL)
396 continue;
397
398 /* Get section flags set by user. */
399 sec_flags = get_section_flags(ecp, name);
400
401 /* Create internal section object. */
402 if (strcmp(name, ".shstrtab") != 0) {
403 if ((s = calloc(1, sizeof(*s))) == NULL)
404 err(EXIT_FAILURE, "calloc failed");
405 s->name = name;
406 s->is = is;
407 s->off = ish.sh_offset;
408 s->sz = ish.sh_size;
409 s->align = ish.sh_addralign;
410 s->type = ish.sh_type;
411 s->flags = ish.sh_flags;
412 s->vma = ish.sh_addr;
413
414 /*
415 * Search program headers to determine whether section
416 * is loadable, but if user explicitly set section flags
417 * while neither "load" nor "alloc" is set, we make the
418 * section unloadable.
419 *
420 * Sections in relocatable object is loadable if
421 * section flag SHF_ALLOC is set.
422 */
423 if (sec_flags &&
424 (sec_flags & (SF_LOAD | SF_ALLOC)) == 0)
425 s->loadable = 0;
426 else {
427 s->loadable = add_to_inseg_list(ecp, s);
428 if ((ecp->flags & RELOCATABLE) &&
429 (ish.sh_flags & SHF_ALLOC))
430 s->loadable = 1;
431 }
432 } else {
433 /* Assuming .shstrtab is "unloadable". */
434 s = ecp->shstrtab;
435 s->off = ish.sh_offset;
436 }
437
438 oldndx = newndx = SHN_UNDEF;
439 if (strcmp(name, ".symtab") != 0 &&
440 strcmp(name, ".strtab") != 0) {
441 if (!strcmp(name, ".shstrtab")) {
442 /*
443 * Add sections specified by --add-section and
444 * gnu debuglink. we want these sections have
445 * smaller index than .shstrtab section.
446 */
447 if (ecp->debuglink != NULL)
448 add_gnu_debuglink(ecp);
449 if (ecp->flags & SEC_ADD)
450 insert_sections(ecp);
451 }
452 if ((s->os = elf_newscn(ecp->eout)) == NULL)
453 errx(EXIT_FAILURE, "elf_newscn failed: %s",
454 elf_errmsg(-1));
455 if ((newndx = elf_ndxscn(s->os)) == SHN_UNDEF)
456 errx(EXIT_FAILURE, "elf_ndxscn failed: %s",
457 elf_errmsg(-1));
458 }
459 if ((oldndx = elf_ndxscn(is)) == SHN_UNDEF)
460 errx(EXIT_FAILURE, "elf_ndxscn failed: %s",
461 elf_errmsg(-1));
462 if (oldndx != SHN_UNDEF && newndx != SHN_UNDEF)
463 ecp->secndx[oldndx] = newndx;
464
465 /*
466 * If strip action is STRIP_NONDEBUG(only keep debug),
467 * change sections type of loadable sections and section
468 * groups to SHT_NOBITS, and the content of those sections
469 * will be discarded. However, SHT_NOTE sections should
470 * be kept.
471 */
472 if (ecp->strip == STRIP_NONDEBUG) {
473 if (((ish.sh_flags & SHF_ALLOC) ||
474 (ish.sh_flags & SHF_GROUP)) &&
475 ish.sh_type != SHT_NOTE)
476 s->type = SHT_NOBITS;
477 }
478
479 check_section_rename(ecp, s);
480
481 /* create section header based on input object. */
482 if (strcmp(name, ".symtab") != 0 &&
483 strcmp(name, ".strtab") != 0 &&
484 strcmp(name, ".shstrtab") != 0) {
485 copy_shdr(ecp, s, NULL, 0, sec_flags);
486 /*
487 * elfcopy puts .symtab, .strtab and .shstrtab
488 * sections in the end of the output object.
489 * If the input objects have more sections
490 * after any of these 3 sections, the section
491 * table will be reordered. section symbols
492 * should be regenerated for relocations.
493 */
494 if (reorder)
495 ecp->flags &= ~SYMTAB_INTACT;
496 } else
497 reorder = 1;
498
499 if (strcmp(name, ".symtab") == 0) {
500 ecp->flags |= SYMTAB_EXIST;
501 ecp->symtab = s;
502 }
503 if (strcmp(name, ".strtab") == 0)
504 ecp->strtab = s;
505
506 insert_to_sec_list(ecp, s, 0);
507 }
508 elferr = elf_errno();
509 if (elferr != 0)
510 errx(EXIT_FAILURE, "elf_nextscn failed: %s",
511 elf_errmsg(elferr));
512 }
513
514 struct section *
insert_shtab(struct elfcopy * ecp,int tail)515 insert_shtab(struct elfcopy *ecp, int tail)
516 {
517 struct section *s, *shtab;
518 GElf_Ehdr ieh;
519 int nsecs;
520
521 /*
522 * Treat section header table as a "pseudo" section, insert it
523 * into section list, so later it will get sorted and resynced
524 * just as normal sections.
525 */
526 if ((shtab = calloc(1, sizeof(*shtab))) == NULL)
527 errx(EXIT_FAILURE, "calloc failed");
528 if (!tail) {
529 /*
530 * "shoff" of input object is used as a hint for section
531 * resync later.
532 */
533 if (gelf_getehdr(ecp->ein, &ieh) == NULL)
534 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
535 elf_errmsg(-1));
536 shtab->off = ieh.e_shoff;
537 } else
538 shtab->off = 0;
539 /* Calculate number of sections in the output object. */
540 nsecs = 0;
541 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
542 if (!s->pseudo)
543 nsecs++;
544 }
545 /* Remember there is always a null section, so we +1 here. */
546 shtab->sz = gelf_fsize(ecp->eout, ELF_T_SHDR, nsecs + 1, EV_CURRENT);
547 if (shtab->sz == 0)
548 errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1));
549 shtab->align = (ecp->oec == ELFCLASS32 ? 4 : 8);
550 shtab->loadable = 0;
551 shtab->pseudo = 1;
552 insert_to_sec_list(ecp, shtab, tail);
553
554 return (shtab);
555 }
556
557 void
copy_content(struct elfcopy * ecp)558 copy_content(struct elfcopy *ecp)
559 {
560 struct section *s;
561
562 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
563 /* Skip pseudo section. */
564 if (s->pseudo)
565 continue;
566
567 /* Skip special sections. */
568 if (strcmp(s->name, ".symtab") == 0 ||
569 strcmp(s->name, ".strtab") == 0 ||
570 strcmp(s->name, ".shstrtab") == 0)
571 continue;
572
573 /*
574 * If strip action is STRIP_ALL, relocation info need
575 * to be stripped. Skip filtering otherwisw.
576 */
577 if (ecp->strip == STRIP_ALL &&
578 (s->type == SHT_REL || s->type == SHT_RELA))
579 filter_reloc(ecp, s);
580
581 /*
582 * The section indices in the SHT_GROUP section needs
583 * to be updated since we might have stripped some
584 * sections and changed section numbering.
585 */
586 if (s->type == SHT_GROUP)
587 update_section_group(ecp, s);
588
589 if (is_modify_section(ecp, s->name))
590 modify_section(ecp, s);
591
592 copy_data(s);
593
594 /*
595 * If symbol table is modified, relocation info might
596 * need update, as symbol index may have changed.
597 */
598 if ((ecp->flags & SYMTAB_INTACT) == 0 &&
599 (ecp->flags & SYMTAB_EXIST) &&
600 (s->type == SHT_REL || s->type == SHT_RELA))
601 update_reloc(ecp, s);
602
603 if (is_print_section(ecp, s->name))
604 print_section(s);
605 }
606 }
607
608
609 /*
610 * Update section group section. The section indices in the SHT_GROUP
611 * section need update after section numbering changed.
612 */
613 static void
update_section_group(struct elfcopy * ecp,struct section * s)614 update_section_group(struct elfcopy *ecp, struct section *s)
615 {
616 GElf_Shdr ish;
617 Elf_Data *id;
618 uint32_t *ws, *wd;
619 uint64_t n;
620 size_t ishnum;
621 int i, j;
622
623 if (!elf_getshnum(ecp->ein, &ishnum))
624 errx(EXIT_FAILURE, "elf_getshnum failed: %s",
625 elf_errmsg(-1));
626
627 if (gelf_getshdr(s->is, &ish) == NULL)
628 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
629 elf_errmsg(-1));
630
631 if ((id = elf_getdata(s->is, NULL)) == NULL)
632 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
633 elf_errmsg(-1));
634
635 if (ish.sh_size == 0)
636 return;
637
638 if (ish.sh_entsize == 0)
639 ish.sh_entsize = 4;
640
641 ws = id->d_buf;
642
643 /* We only support COMDAT section. */
644 #ifndef GRP_COMDAT
645 #define GRP_COMDAT 0x1
646 #endif
647 if ((*ws & GRP_COMDAT) == 0)
648 return;
649
650 if ((s->buf = malloc(ish.sh_size)) == NULL)
651 err(EXIT_FAILURE, "malloc failed");
652
653 s->sz = ish.sh_size;
654
655 wd = s->buf;
656
657 /* Copy the flag word as-is. */
658 *wd = *ws;
659
660 /* Update the section indices. */
661 n = ish.sh_size / ish.sh_entsize;
662 for(i = 1, j = 1; (uint64_t)i < n; i++) {
663 if (ws[i] != SHN_UNDEF && ws[i] < ishnum &&
664 ecp->secndx[ws[i]] != 0)
665 wd[j++] = ecp->secndx[ws[i]];
666 else
667 s->sz -= 4;
668 }
669
670 s->nocopy = 1;
671 }
672
673 /*
674 * Filter relocation entries, only keep those entries whose
675 * symbol is in the keep list.
676 */
677 static void
filter_reloc(struct elfcopy * ecp,struct section * s)678 filter_reloc(struct elfcopy *ecp, struct section *s)
679 {
680 const char *name;
681 GElf_Shdr ish;
682 GElf_Rel rel;
683 GElf_Rela rela;
684 Elf32_Rel *rel32;
685 Elf64_Rel *rel64;
686 Elf32_Rela *rela32;
687 Elf64_Rela *rela64;
688 Elf_Data *id;
689 uint64_t cap, n, nrels, sym;
690 int elferr, i;
691
692 if (gelf_getshdr(s->is, &ish) == NULL)
693 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
694 elf_errmsg(-1));
695
696 /* We don't want to touch relocation info for dynamic symbols. */
697 if ((ecp->flags & SYMTAB_EXIST) == 0) {
698 /*
699 * No symbol table in output. If sh_link points to a section
700 * that exists in the output object, this relocation section
701 * is for dynamic symbols. Don't touch it.
702 */
703 if (ish.sh_link != 0 && ecp->secndx[ish.sh_link] != 0)
704 return;
705 } else {
706 /* Symbol table exist, check if index equals. */
707 if (ish.sh_link != elf_ndxscn(ecp->symtab->is))
708 return;
709 }
710
711 #define COPYREL(REL, SZ) do { \
712 if (nrels == 0) { \
713 if ((REL##SZ = malloc(cap * \
714 sizeof(*REL##SZ))) == NULL) \
715 err(EXIT_FAILURE, "malloc failed"); \
716 } \
717 if (nrels >= cap) { \
718 cap *= 2; \
719 if ((REL##SZ = realloc(REL##SZ, cap * \
720 sizeof(*REL##SZ))) == NULL) \
721 err(EXIT_FAILURE, "realloc failed"); \
722 } \
723 REL##SZ[nrels].r_offset = REL.r_offset; \
724 REL##SZ[nrels].r_info = REL.r_info; \
725 if (s->type == SHT_RELA) \
726 rela##SZ[nrels].r_addend = rela.r_addend; \
727 nrels++; \
728 } while (0)
729
730 nrels = 0;
731 cap = 4; /* keep list is usually small. */
732 rel32 = NULL;
733 rel64 = NULL;
734 rela32 = NULL;
735 rela64 = NULL;
736 if ((id = elf_getdata(s->is, NULL)) == NULL)
737 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
738 elf_errmsg(-1));
739 n = ish.sh_size / ish.sh_entsize;
740 for(i = 0; (uint64_t)i < n; i++) {
741 if (s->type == SHT_REL) {
742 if (gelf_getrel(id, i, &rel) != &rel)
743 errx(EXIT_FAILURE, "gelf_getrel failed: %s",
744 elf_errmsg(-1));
745 sym = GELF_R_SYM(rel.r_info);
746 } else {
747 if (gelf_getrela(id, i, &rela) != &rela)
748 errx(EXIT_FAILURE, "gelf_getrel failed: %s",
749 elf_errmsg(-1));
750 sym = GELF_R_SYM(rela.r_info);
751 }
752 /*
753 * If a relocation references a symbol and we are omitting
754 * either that symbol or the entire symbol table we cannot
755 * produce valid output, and so just omit the relocation.
756 * Broken output like this is generally not useful, but some
757 * uses of elfcopy/strip rely on it - for example, GCC's build
758 * process uses it to check for build reproducibility by
759 * stripping objects and comparing them.
760 *
761 * Relocations that do not reference a symbol are retained.
762 */
763 if (sym != 0) {
764 if (ish.sh_link == 0 || ecp->secndx[ish.sh_link] == 0)
765 continue;
766 name = elf_strptr(ecp->ein, elf_ndxscn(ecp->strtab->is),
767 sym);
768 if (name == NULL)
769 errx(EXIT_FAILURE, "elf_strptr failed: %s",
770 elf_errmsg(-1));
771 if (lookup_symop_list(ecp, name, SYMOP_KEEP) == NULL)
772 continue;
773 }
774 if (ecp->oec == ELFCLASS32) {
775 if (s->type == SHT_REL)
776 COPYREL(rel, 32);
777 else
778 COPYREL(rela, 32);
779 } else {
780 if (s->type == SHT_REL)
781 COPYREL(rel, 64);
782 else
783 COPYREL(rela, 64);
784 }
785 }
786 elferr = elf_errno();
787 if (elferr != 0)
788 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
789 elf_errmsg(elferr));
790
791 if (ecp->oec == ELFCLASS32) {
792 if (s->type == SHT_REL)
793 s->buf = rel32;
794 else
795 s->buf = rela32;
796 } else {
797 if (s->type == SHT_REL)
798 s->buf = rel64;
799 else
800 s->buf = rela64;
801 }
802 s->sz = gelf_fsize(ecp->eout, (s->type == SHT_REL ? ELF_T_REL :
803 ELF_T_RELA), nrels, EV_CURRENT);
804 s->nocopy = 1;
805 }
806
807 static void
update_reloc(struct elfcopy * ecp,struct section * s)808 update_reloc(struct elfcopy *ecp, struct section *s)
809 {
810 GElf_Shdr osh;
811 GElf_Rel rel;
812 GElf_Rela rela;
813 Elf_Data *od;
814 uint64_t n;
815 int i;
816
817 #define UPDATEREL(REL) do { \
818 if (gelf_get##REL(od, i, &REL) != &REL) \
819 errx(EXIT_FAILURE, "gelf_get##REL failed: %s", \
820 elf_errmsg(-1)); \
821 REL.r_info = GELF_R_INFO(ecp->symndx[GELF_R_SYM(REL.r_info)], \
822 GELF_R_TYPE(REL.r_info)); \
823 if (!gelf_update_##REL(od, i, &REL)) \
824 errx(EXIT_FAILURE, "gelf_update_##REL failed: %s", \
825 elf_errmsg(-1)); \
826 } while(0)
827
828 if (s->sz == 0)
829 return;
830 if (gelf_getshdr(s->os, &osh) == NULL)
831 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
832 elf_errmsg(-1));
833 /* Only process .symtab reloc info. */
834 if (osh.sh_link != elf_ndxscn(ecp->symtab->is))
835 return;
836 if ((od = elf_getdata(s->os, NULL)) == NULL)
837 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
838 elf_errmsg(-1));
839 n = osh.sh_size / osh.sh_entsize;
840 for(i = 0; (uint64_t)i < n; i++) {
841 if (s->type == SHT_REL)
842 UPDATEREL(rel);
843 else
844 UPDATEREL(rela);
845 }
846 }
847
848 static void
pad_section(struct elfcopy * ecp,struct section * s)849 pad_section(struct elfcopy *ecp, struct section *s)
850 {
851 GElf_Shdr osh;
852 Elf_Data *od;
853
854 if (s == NULL || s->pad_sz == 0)
855 return;
856
857 if ((s->pad = malloc(s->pad_sz)) == NULL)
858 err(EXIT_FAILURE, "malloc failed");
859 memset(s->pad, ecp->fill, s->pad_sz);
860
861 /* Create a new Elf_Data to contain the padding bytes. */
862 if ((od = elf_newdata(s->os)) == NULL)
863 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
864 elf_errmsg(-1));
865 od->d_align = 1;
866 od->d_off = s->sz;
867 od->d_buf = s->pad;
868 od->d_type = ELF_T_BYTE;
869 od->d_size = s->pad_sz;
870 od->d_version = EV_CURRENT;
871
872 /* Update section header. */
873 if (gelf_getshdr(s->os, &osh) == NULL)
874 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
875 elf_errmsg(-1));
876 osh.sh_size = s->sz + s->pad_sz;
877 if (!gelf_update_shdr(s->os, &osh))
878 errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
879 elf_errmsg(-1));
880 }
881
882 void
resync_sections(struct elfcopy * ecp)883 resync_sections(struct elfcopy *ecp)
884 {
885 struct section *s, *ps;
886 GElf_Shdr osh;
887 uint64_t off;
888 int first;
889
890 ps = NULL;
891 first = 1;
892 off = 0;
893 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
894 if (first) {
895 off = s->off;
896 first = 0;
897 }
898
899 /*
900 * Ignore TLS sections with load address 0 and without
901 * content. We don't need to adjust their file offset or
902 * VMA, only the size matters.
903 */
904 if (s->seg_tls != NULL && s->type == SHT_NOBITS &&
905 s->off == 0)
906 continue;
907
908 /* Align section offset. */
909 if (s->align == 0)
910 s->align = 1;
911 if (off <= s->off) {
912 if (!s->loadable || (ecp->flags & RELOCATABLE))
913 s->off = roundup(off, s->align);
914 } else {
915 if (s->loadable && (ecp->flags & RELOCATABLE) == 0)
916 warnx("moving loadable section %s, "
917 "is this intentional?", s->name);
918 s->off = roundup(off, s->align);
919 }
920
921 /* Calculate next section offset. */
922 off = s->off;
923 if (s->pseudo || (s->type != SHT_NOBITS && s->type != SHT_NULL))
924 off += s->sz;
925
926 if (s->pseudo) {
927 ps = NULL;
928 continue;
929 }
930
931 /* Count padding bytes added through --pad-to. */
932 if (s->pad_sz > 0)
933 off += s->pad_sz;
934
935 /* Update section header accordingly. */
936 if (gelf_getshdr(s->os, &osh) == NULL)
937 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
938 elf_errmsg(-1));
939 osh.sh_addr = s->vma;
940 osh.sh_offset = s->off;
941 osh.sh_size = s->sz;
942 if (!gelf_update_shdr(s->os, &osh))
943 errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
944 elf_errmsg(-1));
945
946 /* Add padding for previous section, if need. */
947 if (ps != NULL) {
948 if (ps->pad_sz > 0) {
949 /* Apply padding added by --pad-to. */
950 pad_section(ecp, ps);
951 } else if ((ecp->flags & GAP_FILL) &&
952 (ps->off + ps->sz < s->off)) {
953 /*
954 * Fill the gap between sections by padding
955 * the section with lower address.
956 */
957 ps->pad_sz = s->off - (ps->off + ps->sz);
958 pad_section(ecp, ps);
959 }
960 }
961
962 ps = s;
963 }
964
965 /* Pad the last section, if need. */
966 if (ps != NULL && ps->pad_sz > 0)
967 pad_section(ecp, ps);
968 }
969
970 static void
modify_section(struct elfcopy * ecp,struct section * s)971 modify_section(struct elfcopy *ecp, struct section *s)
972 {
973 struct sec_action *sac;
974 size_t srcsz, dstsz, p, len;
975 char *b, *c, *d, *src, *end;
976 int dupe;
977
978 src = read_section(s, &srcsz);
979 if (src == NULL || srcsz == 0) {
980 /* For empty section, we proceed if we need to append. */
981 if (!is_append_section(ecp, s->name))
982 return;
983 }
984
985 /* Allocate buffer needed for new section data. */
986 dstsz = srcsz;
987 if (is_append_section(ecp, s->name)) {
988 sac = lookup_sec_act(ecp, s->name, 0);
989 dstsz += strlen(sac->string) + 1;
990 }
991 if ((b = malloc(dstsz)) == NULL)
992 err(EXIT_FAILURE, "malloc failed");
993 s->buf = b;
994
995 /* Compress section. */
996 p = 0;
997 if (is_compress_section(ecp, s->name)) {
998 end = src + srcsz;
999 for(c = src; c < end;) {
1000 len = 0;
1001 while(c + len < end && c[len] != '\0')
1002 len++;
1003 if (c + len == end) {
1004 /* XXX should we warn here? */
1005 strncpy(&b[p], c, len);
1006 p += len;
1007 break;
1008 }
1009 dupe = 0;
1010 for (d = b; d < b + p; ) {
1011 if (strcmp(d, c) == 0) {
1012 dupe = 1;
1013 break;
1014 }
1015 d += strlen(d) + 1;
1016 }
1017 if (!dupe) {
1018 strncpy(&b[p], c, len);
1019 b[p + len] = '\0';
1020 p += len + 1;
1021 }
1022 c += len + 1;
1023 }
1024 } else {
1025 memcpy(b, src, srcsz);
1026 p += srcsz;
1027 }
1028
1029 /* Append section. */
1030 if (is_append_section(ecp, s->name)) {
1031 sac = lookup_sec_act(ecp, s->name, 0);
1032 len = strlen(sac->string);
1033 strncpy(&b[p], sac->string, len);
1034 b[p + len] = '\0';
1035 p += len + 1;
1036 }
1037
1038 s->sz = p;
1039 s->nocopy = 1;
1040 }
1041
1042 static void
print_data(const char * d,size_t sz)1043 print_data(const char *d, size_t sz)
1044 {
1045 const char *c;
1046
1047 for (c = d; c < d + sz; c++) {
1048 if (*c == '\0')
1049 putchar('\n');
1050 else
1051 putchar(*c);
1052 }
1053 }
1054
1055 static void
print_section(struct section * s)1056 print_section(struct section *s)
1057 {
1058 Elf_Data *id;
1059 int elferr;
1060
1061 if (s->buf != NULL && s->sz > 0) {
1062 print_data(s->buf, s->sz);
1063 } else {
1064 id = NULL;
1065 while ((id = elf_getdata(s->is, id)) != NULL ||
1066 (id = elf_rawdata(s->is, id)) != NULL) {
1067 (void) elf_errno();
1068 print_data(id->d_buf, id->d_size);
1069 }
1070 elferr = elf_errno();
1071 if (elferr != 0)
1072 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
1073 elf_errmsg(elferr));
1074 }
1075 putchar('\n');
1076 }
1077
1078 static void *
read_section(struct section * s,size_t * size)1079 read_section(struct section *s, size_t *size)
1080 {
1081 Elf_Data *id;
1082 char *b;
1083 size_t sz;
1084 int elferr;
1085
1086 sz = 0;
1087 b = NULL;
1088 id = NULL;
1089 while ((id = elf_getdata(s->is, id)) != NULL ||
1090 (id = elf_rawdata(s->is, id)) != NULL) {
1091 (void) elf_errno();
1092 if (b == NULL)
1093 b = malloc(id->d_size);
1094 else
1095 b = malloc(sz + id->d_size);
1096 if (b == NULL)
1097 err(EXIT_FAILURE, "malloc or realloc failed");
1098
1099 memcpy(&b[sz], id->d_buf, id->d_size);
1100 sz += id->d_size;
1101 }
1102 elferr = elf_errno();
1103 if (elferr != 0)
1104 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
1105 elf_errmsg(elferr));
1106
1107 *size = sz;
1108
1109 return (b);
1110 }
1111
1112 void
copy_shdr(struct elfcopy * ecp,struct section * s,const char * name,int copy,int sec_flags)1113 copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy,
1114 int sec_flags)
1115 {
1116 GElf_Shdr ish, osh;
1117
1118 if (gelf_getshdr(s->is, &ish) == NULL)
1119 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1120 elf_errmsg(-1));
1121 if (gelf_getshdr(s->os, &osh) == NULL)
1122 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1123 elf_errmsg(-1));
1124
1125 if (copy)
1126 (void) memcpy(&osh, &ish, sizeof(ish));
1127 else {
1128 osh.sh_type = s->type;
1129 osh.sh_addr = s->vma;
1130 osh.sh_offset = s->off;
1131 osh.sh_size = s->sz;
1132 osh.sh_link = ish.sh_link;
1133 osh.sh_info = ish.sh_info;
1134 osh.sh_addralign = s->align;
1135 osh.sh_entsize = ish.sh_entsize;
1136
1137 if (sec_flags) {
1138 osh.sh_flags = 0;
1139 if (sec_flags & SF_ALLOC)
1140 osh.sh_flags |= SHF_ALLOC;
1141 if ((sec_flags & SF_READONLY) == 0)
1142 osh.sh_flags |= SHF_WRITE;
1143 if (sec_flags & SF_CODE)
1144 osh.sh_flags |= SHF_EXECINSTR;
1145 if ((sec_flags & SF_CONTENTS) &&
1146 s->type == SHT_NOBITS && s->sz > 0) {
1147 /*
1148 * Convert SHT_NOBITS section to section with
1149 * (zero'ed) content on file.
1150 */
1151 osh.sh_type = s->type = SHT_PROGBITS;
1152 if ((s->buf = calloc(1, s->sz)) == NULL)
1153 err(EXIT_FAILURE, "malloc failed");
1154 s->nocopy = 1;
1155 }
1156 } else {
1157 osh.sh_flags = ish.sh_flags;
1158 /*
1159 * Newer binutils as(1) emits the section flag
1160 * SHF_INFO_LINK for relocation sections. elfcopy
1161 * emits this flag in the output section if it's
1162 * missing in the input section, to remain compatible
1163 * with binutils.
1164 */
1165 if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA)
1166 osh.sh_flags |= SHF_INFO_LINK;
1167 }
1168 }
1169
1170 if (name == NULL)
1171 add_to_shstrtab(ecp, s->name);
1172 else
1173 add_to_shstrtab(ecp, name);
1174
1175 if (!gelf_update_shdr(s->os, &osh))
1176 errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
1177 elf_errmsg(-1));
1178 }
1179
1180 void
copy_data(struct section * s)1181 copy_data(struct section *s)
1182 {
1183 Elf_Data *id, *od;
1184 int elferr;
1185
1186 if (s->nocopy && s->buf == NULL)
1187 return;
1188
1189 if ((id = elf_getdata(s->is, NULL)) == NULL) {
1190 (void) elf_errno();
1191 if ((id = elf_rawdata(s->is, NULL)) == NULL) {
1192 elferr = elf_errno();
1193 if (elferr != 0)
1194 errx(EXIT_FAILURE, "failed to read section:"
1195 " %s", s->name);
1196 return;
1197 }
1198 }
1199
1200 if ((od = elf_newdata(s->os)) == NULL)
1201 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1202 elf_errmsg(-1));
1203
1204 if (s->nocopy) {
1205 /* Use s->buf as content if s->nocopy is set. */
1206 od->d_align = id->d_align;
1207 od->d_off = 0;
1208 od->d_buf = s->buf;
1209 od->d_type = id->d_type;
1210 od->d_size = s->sz;
1211 od->d_version = id->d_version;
1212 } else {
1213 od->d_align = id->d_align;
1214 od->d_off = id->d_off;
1215 od->d_buf = id->d_buf;
1216 od->d_type = id->d_type;
1217 od->d_size = id->d_size;
1218 od->d_version = id->d_version;
1219 }
1220
1221 /*
1222 * Alignment Fixup. libelf does not allow the alignment for
1223 * Elf_Data descriptor to be set to 0. In this case we workaround
1224 * it by setting the alignment to 1.
1225 *
1226 * According to the ELF ABI, alignment 0 and 1 has the same
1227 * meaning: the section has no alignment constraints.
1228 */
1229 if (od->d_align == 0)
1230 od->d_align = 1;
1231 }
1232
1233 struct section *
create_external_section(struct elfcopy * ecp,const char * name,char * newname,void * buf,uint64_t size,uint64_t off,uint64_t stype,Elf_Type dtype,uint64_t flags,uint64_t align,uint64_t vma,int loadable)1234 create_external_section(struct elfcopy *ecp, const char *name, char *newname,
1235 void *buf, uint64_t size, uint64_t off, uint64_t stype, Elf_Type dtype,
1236 uint64_t flags, uint64_t align, uint64_t vma, int loadable)
1237 {
1238 struct section *s;
1239 Elf_Scn *os;
1240 Elf_Data *od;
1241 GElf_Shdr osh;
1242
1243 if ((os = elf_newscn(ecp->eout)) == NULL)
1244 errx(EXIT_FAILURE, "elf_newscn() failed: %s",
1245 elf_errmsg(-1));
1246 if ((s = calloc(1, sizeof(*s))) == NULL)
1247 err(EXIT_FAILURE, "calloc failed");
1248 s->name = name;
1249 s->newname = newname; /* needs to be free()'ed */
1250 s->off = off;
1251 s->sz = size;
1252 s->vma = vma;
1253 s->align = align;
1254 s->loadable = loadable;
1255 s->is = NULL;
1256 s->os = os;
1257 s->type = stype;
1258 s->nocopy = 1;
1259 insert_to_sec_list(ecp, s, 1);
1260
1261 if (gelf_getshdr(os, &osh) == NULL)
1262 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1263 elf_errmsg(-1));
1264 osh.sh_flags = flags;
1265 osh.sh_type = s->type;
1266 osh.sh_addr = s->vma;
1267 osh.sh_addralign = s->align;
1268 if (!gelf_update_shdr(os, &osh))
1269 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1270 elf_errmsg(-1));
1271 add_to_shstrtab(ecp, name);
1272
1273 if (buf != NULL && size != 0) {
1274 if ((od = elf_newdata(os)) == NULL)
1275 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1276 elf_errmsg(-1));
1277 od->d_align = align;
1278 od->d_off = 0;
1279 od->d_buf = buf;
1280 od->d_size = size;
1281 od->d_type = dtype;
1282 od->d_version = EV_CURRENT;
1283 }
1284
1285 /*
1286 * Clear SYMTAB_INTACT, as we probably need to update/add new
1287 * STT_SECTION symbols into the symbol table.
1288 */
1289 ecp->flags &= ~SYMTAB_INTACT;
1290
1291 return (s);
1292 }
1293
1294 /*
1295 * Insert sections specified by --add-section to the end of section list.
1296 */
1297 static void
insert_sections(struct elfcopy * ecp)1298 insert_sections(struct elfcopy *ecp)
1299 {
1300 struct sec_add *sa;
1301 struct section *s;
1302 size_t off;
1303 uint64_t stype;
1304
1305 /* Put these sections in the end of current list. */
1306 off = 0;
1307 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1308 if (s->type != SHT_NOBITS && s->type != SHT_NULL)
1309 off = s->off + s->sz;
1310 else
1311 off = s->off;
1312 }
1313
1314 STAILQ_FOREACH(sa, &ecp->v_sadd, sadd_list) {
1315
1316 /* TODO: Add section header vma/lma, flag changes here */
1317
1318 /*
1319 * The default section type for user added section is
1320 * SHT_PROGBITS. If the section name match certain patterns,
1321 * elfcopy will try to set a more appropriate section type.
1322 * However, data type is always set to ELF_T_BYTE and no
1323 * translation is performed by libelf.
1324 */
1325 stype = SHT_PROGBITS;
1326 if (strcmp(sa->name, ".note") == 0 ||
1327 strncmp(sa->name, ".note.", strlen(".note.")) == 0)
1328 stype = SHT_NOTE;
1329
1330 (void) create_external_section(ecp, sa->name, NULL, sa->content,
1331 sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0);
1332 }
1333 }
1334
1335 void
add_to_shstrtab(struct elfcopy * ecp,const char * name)1336 add_to_shstrtab(struct elfcopy *ecp, const char *name)
1337 {
1338
1339 if (elftc_string_table_insert(ecp->shstrtab->strtab, name) == 0)
1340 errx(EXIT_FAILURE, "elftc_string_table_insert failed");
1341 }
1342
1343 void
update_shdr(struct elfcopy * ecp,int update_link)1344 update_shdr(struct elfcopy *ecp, int update_link)
1345 {
1346 struct section *s;
1347 GElf_Shdr osh;
1348 int elferr;
1349
1350 /* Finalize the section name string table (.shstrtab). */
1351 set_shstrtab(ecp);
1352
1353 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1354 if (s->pseudo)
1355 continue;
1356
1357 if (gelf_getshdr(s->os, &osh) == NULL)
1358 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
1359 elf_errmsg(-1));
1360
1361 /* Find section name in string table and set sh_name. */
1362 osh.sh_name = elftc_string_table_lookup(ecp->shstrtab->strtab,
1363 s->name);
1364
1365 /*
1366 * sh_link needs to be updated, since the index of the
1367 * linked section might have changed.
1368 */
1369 if (update_link && osh.sh_link != 0)
1370 osh.sh_link = ecp->secndx[osh.sh_link];
1371
1372 /*
1373 * sh_info of relocation section links to the section to which
1374 * its relocation info applies. So it may need update as well.
1375 */
1376 if ((s->type == SHT_REL || s->type == SHT_RELA) &&
1377 osh.sh_info != 0)
1378 osh.sh_info = ecp->secndx[osh.sh_info];
1379
1380 /*
1381 * sh_info of SHT_GROUP section needs to point to the correct
1382 * string in the symbol table.
1383 */
1384 if (s->type == SHT_GROUP && (ecp->flags & SYMTAB_EXIST) &&
1385 (ecp->flags & SYMTAB_INTACT) == 0)
1386 osh.sh_info = ecp->symndx[osh.sh_info];
1387
1388 if (!gelf_update_shdr(s->os, &osh))
1389 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1390 elf_errmsg(-1));
1391 }
1392 elferr = elf_errno();
1393 if (elferr != 0)
1394 errx(EXIT_FAILURE, "elf_nextscn failed: %s",
1395 elf_errmsg(elferr));
1396 }
1397
1398 void
init_shstrtab(struct elfcopy * ecp)1399 init_shstrtab(struct elfcopy *ecp)
1400 {
1401 Elf_Scn *shstrtab;
1402 GElf_Shdr shdr;
1403 struct section *s;
1404 size_t indx, sizehint;
1405
1406 if (elf_getshdrstrndx(ecp->ein, &indx) == 0) {
1407 shstrtab = elf_getscn(ecp->ein, indx);
1408 if (shstrtab == NULL)
1409 errx(EXIT_FAILURE, "elf_getscn failed: %s",
1410 elf_errmsg(-1));
1411 if (gelf_getshdr(shstrtab, &shdr) != &shdr)
1412 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
1413 elf_errmsg(-1));
1414 sizehint = shdr.sh_size;
1415 } else {
1416 /* Clear the error from elf_getshdrstrndx(3). */
1417 (void)elf_errno();
1418 sizehint = 0;
1419 }
1420
1421 if ((ecp->shstrtab = calloc(1, sizeof(*ecp->shstrtab))) == NULL)
1422 err(EXIT_FAILURE, "calloc failed");
1423 s = ecp->shstrtab;
1424 s->name = ".shstrtab";
1425 s->is = NULL;
1426 s->sz = 0;
1427 s->align = 1;
1428 s->loadable = 0;
1429 s->type = SHT_STRTAB;
1430 s->vma = 0;
1431 s->strtab = elftc_string_table_create(sizehint);
1432
1433 add_to_shstrtab(ecp, "");
1434 add_to_shstrtab(ecp, ".symtab");
1435 add_to_shstrtab(ecp, ".strtab");
1436 add_to_shstrtab(ecp, ".shstrtab");
1437 }
1438
1439 static void
set_shstrtab(struct elfcopy * ecp)1440 set_shstrtab(struct elfcopy *ecp)
1441 {
1442 struct section *s;
1443 Elf_Data *data;
1444 GElf_Shdr sh;
1445 const char *image;
1446 size_t sz;
1447
1448 s = ecp->shstrtab;
1449
1450 if (s->os == NULL) {
1451 /* Input object does not contain .shstrtab section */
1452 if ((s->os = elf_newscn(ecp->eout)) == NULL)
1453 errx(EXIT_FAILURE, "elf_newscn failed: %s",
1454 elf_errmsg(-1));
1455 insert_to_sec_list(ecp, s, 1);
1456 }
1457
1458 if (gelf_getshdr(s->os, &sh) == NULL)
1459 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1460 elf_errmsg(-1));
1461 sh.sh_addr = 0;
1462 sh.sh_addralign = 1;
1463 sh.sh_offset = s->off;
1464 sh.sh_type = SHT_STRTAB;
1465 sh.sh_flags = 0;
1466 sh.sh_entsize = 0;
1467 sh.sh_info = 0;
1468 sh.sh_link = 0;
1469
1470 if ((data = elf_newdata(s->os)) == NULL)
1471 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1472 elf_errmsg(-1));
1473
1474 /*
1475 * If we don't have a symbol table, skip those a few bytes
1476 * which are reserved for this in the beginning of shstrtab.
1477 */
1478 if (!(ecp->flags & SYMTAB_EXIST)) {
1479 elftc_string_table_remove(s->strtab, ".symtab");
1480 elftc_string_table_remove(s->strtab, ".strtab");
1481 }
1482
1483 image = elftc_string_table_image(s->strtab, &sz);
1484 s->sz = sz;
1485
1486 sh.sh_size = sz;
1487 if (!gelf_update_shdr(s->os, &sh))
1488 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1489 elf_errmsg(-1));
1490
1491 data->d_align = 1;
1492 data->d_buf = (void *)(uintptr_t)image;
1493 data->d_size = sz;
1494 data->d_off = 0;
1495 data->d_type = ELF_T_BYTE;
1496 data->d_version = EV_CURRENT;
1497
1498 if (!elf_setshstrndx(ecp->eout, elf_ndxscn(s->os)))
1499 errx(EXIT_FAILURE, "elf_setshstrndx() failed: %s",
1500 elf_errmsg(-1));
1501 }
1502
1503 void
add_section(struct elfcopy * ecp,const char * arg)1504 add_section(struct elfcopy *ecp, const char *arg)
1505 {
1506 struct sec_add *sa;
1507 struct stat sb;
1508 const char *s, *fn;
1509 FILE *fp;
1510 int len;
1511
1512 if ((s = strchr(arg, '=')) == NULL)
1513 errx(EXIT_FAILURE,
1514 "illegal format for --add-section option");
1515 if ((sa = malloc(sizeof(*sa))) == NULL)
1516 err(EXIT_FAILURE, "malloc failed");
1517
1518 len = s - arg;
1519 if ((sa->name = malloc(len + 1)) == NULL)
1520 err(EXIT_FAILURE, "malloc failed");
1521 strncpy(sa->name, arg, len);
1522 sa->name[len] = '\0';
1523
1524 fn = s + 1;
1525 if (stat(fn, &sb) == -1)
1526 err(EXIT_FAILURE, "stat failed");
1527 sa->size = sb.st_size;
1528 if (sa->size > 0) {
1529 if ((sa->content = malloc(sa->size)) == NULL)
1530 err(EXIT_FAILURE, "malloc failed");
1531 if ((fp = fopen(fn, "r")) == NULL)
1532 err(EXIT_FAILURE, "can not open %s", fn);
1533 if (fread(sa->content, 1, sa->size, fp) == 0 ||
1534 ferror(fp))
1535 err(EXIT_FAILURE, "fread failed");
1536 fclose(fp);
1537 } else
1538 sa->content = NULL;
1539
1540 STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1541 ecp->flags |= SEC_ADD;
1542 }
1543
1544 void
free_sec_add(struct elfcopy * ecp)1545 free_sec_add(struct elfcopy *ecp)
1546 {
1547 struct sec_add *sa, *sa_temp;
1548
1549 STAILQ_FOREACH_SAFE(sa, &ecp->v_sadd, sadd_list, sa_temp) {
1550 STAILQ_REMOVE(&ecp->v_sadd, sa, sec_add, sadd_list);
1551 free(sa->name);
1552 free(sa->content);
1553 free(sa);
1554 }
1555 }
1556
1557 static void
add_gnu_debuglink(struct elfcopy * ecp)1558 add_gnu_debuglink(struct elfcopy *ecp)
1559 {
1560 struct sec_add *sa;
1561 struct stat sb;
1562 FILE *fp;
1563 char *fnbase, *buf;
1564 int crc_off;
1565 int crc;
1566
1567 if (ecp->debuglink == NULL)
1568 return;
1569
1570 /* Read debug file content. */
1571 if ((sa = malloc(sizeof(*sa))) == NULL)
1572 err(EXIT_FAILURE, "malloc failed");
1573 if ((sa->name = strdup(".gnu_debuglink")) == NULL)
1574 err(EXIT_FAILURE, "strdup failed");
1575 if (stat(ecp->debuglink, &sb) == -1)
1576 err(EXIT_FAILURE, "stat failed");
1577 if (sb.st_size == 0)
1578 errx(EXIT_FAILURE, "empty debug link target %s",
1579 ecp->debuglink);
1580 if ((buf = malloc(sb.st_size)) == NULL)
1581 err(EXIT_FAILURE, "malloc failed");
1582 if ((fp = fopen(ecp->debuglink, "r")) == NULL)
1583 err(EXIT_FAILURE, "can not open %s", ecp->debuglink);
1584 if (fread(buf, 1, sb.st_size, fp) == 0 ||
1585 ferror(fp))
1586 err(EXIT_FAILURE, "fread failed");
1587 fclose(fp);
1588
1589 /* Calculate crc checksum. */
1590 crc = calc_crc32(buf, sb.st_size, 0xFFFFFFFF);
1591 free(buf);
1592
1593 /* Calculate section size and the offset to store crc checksum. */
1594 if ((fnbase = basename(ecp->debuglink)) == NULL)
1595 err(EXIT_FAILURE, "basename failed");
1596 crc_off = roundup(strlen(fnbase) + 1, 4);
1597 sa->size = crc_off + 4;
1598
1599 /* Section content. */
1600 if ((sa->content = calloc(1, sa->size)) == NULL)
1601 err(EXIT_FAILURE, "malloc failed");
1602 strncpy(sa->content, fnbase, strlen(fnbase));
1603 if (ecp->oed == ELFDATA2LSB) {
1604 sa->content[crc_off] = crc & 0xFF;
1605 sa->content[crc_off + 1] = (crc >> 8) & 0xFF;
1606 sa->content[crc_off + 2] = (crc >> 16) & 0xFF;
1607 sa->content[crc_off + 3] = crc >> 24;
1608 } else {
1609 sa->content[crc_off] = crc >> 24;
1610 sa->content[crc_off + 1] = (crc >> 16) & 0xFF;
1611 sa->content[crc_off + 2] = (crc >> 8) & 0xFF;
1612 sa->content[crc_off + 3] = crc & 0xFF;
1613 }
1614
1615 STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1616 ecp->flags |= SEC_ADD;
1617 }
1618
1619 static uint32_t crctable[256] =
1620 {
1621 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
1622 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
1623 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
1624 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
1625 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
1626 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
1627 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
1628 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
1629 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
1630 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
1631 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
1632 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
1633 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
1634 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
1635 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
1636 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
1637 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
1638 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
1639 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
1640 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
1641 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
1642 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
1643 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
1644 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
1645 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
1646 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
1647 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
1648 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
1649 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
1650 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
1651 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
1652 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
1653 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
1654 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
1655 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
1656 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
1657 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
1658 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
1659 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
1660 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
1661 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
1662 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
1663 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
1664 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
1665 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
1666 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
1667 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
1668 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
1669 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
1670 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
1671 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
1672 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
1673 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
1674 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
1675 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
1676 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
1677 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
1678 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
1679 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
1680 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
1681 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
1682 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
1683 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
1684 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
1685 };
1686
1687 static uint32_t
calc_crc32(const char * p,size_t len,uint32_t crc)1688 calc_crc32(const char *p, size_t len, uint32_t crc)
1689 {
1690 uint32_t i;
1691
1692 for (i = 0; i < len; i++) {
1693 crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8);
1694 }
1695
1696 return (crc ^ 0xFFFFFFFF);
1697 }
1698