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>
38 ELFTC_VCSID("$Id: sections.c 3758 2019-06-28 01:16:50Z emaste $");
40 static void add_gnu_debuglink(struct elfcopy *ecp);
41 static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc);
42 static void check_section_rename(struct elfcopy *ecp, struct section *s);
43 static void filter_reloc(struct elfcopy *ecp, struct section *s);
44 static int get_section_flags(struct elfcopy *ecp, const char *name);
45 static void insert_sections(struct elfcopy *ecp);
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 void modify_section(struct elfcopy *ecp, struct section *s);
53 static void pad_section(struct elfcopy *ecp, struct section *s);
54 static void print_data(const char *d, size_t sz);
55 static void print_section(struct section *s);
56 static void *read_section(struct section *s, size_t *size);
57 static void set_shstrtab(struct elfcopy *ecp);
58 static void update_reloc(struct elfcopy *ecp, struct section *s);
59 static void update_section_group(struct elfcopy *ecp, struct section *s);
62 is_remove_section(struct elfcopy *ecp, const char *name)
65 /* Always keep section name table */
66 if (strcmp(name, ".shstrtab") == 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)
77 if (ecp->strip == STRIP_DWO && is_dwo_section(name))
79 if (ecp->strip == STRIP_NONDWO && !is_dwo_section(name))
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))
88 if (ecp->strip == STRIP_NONDEBUG)
92 if ((ecp->flags & SEC_REMOVE) || (ecp->flags & SEC_COPY)) {
93 struct sec_action *sac;
95 sac = lookup_sec_act(ecp, name, 0);
96 if ((ecp->flags & SEC_REMOVE) && sac != NULL && sac->remove)
98 if ((ecp->flags & SEC_COPY) && (sac == NULL || !sac->copy))
106 * Relocation section needs to be removed if the section it applies to
110 is_remove_reloc_sec(struct elfcopy *ecp, uint32_t sh_info)
118 if (elf_getshstrndx(ecp->ein, &indx) == 0)
119 errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
122 is = elf_getscn(ecp->ein, sh_info);
124 if (gelf_getshdr(is, &ish) == NULL)
125 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
127 if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) ==
129 errx(EXIT_FAILURE, "elf_strptr failed: %s",
131 if (is_remove_section(ecp, name))
136 elferr = elf_errno();
138 errx(EXIT_FAILURE, "elf_nextscn failed: %s",
141 /* Remove reloc section if we can't find the target section. */
146 is_append_section(struct elfcopy *ecp, const char *name)
148 struct sec_action *sac;
150 sac = lookup_sec_act(ecp, name, 0);
151 if (sac != NULL && sac->append != 0 && sac->string != NULL)
158 is_compress_section(struct elfcopy *ecp, const char *name)
160 struct sec_action *sac;
162 sac = lookup_sec_act(ecp, name, 0);
163 if (sac != NULL && sac->compress != 0)
170 check_section_rename(struct elfcopy *ecp, struct section *s)
172 struct sec_action *sac;
179 sac = lookup_sec_act(ecp, s->name, 0);
180 if (sac != NULL && sac->rename)
181 s->name = sac->newname;
183 if (!strcmp(s->name, ".symtab") ||
184 !strcmp(s->name, ".strtab") ||
185 !strcmp(s->name, ".shstrtab"))
189 if (s->loadable && ecp->prefix_alloc != NULL)
190 prefix = ecp->prefix_alloc;
191 else if (ecp->prefix_sec != NULL)
192 prefix = ecp->prefix_sec;
194 if (prefix != NULL) {
195 namelen = strlen(s->name) + strlen(prefix) + 1;
196 if ((s->newname = malloc(namelen)) == NULL)
197 err(EXIT_FAILURE, "malloc failed");
198 snprintf(s->newname, namelen, "%s%s", prefix, s->name);
199 s->name = s->newname;
204 get_section_flags(struct elfcopy *ecp, const char *name)
206 struct sec_action *sac;
208 sac = lookup_sec_act(ecp, name, 0);
209 if (sac != NULL && sac->flags)
216 * Determine whether the section are debugging section.
217 * According to libbfd, debugging sections are recognized
221 is_debug_section(const char *name)
223 const char *dbg_sec[] = {
233 for(p = dbg_sec; *p; p++) {
234 if (strncmp(name, *p, strlen(*p)) == 0)
242 is_dwo_section(const char *name)
246 if ((len = strlen(name)) > 4 && strcmp(name + len - 4, ".dwo") == 0)
252 is_print_section(struct elfcopy *ecp, const char *name)
254 struct sec_action *sac;
256 sac = lookup_sec_act(ecp, name, 0);
257 if (sac != NULL && sac->print != 0)
264 is_modify_section(struct elfcopy *ecp, const char *name)
267 if (is_append_section(ecp, name) ||
268 is_compress_section(ecp, name))
275 lookup_sec_act(struct elfcopy *ecp, const char *name, int add)
277 struct sec_action *sac;
282 STAILQ_FOREACH(sac, &ecp->v_sac, sac_list) {
283 if (strcmp(name, sac->name) == 0)
290 if ((sac = malloc(sizeof(*sac))) == NULL)
291 errx(EXIT_FAILURE, "not enough memory");
292 memset(sac, 0, sizeof(*sac));
294 STAILQ_INSERT_TAIL(&ecp->v_sac, sac, sac_list);
300 free_sec_act(struct elfcopy *ecp)
302 struct sec_action *sac, *sac_temp;
304 STAILQ_FOREACH_SAFE(sac, &ecp->v_sac, sac_list, sac_temp) {
305 STAILQ_REMOVE(&ecp->v_sac, sac, sec_action, sac_list);
311 insert_to_sec_list(struct elfcopy *ecp, struct section *sec, int tail)
315 if (tail || TAILQ_EMPTY(&ecp->v_sec) ||
316 TAILQ_LAST(&ecp->v_sec, sectionlist)->off <= sec->off) {
317 TAILQ_INSERT_TAIL(&ecp->v_sec, sec, sec_list);
319 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
320 if (sec->off < s->off) {
321 TAILQ_INSERT_BEFORE(s, sec, sec_list);
327 if (sec->pseudo == 0)
332 * First step of section creation: create scn and internal section
333 * structure, discard sections to be removed.
336 create_scn(struct elfcopy *ecp)
343 uint64_t oldndx, newndx;
344 int elferr, sec_flags, reorder;
348 * Insert a pseudo section that contains the ELF header
349 * and program header. Used as reference for section offset
350 * or load address adjustment.
352 if ((s = calloc(1, sizeof(*s))) == NULL)
353 err(EXIT_FAILURE, "calloc failed");
355 s->sz = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT) +
356 gelf_fsize(ecp->eout, ELF_T_PHDR, ecp->ophnum, EV_CURRENT);
359 s->loadable = add_to_inseg_list(ecp, s);
360 insert_to_sec_list(ecp, s, 0);
362 /* Create internal .shstrtab section. */
365 if (elf_getshstrndx(ecp->ein, &indx) == 0)
366 errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
369 sections_added = false;
372 while ((is = elf_nextscn(ecp->ein, is)) != NULL) {
373 if (gelf_getshdr(is, &ish) == NULL)
374 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
376 if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == NULL)
377 errx(EXIT_FAILURE, "elf_strptr failed: %s",
380 /* Skip sections to be removed. */
381 if (is_remove_section(ecp, name))
385 * Relocation section need to be remove if the section
386 * it applies will be removed.
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))
394 * Section groups should be removed if symbol table will
395 * be removed. (section group's signature stored in symbol
398 if (ish.sh_type == SHT_GROUP && ecp->strip == STRIP_ALL)
401 /* Get section flags set by user. */
402 sec_flags = get_section_flags(ecp, name);
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");
410 s->off = ish.sh_offset;
412 s->align = ish.sh_addralign;
413 s->type = ish.sh_type;
414 s->flags = ish.sh_flags;
415 s->vma = ish.sh_addr;
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.
423 * Sections in relocatable object is loadable if
424 * section flag SHF_ALLOC is set.
427 (sec_flags & (SF_LOAD | SF_ALLOC)) == 0)
430 s->loadable = add_to_inseg_list(ecp, s);
431 if ((ecp->flags & RELOCATABLE) &&
432 (ish.sh_flags & SHF_ALLOC))
436 /* Assuming .shstrtab is "unloadable". */
438 s->off = ish.sh_offset;
441 oldndx = newndx = SHN_UNDEF;
442 if (strcmp(name, ".symtab") != 0 &&
443 strcmp(name, ".strtab") != 0) {
444 /* Add new sections before .shstrtab if we have one. */
445 if (!strcmp(name, ".shstrtab")) {
447 * Add sections specified by --add-section and
448 * gnu debuglink. we want these sections have
449 * smaller index than .shstrtab section.
451 sections_added = true;
452 if (ecp->debuglink != NULL)
453 add_gnu_debuglink(ecp);
454 if (ecp->flags & SEC_ADD)
455 insert_sections(ecp);
457 if ((s->os = elf_newscn(ecp->eout)) == NULL)
458 errx(EXIT_FAILURE, "elf_newscn failed: %s",
460 if ((newndx = elf_ndxscn(s->os)) == SHN_UNDEF)
461 errx(EXIT_FAILURE, "elf_ndxscn failed: %s",
464 if ((oldndx = elf_ndxscn(is)) == SHN_UNDEF)
465 errx(EXIT_FAILURE, "elf_ndxscn failed: %s",
467 if (oldndx != SHN_UNDEF && newndx != SHN_UNDEF)
468 ecp->secndx[oldndx] = newndx;
471 * If strip action is STRIP_NONDEBUG(only keep debug),
472 * change sections type of loadable sections and section
473 * groups to SHT_NOBITS, and the content of those sections
474 * will be discarded. However, SHT_NOTE sections should
477 if (ecp->strip == STRIP_NONDEBUG) {
478 if (((ish.sh_flags & SHF_ALLOC) ||
479 (ish.sh_flags & SHF_GROUP)) &&
480 ish.sh_type != SHT_NOTE)
481 s->type = SHT_NOBITS;
484 check_section_rename(ecp, s);
486 /* create section header based on input object. */
487 if (strcmp(name, ".symtab") != 0 &&
488 strcmp(name, ".strtab") != 0 &&
489 strcmp(name, ".shstrtab") != 0) {
490 copy_shdr(ecp, s, NULL, 0, sec_flags);
492 * elfcopy puts .symtab, .strtab and .shstrtab
493 * sections in the end of the output object.
494 * If the input objects have more sections
495 * after any of these 3 sections, the section
496 * table will be reordered. section symbols
497 * should be regenerated for relocations.
500 ecp->flags &= ~SYMTAB_INTACT;
504 if (strcmp(name, ".symtab") == 0) {
505 ecp->flags |= SYMTAB_EXIST;
508 if (strcmp(name, ".strtab") == 0)
511 insert_to_sec_list(ecp, s, 0);
513 if (!sections_added) {
514 if (ecp->debuglink != NULL)
515 add_gnu_debuglink(ecp);
516 if (ecp->flags & SEC_ADD)
517 insert_sections(ecp);
519 elferr = elf_errno();
521 errx(EXIT_FAILURE, "elf_nextscn failed: %s",
526 insert_shtab(struct elfcopy *ecp, int tail)
528 struct section *s, *shtab;
533 * Treat section header table as a "pseudo" section, insert it
534 * into section list, so later it will get sorted and resynced
535 * just as normal sections.
537 if ((shtab = calloc(1, sizeof(*shtab))) == NULL)
538 errx(EXIT_FAILURE, "calloc failed");
541 * "shoff" of input object is used as a hint for section
544 if (gelf_getehdr(ecp->ein, &ieh) == NULL)
545 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
547 shtab->off = ieh.e_shoff;
550 /* Calculate number of sections in the output object. */
552 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
556 /* Remember there is always a null section, so we +1 here. */
557 shtab->sz = gelf_fsize(ecp->eout, ELF_T_SHDR, nsecs + 1, EV_CURRENT);
559 errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1));
560 shtab->align = (ecp->oec == ELFCLASS32 ? 4 : 8);
563 insert_to_sec_list(ecp, shtab, tail);
569 copy_content(struct elfcopy *ecp)
573 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
574 /* Skip pseudo section. */
578 /* Skip special sections. */
579 if (strcmp(s->name, ".symtab") == 0 ||
580 strcmp(s->name, ".strtab") == 0 ||
581 strcmp(s->name, ".shstrtab") == 0)
585 * If strip action is STRIP_ALL, relocation info need
586 * to be stripped. Skip filtering otherwisw.
588 if (ecp->strip == STRIP_ALL &&
589 (s->type == SHT_REL || s->type == SHT_RELA))
590 filter_reloc(ecp, s);
593 * The section indices in the SHT_GROUP section needs
594 * to be updated since we might have stripped some
595 * sections and changed section numbering.
597 if (s->type == SHT_GROUP)
598 update_section_group(ecp, s);
600 if (is_modify_section(ecp, s->name))
601 modify_section(ecp, s);
606 * If symbol table is modified, relocation info might
607 * need update, as symbol index may have changed.
609 if ((ecp->flags & SYMTAB_INTACT) == 0 &&
610 (ecp->flags & SYMTAB_EXIST) &&
611 (s->type == SHT_REL || s->type == SHT_RELA))
612 update_reloc(ecp, s);
614 if (is_print_section(ecp, s->name))
621 * Update section group section. The section indices in the SHT_GROUP
622 * section need update after section numbering changed.
625 update_section_group(struct elfcopy *ecp, struct section *s)
634 if (!elf_getshnum(ecp->ein, &ishnum))
635 errx(EXIT_FAILURE, "elf_getshnum failed: %s",
638 if (gelf_getshdr(s->is, &ish) == NULL)
639 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
642 if ((id = elf_getdata(s->is, NULL)) == NULL)
643 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
646 if (ish.sh_size == 0)
649 if (ish.sh_entsize == 0)
654 /* We only support COMDAT section. */
656 #define GRP_COMDAT 0x1
658 if ((*ws & GRP_COMDAT) == 0)
661 if ((s->buf = malloc(ish.sh_size)) == NULL)
662 err(EXIT_FAILURE, "malloc failed");
668 /* Copy the flag word as-is. */
671 /* Update the section indices. */
672 n = ish.sh_size / ish.sh_entsize;
673 for(i = 1, j = 1; (uint64_t)i < n; i++) {
674 if (ws[i] != SHN_UNDEF && ws[i] < ishnum &&
675 ecp->secndx[ws[i]] != 0)
676 wd[j++] = ecp->secndx[ws[i]];
685 * Filter relocation entries, only keep those entries whose
686 * symbol is in the keep list.
689 filter_reloc(struct elfcopy *ecp, struct section *s)
700 uint64_t cap, n, nrels, sym;
703 if (gelf_getshdr(s->is, &ish) == NULL)
704 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
707 /* We don't want to touch relocation info for dynamic symbols. */
708 if ((ecp->flags & SYMTAB_EXIST) == 0) {
710 * No symbol table in output. If sh_link points to a section
711 * that exists in the output object, this relocation section
712 * is for dynamic symbols. Don't touch it.
714 if (ish.sh_link != 0 && ecp->secndx[ish.sh_link] != 0)
717 /* Symbol table exist, check if index equals. */
718 if (ish.sh_link != elf_ndxscn(ecp->symtab->is))
722 #define COPYREL(REL, SZ) do { \
724 if ((REL##SZ = malloc(cap * \
725 sizeof(*REL##SZ))) == NULL) \
726 err(EXIT_FAILURE, "malloc failed"); \
728 if (nrels >= cap) { \
730 if ((REL##SZ = realloc(REL##SZ, cap * \
731 sizeof(*REL##SZ))) == NULL) \
732 err(EXIT_FAILURE, "realloc failed"); \
734 REL##SZ[nrels].r_offset = REL.r_offset; \
735 REL##SZ[nrels].r_info = REL.r_info; \
736 if (s->type == SHT_RELA) \
737 rela##SZ[nrels].r_addend = rela.r_addend; \
742 cap = 4; /* keep list is usually small. */
747 if ((id = elf_getdata(s->is, NULL)) == NULL)
748 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
750 n = ish.sh_size / ish.sh_entsize;
751 for(i = 0; (uint64_t)i < n; i++) {
752 if (s->type == SHT_REL) {
753 if (gelf_getrel(id, i, &rel) != &rel)
754 errx(EXIT_FAILURE, "gelf_getrel failed: %s",
756 sym = GELF_R_SYM(rel.r_info);
758 if (gelf_getrela(id, i, &rela) != &rela)
759 errx(EXIT_FAILURE, "gelf_getrel failed: %s",
761 sym = GELF_R_SYM(rela.r_info);
764 * If a relocation references a symbol and we are omitting
765 * either that symbol or the entire symbol table we cannot
766 * produce valid output, and so just omit the relocation.
767 * Broken output like this is generally not useful, but some
768 * uses of elfcopy/strip rely on it - for example, GCC's build
769 * process uses it to check for build reproducibility by
770 * stripping objects and comparing them.
772 * Relocations that do not reference a symbol are retained.
775 if (ish.sh_link == 0 || ecp->secndx[ish.sh_link] == 0)
777 name = elf_strptr(ecp->ein, elf_ndxscn(ecp->strtab->is),
780 errx(EXIT_FAILURE, "elf_strptr failed: %s",
782 if (lookup_symop_list(ecp, name, SYMOP_KEEP) == NULL)
785 if (ecp->oec == ELFCLASS32) {
786 if (s->type == SHT_REL)
791 if (s->type == SHT_REL)
797 elferr = elf_errno();
799 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
802 if (ecp->oec == ELFCLASS32) {
803 if (s->type == SHT_REL)
808 if (s->type == SHT_REL)
813 s->sz = gelf_fsize(ecp->eout, (s->type == SHT_REL ? ELF_T_REL :
814 ELF_T_RELA), nrels, EV_CURRENT);
819 update_reloc(struct elfcopy *ecp, struct section *s)
828 #define UPDATEREL(REL) do { \
829 if (gelf_get##REL(od, i, &REL) != &REL) \
830 errx(EXIT_FAILURE, "gelf_get##REL failed: %s", \
832 REL.r_info = GELF_R_INFO(ecp->symndx[GELF_R_SYM(REL.r_info)], \
833 GELF_R_TYPE(REL.r_info)); \
834 if (!gelf_update_##REL(od, i, &REL)) \
835 errx(EXIT_FAILURE, "gelf_update_##REL failed: %s", \
841 if (gelf_getshdr(s->os, &osh) == NULL)
842 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
844 /* Only process .symtab reloc info. */
845 if (osh.sh_link != elf_ndxscn(ecp->symtab->is))
847 if ((od = elf_getdata(s->os, NULL)) == NULL)
848 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
850 n = osh.sh_size / osh.sh_entsize;
851 for(i = 0; (uint64_t)i < n; i++) {
852 if (s->type == SHT_REL)
860 pad_section(struct elfcopy *ecp, struct section *s)
865 if (s == NULL || s->pad_sz == 0)
868 if ((s->pad = malloc(s->pad_sz)) == NULL)
869 err(EXIT_FAILURE, "malloc failed");
870 memset(s->pad, ecp->fill, s->pad_sz);
872 /* Create a new Elf_Data to contain the padding bytes. */
873 if ((od = elf_newdata(s->os)) == NULL)
874 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
879 od->d_type = ELF_T_BYTE;
880 od->d_size = s->pad_sz;
881 od->d_version = EV_CURRENT;
883 /* Update section header. */
884 if (gelf_getshdr(s->os, &osh) == NULL)
885 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
887 osh.sh_size = s->sz + s->pad_sz;
888 if (!gelf_update_shdr(s->os, &osh))
889 errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
894 section_type_alignment(int sht, int class)
903 case SHT_PREINIT_ARRAY:
907 return (class == ELFCLASS64 ? 8 : 4);
910 case SHT_GNU_LIBLIST:
914 case SHT_SUNW_verdef: /* == SHT_GNU_verdef */
915 case SHT_SUNW_verneed: /* == SHT_GNU_verneed */
916 case SHT_SYMTAB_SHNDX:
918 case SHT_SUNW_syminfo:
919 case SHT_SUNW_versym: /* == SHT_GNU_versym */
931 resync_sections(struct elfcopy *ecp)
933 struct section *s, *ps;
942 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
949 * Ignore TLS sections with load address 0 and without
950 * content. We don't need to adjust their file offset or
951 * VMA, only the size matters.
953 if (s->seg_tls != NULL && s->type == SHT_NOBITS &&
957 /* Align section offset. */
960 min_alignment = section_type_alignment(s->type, ecp->oec);
961 if (s->align < INT_MAX && (int)s->align < min_alignment) {
962 warnx("section %s alignment %d increased to %d",
963 s->name, (int)s->align, min_alignment);
964 s->align = min_alignment;
967 if (!s->loadable || (ecp->flags & RELOCATABLE))
968 s->off = roundup(off, s->align);
970 if (s->loadable && (ecp->flags & RELOCATABLE) == 0)
971 warnx("moving loadable section %s, "
972 "is this intentional?", s->name);
973 s->off = roundup(off, s->align);
976 /* Calculate next section offset. */
978 if (s->pseudo || (s->type != SHT_NOBITS && s->type != SHT_NULL))
986 /* Count padding bytes added through --pad-to. */
990 /* Update section header accordingly. */
991 if (gelf_getshdr(s->os, &osh) == NULL)
992 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
994 osh.sh_addr = s->vma;
995 osh.sh_addralign = s->align;
996 osh.sh_offset = s->off;
998 if (!gelf_update_shdr(s->os, &osh))
999 errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
1002 /* Add padding for previous section, if need. */
1004 if (ps->pad_sz > 0) {
1005 /* Apply padding added by --pad-to. */
1006 pad_section(ecp, ps);
1007 } else if ((ecp->flags & GAP_FILL) &&
1008 (ps->off + ps->sz < s->off)) {
1010 * Fill the gap between sections by padding
1011 * the section with lower address.
1013 ps->pad_sz = s->off - (ps->off + ps->sz);
1014 pad_section(ecp, ps);
1021 /* Pad the last section, if need. */
1022 if (ps != NULL && ps->pad_sz > 0)
1023 pad_section(ecp, ps);
1027 modify_section(struct elfcopy *ecp, struct section *s)
1029 struct sec_action *sac;
1030 size_t srcsz, dstsz, p, len;
1031 char *b, *c, *d, *src, *end;
1034 src = read_section(s, &srcsz);
1035 if (src == NULL || srcsz == 0) {
1036 /* For empty section, we proceed if we need to append. */
1037 if (!is_append_section(ecp, s->name))
1041 /* Allocate buffer needed for new section data. */
1043 if (is_append_section(ecp, s->name)) {
1044 sac = lookup_sec_act(ecp, s->name, 0);
1045 dstsz += strlen(sac->string) + 1;
1047 if ((b = malloc(dstsz)) == NULL)
1048 err(EXIT_FAILURE, "malloc failed");
1051 /* Compress section. */
1053 if (is_compress_section(ecp, s->name)) {
1055 for(c = src; c < end;) {
1057 while(c + len < end && c[len] != '\0')
1059 if (c + len == end) {
1060 /* XXX should we warn here? */
1061 strncpy(&b[p], c, len);
1066 for (d = b; d < b + p; ) {
1067 if (strcmp(d, c) == 0) {
1074 strncpy(&b[p], c, len);
1081 memcpy(b, src, srcsz);
1085 /* Append section. */
1086 if (is_append_section(ecp, s->name)) {
1087 sac = lookup_sec_act(ecp, s->name, 0);
1088 len = strlen(sac->string);
1089 strncpy(&b[p], sac->string, len);
1099 print_data(const char *d, size_t sz)
1103 for (c = d; c < d + sz; c++) {
1112 print_section(struct section *s)
1117 if (s->buf != NULL && s->sz > 0) {
1118 print_data(s->buf, s->sz);
1121 while ((id = elf_getdata(s->is, id)) != NULL ||
1122 (id = elf_rawdata(s->is, id)) != NULL) {
1124 print_data(id->d_buf, id->d_size);
1126 elferr = elf_errno();
1128 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
1129 elf_errmsg(elferr));
1135 read_section(struct section *s, size_t *size)
1145 while ((id = elf_getdata(s->is, id)) != NULL ||
1146 (id = elf_rawdata(s->is, id)) != NULL) {
1149 b = malloc(id->d_size);
1151 b = realloc(b, sz + id->d_size);
1153 err(EXIT_FAILURE, "malloc or realloc failed");
1155 memcpy(&b[sz], id->d_buf, id->d_size);
1158 elferr = elf_errno();
1160 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
1161 elf_errmsg(elferr));
1169 copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy,
1174 if (gelf_getshdr(s->is, &ish) == NULL)
1175 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1177 if (gelf_getshdr(s->os, &osh) == NULL)
1178 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1182 (void) memcpy(&osh, &ish, sizeof(ish));
1184 osh.sh_type = s->type;
1185 osh.sh_addr = s->vma;
1186 osh.sh_offset = s->off;
1187 osh.sh_size = s->sz;
1188 osh.sh_link = ish.sh_link;
1189 osh.sh_info = ish.sh_info;
1190 osh.sh_addralign = s->align;
1191 osh.sh_entsize = ish.sh_entsize;
1195 if (sec_flags & SF_ALLOC)
1196 osh.sh_flags |= SHF_ALLOC;
1197 if ((sec_flags & SF_READONLY) == 0)
1198 osh.sh_flags |= SHF_WRITE;
1199 if (sec_flags & SF_CODE)
1200 osh.sh_flags |= SHF_EXECINSTR;
1201 if ((sec_flags & SF_CONTENTS) &&
1202 s->type == SHT_NOBITS && s->sz > 0) {
1204 * Convert SHT_NOBITS section to section with
1205 * (zero'ed) content on file.
1207 osh.sh_type = s->type = SHT_PROGBITS;
1208 if ((s->buf = calloc(1, s->sz)) == NULL)
1209 err(EXIT_FAILURE, "malloc failed");
1213 osh.sh_flags = ish.sh_flags;
1215 * Newer binutils as(1) emits the section flag
1216 * SHF_INFO_LINK for relocation sections. elfcopy
1217 * emits this flag in the output section if it's
1218 * missing in the input section, to remain compatible
1221 if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA)
1222 osh.sh_flags |= SHF_INFO_LINK;
1227 add_to_shstrtab(ecp, s->name);
1229 add_to_shstrtab(ecp, name);
1231 if (!gelf_update_shdr(s->os, &osh))
1232 errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
1237 copy_data(struct section *s)
1242 if (s->nocopy && s->buf == NULL)
1245 if ((id = elf_getdata(s->is, NULL)) == NULL) {
1247 if ((id = elf_rawdata(s->is, NULL)) == NULL) {
1248 elferr = elf_errno();
1250 errx(EXIT_FAILURE, "failed to read section:"
1256 if ((od = elf_newdata(s->os)) == NULL)
1257 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1261 /* Use s->buf as content if s->nocopy is set. */
1262 od->d_align = id->d_align;
1265 od->d_type = id->d_type;
1267 od->d_version = id->d_version;
1269 od->d_align = id->d_align;
1270 od->d_off = id->d_off;
1271 od->d_buf = id->d_buf;
1272 od->d_type = id->d_type;
1273 od->d_size = id->d_size;
1274 od->d_version = id->d_version;
1278 * Alignment Fixup. libelf does not allow the alignment for
1279 * Elf_Data descriptor to be set to 0. In this case we workaround
1280 * it by setting the alignment to 1.
1282 * According to the ELF ABI, alignment 0 and 1 has the same
1283 * meaning: the section has no alignment constraints.
1285 if (od->d_align == 0)
1290 create_external_section(struct elfcopy *ecp, const char *name, char *newname,
1291 void *buf, uint64_t size, uint64_t off, uint64_t stype, Elf_Type dtype,
1292 uint64_t flags, uint64_t align, uint64_t vma, int loadable)
1299 if ((os = elf_newscn(ecp->eout)) == NULL)
1300 errx(EXIT_FAILURE, "elf_newscn() failed: %s",
1302 if ((s = calloc(1, sizeof(*s))) == NULL)
1303 err(EXIT_FAILURE, "calloc failed");
1305 s->newname = newname; /* needs to be free()'ed */
1310 s->loadable = loadable;
1315 insert_to_sec_list(ecp, s, 1);
1317 if (gelf_getshdr(os, &osh) == NULL)
1318 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1320 osh.sh_flags = flags;
1321 osh.sh_type = s->type;
1322 osh.sh_addr = s->vma;
1323 osh.sh_addralign = s->align;
1324 if (!gelf_update_shdr(os, &osh))
1325 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1327 add_to_shstrtab(ecp, name);
1329 if (buf != NULL && size != 0) {
1330 if ((od = elf_newdata(os)) == NULL)
1331 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1333 od->d_align = align;
1338 od->d_version = EV_CURRENT;
1342 * Clear SYMTAB_INTACT, as we probably need to update/add new
1343 * STT_SECTION symbols into the symbol table.
1345 ecp->flags &= ~SYMTAB_INTACT;
1351 * Insert sections specified by --add-section to the end of section list.
1354 insert_sections(struct elfcopy *ecp)
1361 /* Put these sections in the end of current list. */
1363 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1364 if (s->type != SHT_NOBITS && s->type != SHT_NULL)
1365 off = s->off + s->sz;
1370 STAILQ_FOREACH(sa, &ecp->v_sadd, sadd_list) {
1372 /* TODO: Add section header vma/lma, flag changes here */
1375 * The default section type for user added section is
1376 * SHT_PROGBITS. If the section name match certain patterns,
1377 * elfcopy will try to set a more appropriate section type.
1378 * However, data type is always set to ELF_T_BYTE and no
1379 * translation is performed by libelf.
1381 stype = SHT_PROGBITS;
1382 if (strcmp(sa->name, ".note") == 0 ||
1383 strncmp(sa->name, ".note.", strlen(".note.")) == 0)
1386 (void) create_external_section(ecp, sa->name, NULL, sa->content,
1387 sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0);
1392 add_to_shstrtab(struct elfcopy *ecp, const char *name)
1395 if (elftc_string_table_insert(ecp->shstrtab->strtab, name) == 0)
1396 errx(EXIT_FAILURE, "elftc_string_table_insert failed");
1400 update_shdr(struct elfcopy *ecp, int update_link)
1406 /* Finalize the section name string table (.shstrtab). */
1409 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1413 if (gelf_getshdr(s->os, &osh) == NULL)
1414 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
1417 /* Find section name in string table and set sh_name. */
1418 osh.sh_name = elftc_string_table_lookup(ecp->shstrtab->strtab,
1422 * sh_link needs to be updated, since the index of the
1423 * linked section might have changed.
1425 if (update_link && osh.sh_link != 0)
1426 osh.sh_link = ecp->secndx[osh.sh_link];
1429 * sh_info of relocation section links to the section to which
1430 * its relocation info applies. So it may need update as well.
1432 if ((s->type == SHT_REL || s->type == SHT_RELA) &&
1434 osh.sh_info = ecp->secndx[osh.sh_info];
1437 * sh_info of SHT_GROUP section needs to point to the correct
1438 * string in the symbol table.
1440 if (s->type == SHT_GROUP && (ecp->flags & SYMTAB_EXIST) &&
1441 (ecp->flags & SYMTAB_INTACT) == 0)
1442 osh.sh_info = ecp->symndx[osh.sh_info];
1444 if (!gelf_update_shdr(s->os, &osh))
1445 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1448 elferr = elf_errno();
1450 errx(EXIT_FAILURE, "elf_nextscn failed: %s",
1451 elf_errmsg(elferr));
1455 init_shstrtab(struct elfcopy *ecp)
1460 size_t indx, sizehint;
1462 if (elf_getshdrstrndx(ecp->ein, &indx) == 0) {
1463 shstrtab = elf_getscn(ecp->ein, indx);
1464 if (shstrtab == NULL)
1465 errx(EXIT_FAILURE, "elf_getscn failed: %s",
1467 if (gelf_getshdr(shstrtab, &shdr) != &shdr)
1468 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
1470 sizehint = shdr.sh_size;
1472 /* Clear the error from elf_getshdrstrndx(3). */
1477 if ((ecp->shstrtab = calloc(1, sizeof(*ecp->shstrtab))) == NULL)
1478 err(EXIT_FAILURE, "calloc failed");
1480 s->name = ".shstrtab";
1485 s->type = SHT_STRTAB;
1487 s->strtab = elftc_string_table_create(sizehint);
1489 add_to_shstrtab(ecp, "");
1490 add_to_shstrtab(ecp, ".symtab");
1491 add_to_shstrtab(ecp, ".strtab");
1492 add_to_shstrtab(ecp, ".shstrtab");
1496 set_shstrtab(struct elfcopy *ecp)
1506 if (s->os == NULL) {
1507 /* Input object does not contain .shstrtab section */
1508 if ((s->os = elf_newscn(ecp->eout)) == NULL)
1509 errx(EXIT_FAILURE, "elf_newscn failed: %s",
1511 insert_to_sec_list(ecp, s, 1);
1514 if (gelf_getshdr(s->os, &sh) == NULL)
1515 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1518 sh.sh_addralign = 1;
1519 sh.sh_offset = s->off;
1520 sh.sh_type = SHT_STRTAB;
1526 if ((data = elf_newdata(s->os)) == NULL)
1527 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1531 * If we don't have a symbol table, skip those a few bytes
1532 * which are reserved for this in the beginning of shstrtab.
1534 if (!(ecp->flags & SYMTAB_EXIST)) {
1535 elftc_string_table_remove(s->strtab, ".symtab");
1536 elftc_string_table_remove(s->strtab, ".strtab");
1539 image = elftc_string_table_image(s->strtab, &sz);
1543 if (!gelf_update_shdr(s->os, &sh))
1544 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1548 data->d_buf = (void *)(uintptr_t)image;
1551 data->d_type = ELF_T_BYTE;
1552 data->d_version = EV_CURRENT;
1554 if (!elf_setshstrndx(ecp->eout, elf_ndxscn(s->os)))
1555 errx(EXIT_FAILURE, "elf_setshstrndx() failed: %s",
1560 add_section(struct elfcopy *ecp, const char *arg)
1568 if ((s = strchr(arg, '=')) == NULL)
1570 "illegal format for --add-section option");
1571 if ((sa = malloc(sizeof(*sa))) == NULL)
1572 err(EXIT_FAILURE, "malloc failed");
1575 if ((sa->name = malloc(len + 1)) == NULL)
1576 err(EXIT_FAILURE, "malloc failed");
1577 strncpy(sa->name, arg, len);
1578 sa->name[len] = '\0';
1581 if (stat(fn, &sb) == -1)
1582 err(EXIT_FAILURE, "stat failed");
1583 sa->size = sb.st_size;
1585 if ((sa->content = malloc(sa->size)) == NULL)
1586 err(EXIT_FAILURE, "malloc failed");
1587 if ((fp = fopen(fn, "r")) == NULL)
1588 err(EXIT_FAILURE, "can not open %s", fn);
1589 if (fread(sa->content, 1, sa->size, fp) == 0 ||
1591 err(EXIT_FAILURE, "fread failed");
1596 STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1597 ecp->flags |= SEC_ADD;
1601 free_sec_add(struct elfcopy *ecp)
1603 struct sec_add *sa, *sa_temp;
1605 STAILQ_FOREACH_SAFE(sa, &ecp->v_sadd, sadd_list, sa_temp) {
1606 STAILQ_REMOVE(&ecp->v_sadd, sa, sec_add, sadd_list);
1614 add_gnu_debuglink(struct elfcopy *ecp)
1623 if (ecp->debuglink == NULL)
1626 /* Read debug file content. */
1627 if ((sa = malloc(sizeof(*sa))) == NULL)
1628 err(EXIT_FAILURE, "malloc failed");
1629 if ((sa->name = strdup(".gnu_debuglink")) == NULL)
1630 err(EXIT_FAILURE, "strdup failed");
1631 if (stat(ecp->debuglink, &sb) == -1)
1632 err(EXIT_FAILURE, "stat failed");
1633 if (sb.st_size == 0)
1634 errx(EXIT_FAILURE, "empty debug link target %s",
1636 if ((buf = malloc(sb.st_size)) == NULL)
1637 err(EXIT_FAILURE, "malloc failed");
1638 if ((fp = fopen(ecp->debuglink, "r")) == NULL)
1639 err(EXIT_FAILURE, "can not open %s", ecp->debuglink);
1640 if (fread(buf, 1, sb.st_size, fp) == 0 ||
1642 err(EXIT_FAILURE, "fread failed");
1645 /* Calculate crc checksum. */
1646 crc = calc_crc32(buf, sb.st_size, 0xFFFFFFFF);
1649 /* Calculate section size and the offset to store crc checksum. */
1650 if ((fnbase = basename(ecp->debuglink)) == NULL)
1651 err(EXIT_FAILURE, "basename failed");
1652 crc_off = roundup(strlen(fnbase) + 1, 4);
1653 sa->size = crc_off + 4;
1655 /* Section content. */
1656 if ((sa->content = calloc(1, sa->size)) == NULL)
1657 err(EXIT_FAILURE, "malloc failed");
1658 strncpy(sa->content, fnbase, strlen(fnbase));
1659 if (ecp->oed == ELFDATA2LSB) {
1660 sa->content[crc_off] = crc & 0xFF;
1661 sa->content[crc_off + 1] = (crc >> 8) & 0xFF;
1662 sa->content[crc_off + 2] = (crc >> 16) & 0xFF;
1663 sa->content[crc_off + 3] = crc >> 24;
1665 sa->content[crc_off] = crc >> 24;
1666 sa->content[crc_off + 1] = (crc >> 16) & 0xFF;
1667 sa->content[crc_off + 2] = (crc >> 8) & 0xFF;
1668 sa->content[crc_off + 3] = crc & 0xFF;
1671 STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1672 ecp->flags |= SEC_ADD;
1675 static uint32_t crctable[256] =
1677 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
1678 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
1679 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
1680 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
1681 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
1682 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
1683 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
1684 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
1685 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
1686 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
1687 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
1688 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
1689 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
1690 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
1691 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
1692 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
1693 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
1694 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
1695 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
1696 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
1697 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
1698 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
1699 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
1700 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
1701 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
1702 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
1703 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
1704 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
1705 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
1706 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
1707 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
1708 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
1709 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
1710 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
1711 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
1712 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
1713 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
1714 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
1715 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
1716 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
1717 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
1718 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
1719 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
1720 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
1721 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
1722 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
1723 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
1724 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
1725 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
1726 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
1727 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
1728 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
1729 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
1730 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
1731 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
1732 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
1733 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
1734 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
1735 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
1736 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
1737 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
1738 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
1739 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
1740 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
1744 calc_crc32(const char *p, size_t len, uint32_t crc)
1748 for (i = 0; i < len; i++) {
1749 crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8);
1752 return (crc ^ 0xFFFFFFFF);