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