2 * Copyright (c) 2007-2011,2014 Kai Wang
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 #include <sys/param.h>
37 ELFTC_VCSID("$Id: sections.c 3758 2019-06-28 01:16:50Z emaste $");
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);
61 is_remove_section(struct elfcopy *ecp, const char *name)
64 /* Always keep section name table */
65 if (strcmp(name, ".shstrtab") == 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)
76 if (ecp->strip == STRIP_DWO && is_dwo_section(name))
78 if (ecp->strip == STRIP_NONDWO && !is_dwo_section(name))
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))
87 if (ecp->strip == STRIP_NONDEBUG)
91 if ((ecp->flags & SEC_REMOVE) || (ecp->flags & SEC_COPY)) {
92 struct sec_action *sac;
94 sac = lookup_sec_act(ecp, name, 0);
95 if ((ecp->flags & SEC_REMOVE) && sac != NULL && sac->remove)
97 if ((ecp->flags & SEC_COPY) && (sac == NULL || !sac->copy))
105 * Relocation section needs to be removed if the section it applies to
109 is_remove_reloc_sec(struct elfcopy *ecp, uint32_t sh_info)
117 if (elf_getshstrndx(ecp->ein, &indx) == 0)
118 errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
121 is = elf_getscn(ecp->ein, sh_info);
123 if (gelf_getshdr(is, &ish) == NULL)
124 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
126 if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) ==
128 errx(EXIT_FAILURE, "elf_strptr failed: %s",
130 if (is_remove_section(ecp, name))
135 elferr = elf_errno();
137 errx(EXIT_FAILURE, "elf_nextscn failed: %s",
140 /* Remove reloc section if we can't find the target section. */
145 is_append_section(struct elfcopy *ecp, const char *name)
147 struct sec_action *sac;
149 sac = lookup_sec_act(ecp, name, 0);
150 if (sac != NULL && sac->append != 0 && sac->string != NULL)
157 is_compress_section(struct elfcopy *ecp, const char *name)
159 struct sec_action *sac;
161 sac = lookup_sec_act(ecp, name, 0);
162 if (sac != NULL && sac->compress != 0)
169 check_section_rename(struct elfcopy *ecp, struct section *s)
171 struct sec_action *sac;
178 sac = lookup_sec_act(ecp, s->name, 0);
179 if (sac != NULL && sac->rename)
180 s->name = sac->newname;
182 if (!strcmp(s->name, ".symtab") ||
183 !strcmp(s->name, ".strtab") ||
184 !strcmp(s->name, ".shstrtab"))
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;
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;
203 get_section_flags(struct elfcopy *ecp, const char *name)
205 struct sec_action *sac;
207 sac = lookup_sec_act(ecp, name, 0);
208 if (sac != NULL && sac->flags)
215 * Determine whether the section are debugging section.
216 * According to libbfd, debugging sections are recognized
220 is_debug_section(const char *name)
222 const char *dbg_sec[] = {
232 for(p = dbg_sec; *p; p++) {
233 if (strncmp(name, *p, strlen(*p)) == 0)
241 is_dwo_section(const char *name)
245 if ((len = strlen(name)) > 4 && strcmp(name + len - 4, ".dwo") == 0)
251 is_print_section(struct elfcopy *ecp, const char *name)
253 struct sec_action *sac;
255 sac = lookup_sec_act(ecp, name, 0);
256 if (sac != NULL && sac->print != 0)
263 is_modify_section(struct elfcopy *ecp, const char *name)
266 if (is_append_section(ecp, name) ||
267 is_compress_section(ecp, name))
274 lookup_sec_act(struct elfcopy *ecp, const char *name, int add)
276 struct sec_action *sac;
281 STAILQ_FOREACH(sac, &ecp->v_sac, sac_list) {
282 if (strcmp(name, sac->name) == 0)
289 if ((sac = malloc(sizeof(*sac))) == NULL)
290 errx(EXIT_FAILURE, "not enough memory");
291 memset(sac, 0, sizeof(*sac));
293 STAILQ_INSERT_TAIL(&ecp->v_sac, sac, sac_list);
299 free_sec_act(struct elfcopy *ecp)
301 struct sec_action *sac, *sac_temp;
303 STAILQ_FOREACH_SAFE(sac, &ecp->v_sac, sac_list, sac_temp) {
304 STAILQ_REMOVE(&ecp->v_sac, sac, sec_action, sac_list);
310 insert_to_sec_list(struct elfcopy *ecp, struct section *sec, int tail)
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);
318 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
319 if (sec->off < s->off) {
320 TAILQ_INSERT_BEFORE(s, sec, sec_list);
326 if (sec->pseudo == 0)
331 * First step of section creation: create scn and internal section
332 * structure, discard sections to be removed.
335 create_scn(struct elfcopy *ecp)
342 uint64_t oldndx, newndx;
343 int elferr, sec_flags, reorder;
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.
350 if ((s = calloc(1, sizeof(*s))) == NULL)
351 err(EXIT_FAILURE, "calloc failed");
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);
357 s->loadable = add_to_inseg_list(ecp, s);
358 insert_to_sec_list(ecp, s, 0);
360 /* Create internal .shstrtab section. */
363 if (elf_getshstrndx(ecp->ein, &indx) == 0)
364 errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
369 while ((is = elf_nextscn(ecp->ein, is)) != NULL) {
370 if (gelf_getshdr(is, &ish) == NULL)
371 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
373 if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == NULL)
374 errx(EXIT_FAILURE, "elf_strptr failed: %s",
377 /* Skip sections to be removed. */
378 if (is_remove_section(ecp, name))
382 * Relocation section need to be remove if the section
383 * it applies will be removed.
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))
391 * Section groups should be removed if symbol table will
392 * be removed. (section group's signature stored in symbol
395 if (ish.sh_type == SHT_GROUP && ecp->strip == STRIP_ALL)
398 /* Get section flags set by user. */
399 sec_flags = get_section_flags(ecp, name);
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");
407 s->off = ish.sh_offset;
409 s->align = ish.sh_addralign;
410 s->type = ish.sh_type;
411 s->flags = ish.sh_flags;
412 s->vma = ish.sh_addr;
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.
420 * Sections in relocatable object is loadable if
421 * section flag SHF_ALLOC is set.
424 (sec_flags & (SF_LOAD | SF_ALLOC)) == 0)
427 s->loadable = add_to_inseg_list(ecp, s);
428 if ((ecp->flags & RELOCATABLE) &&
429 (ish.sh_flags & SHF_ALLOC))
433 /* Assuming .shstrtab is "unloadable". */
435 s->off = ish.sh_offset;
438 oldndx = newndx = SHN_UNDEF;
439 if (strcmp(name, ".symtab") != 0 &&
440 strcmp(name, ".strtab") != 0) {
441 if (!strcmp(name, ".shstrtab")) {
443 * Add sections specified by --add-section and
444 * gnu debuglink. we want these sections have
445 * smaller index than .shstrtab section.
447 if (ecp->debuglink != NULL)
448 add_gnu_debuglink(ecp);
449 if (ecp->flags & SEC_ADD)
450 insert_sections(ecp);
452 if ((s->os = elf_newscn(ecp->eout)) == NULL)
453 errx(EXIT_FAILURE, "elf_newscn failed: %s",
455 if ((newndx = elf_ndxscn(s->os)) == SHN_UNDEF)
456 errx(EXIT_FAILURE, "elf_ndxscn failed: %s",
459 if ((oldndx = elf_ndxscn(is)) == SHN_UNDEF)
460 errx(EXIT_FAILURE, "elf_ndxscn failed: %s",
462 if (oldndx != SHN_UNDEF && newndx != SHN_UNDEF)
463 ecp->secndx[oldndx] = newndx;
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
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;
479 check_section_rename(ecp, s);
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);
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.
495 ecp->flags &= ~SYMTAB_INTACT;
499 if (strcmp(name, ".symtab") == 0) {
500 ecp->flags |= SYMTAB_EXIST;
503 if (strcmp(name, ".strtab") == 0)
506 insert_to_sec_list(ecp, s, 0);
508 elferr = elf_errno();
510 errx(EXIT_FAILURE, "elf_nextscn failed: %s",
515 insert_shtab(struct elfcopy *ecp, int tail)
517 struct section *s, *shtab;
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.
526 if ((shtab = calloc(1, sizeof(*shtab))) == NULL)
527 errx(EXIT_FAILURE, "calloc failed");
530 * "shoff" of input object is used as a hint for section
533 if (gelf_getehdr(ecp->ein, &ieh) == NULL)
534 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
536 shtab->off = ieh.e_shoff;
539 /* Calculate number of sections in the output object. */
541 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
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);
548 errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1));
549 shtab->align = (ecp->oec == ELFCLASS32 ? 4 : 8);
552 insert_to_sec_list(ecp, shtab, tail);
558 copy_content(struct elfcopy *ecp)
562 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
563 /* Skip pseudo section. */
567 /* Skip special sections. */
568 if (strcmp(s->name, ".symtab") == 0 ||
569 strcmp(s->name, ".strtab") == 0 ||
570 strcmp(s->name, ".shstrtab") == 0)
574 * If strip action is STRIP_ALL, relocation info need
575 * to be stripped. Skip filtering otherwisw.
577 if (ecp->strip == STRIP_ALL &&
578 (s->type == SHT_REL || s->type == SHT_RELA))
579 filter_reloc(ecp, s);
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.
586 if (s->type == SHT_GROUP)
587 update_section_group(ecp, s);
589 if (is_modify_section(ecp, s->name))
590 modify_section(ecp, s);
595 * If symbol table is modified, relocation info might
596 * need update, as symbol index may have changed.
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);
603 if (is_print_section(ecp, s->name))
610 * Update section group section. The section indices in the SHT_GROUP
611 * section need update after section numbering changed.
614 update_section_group(struct elfcopy *ecp, struct section *s)
623 if (!elf_getshnum(ecp->ein, &ishnum))
624 errx(EXIT_FAILURE, "elf_getshnum failed: %s",
627 if (gelf_getshdr(s->is, &ish) == NULL)
628 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
631 if ((id = elf_getdata(s->is, NULL)) == NULL)
632 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
635 if (ish.sh_size == 0)
638 if (ish.sh_entsize == 0)
643 /* We only support COMDAT section. */
645 #define GRP_COMDAT 0x1
647 if ((*ws & GRP_COMDAT) == 0)
650 if ((s->buf = malloc(ish.sh_size)) == NULL)
651 err(EXIT_FAILURE, "malloc failed");
657 /* Copy the flag word as-is. */
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]];
674 * Filter relocation entries, only keep those entries whose
675 * symbol is in the keep list.
678 filter_reloc(struct elfcopy *ecp, struct section *s)
689 uint64_t cap, n, nrels, sym;
692 if (gelf_getshdr(s->is, &ish) == NULL)
693 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
696 /* We don't want to touch relocation info for dynamic symbols. */
697 if ((ecp->flags & SYMTAB_EXIST) == 0) {
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.
703 if (ish.sh_link != 0 && ecp->secndx[ish.sh_link] != 0)
706 /* Symbol table exist, check if index equals. */
707 if (ish.sh_link != elf_ndxscn(ecp->symtab->is))
711 #define COPYREL(REL, SZ) do { \
713 if ((REL##SZ = malloc(cap * \
714 sizeof(*REL##SZ))) == NULL) \
715 err(EXIT_FAILURE, "malloc failed"); \
717 if (nrels >= cap) { \
719 if ((REL##SZ = realloc(REL##SZ, cap * \
720 sizeof(*REL##SZ))) == NULL) \
721 err(EXIT_FAILURE, "realloc failed"); \
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; \
731 cap = 4; /* keep list is usually small. */
736 if ((id = elf_getdata(s->is, NULL)) == NULL)
737 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
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",
745 sym = GELF_R_SYM(rel.r_info);
747 if (gelf_getrela(id, i, &rela) != &rela)
748 errx(EXIT_FAILURE, "gelf_getrel failed: %s",
750 sym = GELF_R_SYM(rela.r_info);
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.
761 * Relocations that do not reference a symbol are retained.
764 if (ish.sh_link == 0 || ecp->secndx[ish.sh_link] == 0)
766 name = elf_strptr(ecp->ein, elf_ndxscn(ecp->strtab->is),
769 errx(EXIT_FAILURE, "elf_strptr failed: %s",
771 if (lookup_symop_list(ecp, name, SYMOP_KEEP) == NULL)
774 if (ecp->oec == ELFCLASS32) {
775 if (s->type == SHT_REL)
780 if (s->type == SHT_REL)
786 elferr = elf_errno();
788 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
791 if (ecp->oec == ELFCLASS32) {
792 if (s->type == SHT_REL)
797 if (s->type == SHT_REL)
802 s->sz = gelf_fsize(ecp->eout, (s->type == SHT_REL ? ELF_T_REL :
803 ELF_T_RELA), nrels, EV_CURRENT);
808 update_reloc(struct elfcopy *ecp, struct section *s)
817 #define UPDATEREL(REL) do { \
818 if (gelf_get##REL(od, i, &REL) != &REL) \
819 errx(EXIT_FAILURE, "gelf_get##REL failed: %s", \
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", \
830 if (gelf_getshdr(s->os, &osh) == NULL)
831 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
833 /* Only process .symtab reloc info. */
834 if (osh.sh_link != elf_ndxscn(ecp->symtab->is))
836 if ((od = elf_getdata(s->os, NULL)) == NULL)
837 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
839 n = osh.sh_size / osh.sh_entsize;
840 for(i = 0; (uint64_t)i < n; i++) {
841 if (s->type == SHT_REL)
849 pad_section(struct elfcopy *ecp, struct section *s)
854 if (s == NULL || s->pad_sz == 0)
857 if ((s->pad = malloc(s->pad_sz)) == NULL)
858 err(EXIT_FAILURE, "malloc failed");
859 memset(s->pad, ecp->fill, s->pad_sz);
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",
868 od->d_type = ELF_T_BYTE;
869 od->d_size = s->pad_sz;
870 od->d_version = EV_CURRENT;
872 /* Update section header. */
873 if (gelf_getshdr(s->os, &osh) == NULL)
874 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
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",
883 section_type_alignment(int sht, int class)
892 case SHT_PREINIT_ARRAY:
896 return (class == ELFCLASS64 ? 8 : 4);
899 case SHT_GNU_LIBLIST:
903 case SHT_SUNW_verdef: /* == SHT_GNU_verdef */
904 case SHT_SUNW_verneed: /* == SHT_GNU_verneed */
905 case SHT_SYMTAB_SHNDX:
907 case SHT_SUNW_syminfo:
908 case SHT_SUNW_versym: /* == SHT_GNU_versym */
920 resync_sections(struct elfcopy *ecp)
922 struct section *s, *ps;
931 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
938 * Ignore TLS sections with load address 0 and without
939 * content. We don't need to adjust their file offset or
940 * VMA, only the size matters.
942 if (s->seg_tls != NULL && s->type == SHT_NOBITS &&
946 /* Align section offset. */
949 min_alignment = section_type_alignment(s->type, ecp->oec);
950 if (s->align < INT_MAX && (int)s->align < min_alignment) {
951 warnx("section %s alignment %d increased to %d",
952 s->name, (int)s->align, min_alignment);
953 s->align = min_alignment;
956 if (!s->loadable || (ecp->flags & RELOCATABLE))
957 s->off = roundup(off, s->align);
959 if (s->loadable && (ecp->flags & RELOCATABLE) == 0)
960 warnx("moving loadable section %s, "
961 "is this intentional?", s->name);
962 s->off = roundup(off, s->align);
965 /* Calculate next section offset. */
967 if (s->pseudo || (s->type != SHT_NOBITS && s->type != SHT_NULL))
975 /* Count padding bytes added through --pad-to. */
979 /* Update section header accordingly. */
980 if (gelf_getshdr(s->os, &osh) == NULL)
981 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
983 osh.sh_addr = s->vma;
984 osh.sh_addralign = s->align;
985 osh.sh_offset = s->off;
987 if (!gelf_update_shdr(s->os, &osh))
988 errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
991 /* Add padding for previous section, if need. */
993 if (ps->pad_sz > 0) {
994 /* Apply padding added by --pad-to. */
995 pad_section(ecp, ps);
996 } else if ((ecp->flags & GAP_FILL) &&
997 (ps->off + ps->sz < s->off)) {
999 * Fill the gap between sections by padding
1000 * the section with lower address.
1002 ps->pad_sz = s->off - (ps->off + ps->sz);
1003 pad_section(ecp, ps);
1010 /* Pad the last section, if need. */
1011 if (ps != NULL && ps->pad_sz > 0)
1012 pad_section(ecp, ps);
1016 modify_section(struct elfcopy *ecp, struct section *s)
1018 struct sec_action *sac;
1019 size_t srcsz, dstsz, p, len;
1020 char *b, *c, *d, *src, *end;
1023 src = read_section(s, &srcsz);
1024 if (src == NULL || srcsz == 0) {
1025 /* For empty section, we proceed if we need to append. */
1026 if (!is_append_section(ecp, s->name))
1030 /* Allocate buffer needed for new section data. */
1032 if (is_append_section(ecp, s->name)) {
1033 sac = lookup_sec_act(ecp, s->name, 0);
1034 dstsz += strlen(sac->string) + 1;
1036 if ((b = malloc(dstsz)) == NULL)
1037 err(EXIT_FAILURE, "malloc failed");
1040 /* Compress section. */
1042 if (is_compress_section(ecp, s->name)) {
1044 for(c = src; c < end;) {
1046 while(c + len < end && c[len] != '\0')
1048 if (c + len == end) {
1049 /* XXX should we warn here? */
1050 strncpy(&b[p], c, len);
1055 for (d = b; d < b + p; ) {
1056 if (strcmp(d, c) == 0) {
1063 strncpy(&b[p], c, len);
1070 memcpy(b, src, srcsz);
1074 /* Append section. */
1075 if (is_append_section(ecp, s->name)) {
1076 sac = lookup_sec_act(ecp, s->name, 0);
1077 len = strlen(sac->string);
1078 strncpy(&b[p], sac->string, len);
1088 print_data(const char *d, size_t sz)
1092 for (c = d; c < d + sz; c++) {
1101 print_section(struct section *s)
1106 if (s->buf != NULL && s->sz > 0) {
1107 print_data(s->buf, s->sz);
1110 while ((id = elf_getdata(s->is, id)) != NULL ||
1111 (id = elf_rawdata(s->is, id)) != NULL) {
1113 print_data(id->d_buf, id->d_size);
1115 elferr = elf_errno();
1117 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
1118 elf_errmsg(elferr));
1124 read_section(struct section *s, size_t *size)
1134 while ((id = elf_getdata(s->is, id)) != NULL ||
1135 (id = elf_rawdata(s->is, id)) != NULL) {
1138 b = malloc(id->d_size);
1140 b = malloc(sz + id->d_size);
1142 err(EXIT_FAILURE, "malloc or realloc failed");
1144 memcpy(&b[sz], id->d_buf, id->d_size);
1147 elferr = elf_errno();
1149 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
1150 elf_errmsg(elferr));
1158 copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy,
1163 if (gelf_getshdr(s->is, &ish) == NULL)
1164 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1166 if (gelf_getshdr(s->os, &osh) == NULL)
1167 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1171 (void) memcpy(&osh, &ish, sizeof(ish));
1173 osh.sh_type = s->type;
1174 osh.sh_addr = s->vma;
1175 osh.sh_offset = s->off;
1176 osh.sh_size = s->sz;
1177 osh.sh_link = ish.sh_link;
1178 osh.sh_info = ish.sh_info;
1179 osh.sh_addralign = s->align;
1180 osh.sh_entsize = ish.sh_entsize;
1184 if (sec_flags & SF_ALLOC)
1185 osh.sh_flags |= SHF_ALLOC;
1186 if ((sec_flags & SF_READONLY) == 0)
1187 osh.sh_flags |= SHF_WRITE;
1188 if (sec_flags & SF_CODE)
1189 osh.sh_flags |= SHF_EXECINSTR;
1190 if ((sec_flags & SF_CONTENTS) &&
1191 s->type == SHT_NOBITS && s->sz > 0) {
1193 * Convert SHT_NOBITS section to section with
1194 * (zero'ed) content on file.
1196 osh.sh_type = s->type = SHT_PROGBITS;
1197 if ((s->buf = calloc(1, s->sz)) == NULL)
1198 err(EXIT_FAILURE, "malloc failed");
1202 osh.sh_flags = ish.sh_flags;
1204 * Newer binutils as(1) emits the section flag
1205 * SHF_INFO_LINK for relocation sections. elfcopy
1206 * emits this flag in the output section if it's
1207 * missing in the input section, to remain compatible
1210 if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA)
1211 osh.sh_flags |= SHF_INFO_LINK;
1216 add_to_shstrtab(ecp, s->name);
1218 add_to_shstrtab(ecp, name);
1220 if (!gelf_update_shdr(s->os, &osh))
1221 errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
1226 copy_data(struct section *s)
1231 if (s->nocopy && s->buf == NULL)
1234 if ((id = elf_getdata(s->is, NULL)) == NULL) {
1236 if ((id = elf_rawdata(s->is, NULL)) == NULL) {
1237 elferr = elf_errno();
1239 errx(EXIT_FAILURE, "failed to read section:"
1245 if ((od = elf_newdata(s->os)) == NULL)
1246 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1250 /* Use s->buf as content if s->nocopy is set. */
1251 od->d_align = id->d_align;
1254 od->d_type = id->d_type;
1256 od->d_version = id->d_version;
1258 od->d_align = id->d_align;
1259 od->d_off = id->d_off;
1260 od->d_buf = id->d_buf;
1261 od->d_type = id->d_type;
1262 od->d_size = id->d_size;
1263 od->d_version = id->d_version;
1267 * Alignment Fixup. libelf does not allow the alignment for
1268 * Elf_Data descriptor to be set to 0. In this case we workaround
1269 * it by setting the alignment to 1.
1271 * According to the ELF ABI, alignment 0 and 1 has the same
1272 * meaning: the section has no alignment constraints.
1274 if (od->d_align == 0)
1279 create_external_section(struct elfcopy *ecp, const char *name, char *newname,
1280 void *buf, uint64_t size, uint64_t off, uint64_t stype, Elf_Type dtype,
1281 uint64_t flags, uint64_t align, uint64_t vma, int loadable)
1288 if ((os = elf_newscn(ecp->eout)) == NULL)
1289 errx(EXIT_FAILURE, "elf_newscn() failed: %s",
1291 if ((s = calloc(1, sizeof(*s))) == NULL)
1292 err(EXIT_FAILURE, "calloc failed");
1294 s->newname = newname; /* needs to be free()'ed */
1299 s->loadable = loadable;
1304 insert_to_sec_list(ecp, s, 1);
1306 if (gelf_getshdr(os, &osh) == NULL)
1307 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1309 osh.sh_flags = flags;
1310 osh.sh_type = s->type;
1311 osh.sh_addr = s->vma;
1312 osh.sh_addralign = s->align;
1313 if (!gelf_update_shdr(os, &osh))
1314 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1316 add_to_shstrtab(ecp, name);
1318 if (buf != NULL && size != 0) {
1319 if ((od = elf_newdata(os)) == NULL)
1320 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1322 od->d_align = align;
1327 od->d_version = EV_CURRENT;
1331 * Clear SYMTAB_INTACT, as we probably need to update/add new
1332 * STT_SECTION symbols into the symbol table.
1334 ecp->flags &= ~SYMTAB_INTACT;
1340 * Insert sections specified by --add-section to the end of section list.
1343 insert_sections(struct elfcopy *ecp)
1350 /* Put these sections in the end of current list. */
1352 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1353 if (s->type != SHT_NOBITS && s->type != SHT_NULL)
1354 off = s->off + s->sz;
1359 STAILQ_FOREACH(sa, &ecp->v_sadd, sadd_list) {
1361 /* TODO: Add section header vma/lma, flag changes here */
1364 * The default section type for user added section is
1365 * SHT_PROGBITS. If the section name match certain patterns,
1366 * elfcopy will try to set a more appropriate section type.
1367 * However, data type is always set to ELF_T_BYTE and no
1368 * translation is performed by libelf.
1370 stype = SHT_PROGBITS;
1371 if (strcmp(sa->name, ".note") == 0 ||
1372 strncmp(sa->name, ".note.", strlen(".note.")) == 0)
1375 (void) create_external_section(ecp, sa->name, NULL, sa->content,
1376 sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0);
1381 add_to_shstrtab(struct elfcopy *ecp, const char *name)
1384 if (elftc_string_table_insert(ecp->shstrtab->strtab, name) == 0)
1385 errx(EXIT_FAILURE, "elftc_string_table_insert failed");
1389 update_shdr(struct elfcopy *ecp, int update_link)
1395 /* Finalize the section name string table (.shstrtab). */
1398 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1402 if (gelf_getshdr(s->os, &osh) == NULL)
1403 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
1406 /* Find section name in string table and set sh_name. */
1407 osh.sh_name = elftc_string_table_lookup(ecp->shstrtab->strtab,
1411 * sh_link needs to be updated, since the index of the
1412 * linked section might have changed.
1414 if (update_link && osh.sh_link != 0)
1415 osh.sh_link = ecp->secndx[osh.sh_link];
1418 * sh_info of relocation section links to the section to which
1419 * its relocation info applies. So it may need update as well.
1421 if ((s->type == SHT_REL || s->type == SHT_RELA) &&
1423 osh.sh_info = ecp->secndx[osh.sh_info];
1426 * sh_info of SHT_GROUP section needs to point to the correct
1427 * string in the symbol table.
1429 if (s->type == SHT_GROUP && (ecp->flags & SYMTAB_EXIST) &&
1430 (ecp->flags & SYMTAB_INTACT) == 0)
1431 osh.sh_info = ecp->symndx[osh.sh_info];
1433 if (!gelf_update_shdr(s->os, &osh))
1434 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1437 elferr = elf_errno();
1439 errx(EXIT_FAILURE, "elf_nextscn failed: %s",
1440 elf_errmsg(elferr));
1444 init_shstrtab(struct elfcopy *ecp)
1449 size_t indx, sizehint;
1451 if (elf_getshdrstrndx(ecp->ein, &indx) == 0) {
1452 shstrtab = elf_getscn(ecp->ein, indx);
1453 if (shstrtab == NULL)
1454 errx(EXIT_FAILURE, "elf_getscn failed: %s",
1456 if (gelf_getshdr(shstrtab, &shdr) != &shdr)
1457 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
1459 sizehint = shdr.sh_size;
1461 /* Clear the error from elf_getshdrstrndx(3). */
1466 if ((ecp->shstrtab = calloc(1, sizeof(*ecp->shstrtab))) == NULL)
1467 err(EXIT_FAILURE, "calloc failed");
1469 s->name = ".shstrtab";
1474 s->type = SHT_STRTAB;
1476 s->strtab = elftc_string_table_create(sizehint);
1478 add_to_shstrtab(ecp, "");
1479 add_to_shstrtab(ecp, ".symtab");
1480 add_to_shstrtab(ecp, ".strtab");
1481 add_to_shstrtab(ecp, ".shstrtab");
1485 set_shstrtab(struct elfcopy *ecp)
1495 if (s->os == NULL) {
1496 /* Input object does not contain .shstrtab section */
1497 if ((s->os = elf_newscn(ecp->eout)) == NULL)
1498 errx(EXIT_FAILURE, "elf_newscn failed: %s",
1500 insert_to_sec_list(ecp, s, 1);
1503 if (gelf_getshdr(s->os, &sh) == NULL)
1504 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1507 sh.sh_addralign = 1;
1508 sh.sh_offset = s->off;
1509 sh.sh_type = SHT_STRTAB;
1515 if ((data = elf_newdata(s->os)) == NULL)
1516 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1520 * If we don't have a symbol table, skip those a few bytes
1521 * which are reserved for this in the beginning of shstrtab.
1523 if (!(ecp->flags & SYMTAB_EXIST)) {
1524 elftc_string_table_remove(s->strtab, ".symtab");
1525 elftc_string_table_remove(s->strtab, ".strtab");
1528 image = elftc_string_table_image(s->strtab, &sz);
1532 if (!gelf_update_shdr(s->os, &sh))
1533 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1537 data->d_buf = (void *)(uintptr_t)image;
1540 data->d_type = ELF_T_BYTE;
1541 data->d_version = EV_CURRENT;
1543 if (!elf_setshstrndx(ecp->eout, elf_ndxscn(s->os)))
1544 errx(EXIT_FAILURE, "elf_setshstrndx() failed: %s",
1549 add_section(struct elfcopy *ecp, const char *arg)
1557 if ((s = strchr(arg, '=')) == NULL)
1559 "illegal format for --add-section option");
1560 if ((sa = malloc(sizeof(*sa))) == NULL)
1561 err(EXIT_FAILURE, "malloc failed");
1564 if ((sa->name = malloc(len + 1)) == NULL)
1565 err(EXIT_FAILURE, "malloc failed");
1566 strncpy(sa->name, arg, len);
1567 sa->name[len] = '\0';
1570 if (stat(fn, &sb) == -1)
1571 err(EXIT_FAILURE, "stat failed");
1572 sa->size = sb.st_size;
1574 if ((sa->content = malloc(sa->size)) == NULL)
1575 err(EXIT_FAILURE, "malloc failed");
1576 if ((fp = fopen(fn, "r")) == NULL)
1577 err(EXIT_FAILURE, "can not open %s", fn);
1578 if (fread(sa->content, 1, sa->size, fp) == 0 ||
1580 err(EXIT_FAILURE, "fread failed");
1585 STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1586 ecp->flags |= SEC_ADD;
1590 free_sec_add(struct elfcopy *ecp)
1592 struct sec_add *sa, *sa_temp;
1594 STAILQ_FOREACH_SAFE(sa, &ecp->v_sadd, sadd_list, sa_temp) {
1595 STAILQ_REMOVE(&ecp->v_sadd, sa, sec_add, sadd_list);
1603 add_gnu_debuglink(struct elfcopy *ecp)
1612 if (ecp->debuglink == NULL)
1615 /* Read debug file content. */
1616 if ((sa = malloc(sizeof(*sa))) == NULL)
1617 err(EXIT_FAILURE, "malloc failed");
1618 if ((sa->name = strdup(".gnu_debuglink")) == NULL)
1619 err(EXIT_FAILURE, "strdup failed");
1620 if (stat(ecp->debuglink, &sb) == -1)
1621 err(EXIT_FAILURE, "stat failed");
1622 if (sb.st_size == 0)
1623 errx(EXIT_FAILURE, "empty debug link target %s",
1625 if ((buf = malloc(sb.st_size)) == NULL)
1626 err(EXIT_FAILURE, "malloc failed");
1627 if ((fp = fopen(ecp->debuglink, "r")) == NULL)
1628 err(EXIT_FAILURE, "can not open %s", ecp->debuglink);
1629 if (fread(buf, 1, sb.st_size, fp) == 0 ||
1631 err(EXIT_FAILURE, "fread failed");
1634 /* Calculate crc checksum. */
1635 crc = calc_crc32(buf, sb.st_size, 0xFFFFFFFF);
1638 /* Calculate section size and the offset to store crc checksum. */
1639 if ((fnbase = basename(ecp->debuglink)) == NULL)
1640 err(EXIT_FAILURE, "basename failed");
1641 crc_off = roundup(strlen(fnbase) + 1, 4);
1642 sa->size = crc_off + 4;
1644 /* Section content. */
1645 if ((sa->content = calloc(1, sa->size)) == NULL)
1646 err(EXIT_FAILURE, "malloc failed");
1647 strncpy(sa->content, fnbase, strlen(fnbase));
1648 if (ecp->oed == ELFDATA2LSB) {
1649 sa->content[crc_off] = crc & 0xFF;
1650 sa->content[crc_off + 1] = (crc >> 8) & 0xFF;
1651 sa->content[crc_off + 2] = (crc >> 16) & 0xFF;
1652 sa->content[crc_off + 3] = crc >> 24;
1654 sa->content[crc_off] = crc >> 24;
1655 sa->content[crc_off + 1] = (crc >> 16) & 0xFF;
1656 sa->content[crc_off + 2] = (crc >> 8) & 0xFF;
1657 sa->content[crc_off + 3] = crc & 0xFF;
1660 STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1661 ecp->flags |= SEC_ADD;
1664 static uint32_t crctable[256] =
1666 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
1667 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
1668 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
1669 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
1670 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
1671 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
1672 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
1673 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
1674 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
1675 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
1676 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
1677 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
1678 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
1679 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
1680 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
1681 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
1682 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
1683 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
1684 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
1685 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
1686 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
1687 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
1688 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
1689 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
1690 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
1691 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
1692 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
1693 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
1694 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
1695 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
1696 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
1697 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
1698 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
1699 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
1700 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
1701 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
1702 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
1703 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
1704 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
1705 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
1706 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
1707 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
1708 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
1709 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
1710 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
1711 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
1712 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
1713 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
1714 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
1715 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
1716 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
1717 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
1718 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
1719 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
1720 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
1721 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
1722 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
1723 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
1724 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
1725 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
1726 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
1727 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
1728 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
1729 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
1733 calc_crc32(const char *p, size_t len, uint32_t crc)
1737 for (i = 0; i < len; i++) {
1738 crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8);
1741 return (crc ^ 0xFFFFFFFF);