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 3646 2018-10-27 02:25:39Z 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 resync_sections(struct elfcopy *ecp)
885 struct section *s, *ps;
893 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
900 * Ignore TLS sections with load address 0 and without
901 * content. We don't need to adjust their file offset or
902 * VMA, only the size matters.
904 if (s->seg_tls != NULL && s->type == SHT_NOBITS &&
908 /* Align section offset. */
912 if (!s->loadable || (ecp->flags & RELOCATABLE))
913 s->off = roundup(off, s->align);
915 if (s->loadable && (ecp->flags & RELOCATABLE) == 0)
916 warnx("moving loadable section %s, "
917 "is this intentional?", s->name);
918 s->off = roundup(off, s->align);
921 /* Calculate next section offset. */
923 if (s->pseudo || (s->type != SHT_NOBITS && s->type != SHT_NULL))
931 /* Count padding bytes added through --pad-to. */
935 /* Update section header accordingly. */
936 if (gelf_getshdr(s->os, &osh) == NULL)
937 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
939 osh.sh_addr = s->vma;
940 osh.sh_offset = s->off;
942 if (!gelf_update_shdr(s->os, &osh))
943 errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
946 /* Add padding for previous section, if need. */
948 if (ps->pad_sz > 0) {
949 /* Apply padding added by --pad-to. */
950 pad_section(ecp, ps);
951 } else if ((ecp->flags & GAP_FILL) &&
952 (ps->off + ps->sz < s->off)) {
954 * Fill the gap between sections by padding
955 * the section with lower address.
957 ps->pad_sz = s->off - (ps->off + ps->sz);
958 pad_section(ecp, ps);
965 /* Pad the last section, if need. */
966 if (ps != NULL && ps->pad_sz > 0)
967 pad_section(ecp, ps);
971 modify_section(struct elfcopy *ecp, struct section *s)
973 struct sec_action *sac;
974 size_t srcsz, dstsz, p, len;
975 char *b, *c, *d, *src, *end;
978 src = read_section(s, &srcsz);
979 if (src == NULL || srcsz == 0) {
980 /* For empty section, we proceed if we need to append. */
981 if (!is_append_section(ecp, s->name))
985 /* Allocate buffer needed for new section data. */
987 if (is_append_section(ecp, s->name)) {
988 sac = lookup_sec_act(ecp, s->name, 0);
989 dstsz += strlen(sac->string) + 1;
991 if ((b = malloc(dstsz)) == NULL)
992 err(EXIT_FAILURE, "malloc failed");
995 /* Compress section. */
997 if (is_compress_section(ecp, s->name)) {
999 for(c = src; c < end;) {
1001 while(c + len < end && c[len] != '\0')
1003 if (c + len == end) {
1004 /* XXX should we warn here? */
1005 strncpy(&b[p], c, len);
1010 for (d = b; d < b + p; ) {
1011 if (strcmp(d, c) == 0) {
1018 strncpy(&b[p], c, len);
1025 memcpy(b, src, srcsz);
1029 /* Append section. */
1030 if (is_append_section(ecp, s->name)) {
1031 sac = lookup_sec_act(ecp, s->name, 0);
1032 len = strlen(sac->string);
1033 strncpy(&b[p], sac->string, len);
1043 print_data(const char *d, size_t sz)
1047 for (c = d; c < d + sz; c++) {
1056 print_section(struct section *s)
1061 if (s->buf != NULL && s->sz > 0) {
1062 print_data(s->buf, s->sz);
1065 while ((id = elf_getdata(s->is, id)) != NULL ||
1066 (id = elf_rawdata(s->is, id)) != NULL) {
1068 print_data(id->d_buf, id->d_size);
1070 elferr = elf_errno();
1072 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
1073 elf_errmsg(elferr));
1079 read_section(struct section *s, size_t *size)
1089 while ((id = elf_getdata(s->is, id)) != NULL ||
1090 (id = elf_rawdata(s->is, id)) != NULL) {
1093 b = malloc(id->d_size);
1095 b = malloc(sz + id->d_size);
1097 err(EXIT_FAILURE, "malloc or realloc failed");
1099 memcpy(&b[sz], id->d_buf, id->d_size);
1102 elferr = elf_errno();
1104 errx(EXIT_FAILURE, "elf_getdata() failed: %s",
1105 elf_errmsg(elferr));
1113 copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy,
1118 if (gelf_getshdr(s->is, &ish) == NULL)
1119 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1121 if (gelf_getshdr(s->os, &osh) == NULL)
1122 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1126 (void) memcpy(&osh, &ish, sizeof(ish));
1128 osh.sh_type = s->type;
1129 osh.sh_addr = s->vma;
1130 osh.sh_offset = s->off;
1131 osh.sh_size = s->sz;
1132 osh.sh_link = ish.sh_link;
1133 osh.sh_info = ish.sh_info;
1134 osh.sh_addralign = s->align;
1135 osh.sh_entsize = ish.sh_entsize;
1139 if (sec_flags & SF_ALLOC)
1140 osh.sh_flags |= SHF_ALLOC;
1141 if ((sec_flags & SF_READONLY) == 0)
1142 osh.sh_flags |= SHF_WRITE;
1143 if (sec_flags & SF_CODE)
1144 osh.sh_flags |= SHF_EXECINSTR;
1145 if ((sec_flags & SF_CONTENTS) &&
1146 s->type == SHT_NOBITS && s->sz > 0) {
1148 * Convert SHT_NOBITS section to section with
1149 * (zero'ed) content on file.
1151 osh.sh_type = s->type = SHT_PROGBITS;
1152 if ((s->buf = calloc(1, s->sz)) == NULL)
1153 err(EXIT_FAILURE, "malloc failed");
1157 osh.sh_flags = ish.sh_flags;
1159 * Newer binutils as(1) emits the section flag
1160 * SHF_INFO_LINK for relocation sections. elfcopy
1161 * emits this flag in the output section if it's
1162 * missing in the input section, to remain compatible
1165 if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA)
1166 osh.sh_flags |= SHF_INFO_LINK;
1171 add_to_shstrtab(ecp, s->name);
1173 add_to_shstrtab(ecp, name);
1175 if (!gelf_update_shdr(s->os, &osh))
1176 errx(EXIT_FAILURE, "elf_update_shdr failed: %s",
1181 copy_data(struct section *s)
1186 if (s->nocopy && s->buf == NULL)
1189 if ((id = elf_getdata(s->is, NULL)) == NULL) {
1191 if ((id = elf_rawdata(s->is, NULL)) == NULL) {
1192 elferr = elf_errno();
1194 errx(EXIT_FAILURE, "failed to read section:"
1200 if ((od = elf_newdata(s->os)) == NULL)
1201 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1205 /* Use s->buf as content if s->nocopy is set. */
1206 od->d_align = id->d_align;
1209 od->d_type = id->d_type;
1211 od->d_version = id->d_version;
1213 od->d_align = id->d_align;
1214 od->d_off = id->d_off;
1215 od->d_buf = id->d_buf;
1216 od->d_type = id->d_type;
1217 od->d_size = id->d_size;
1218 od->d_version = id->d_version;
1222 * Alignment Fixup. libelf does not allow the alignment for
1223 * Elf_Data descriptor to be set to 0. In this case we workaround
1224 * it by setting the alignment to 1.
1226 * According to the ELF ABI, alignment 0 and 1 has the same
1227 * meaning: the section has no alignment constraints.
1229 if (od->d_align == 0)
1234 create_external_section(struct elfcopy *ecp, const char *name, char *newname,
1235 void *buf, uint64_t size, uint64_t off, uint64_t stype, Elf_Type dtype,
1236 uint64_t flags, uint64_t align, uint64_t vma, int loadable)
1243 if ((os = elf_newscn(ecp->eout)) == NULL)
1244 errx(EXIT_FAILURE, "elf_newscn() failed: %s",
1246 if ((s = calloc(1, sizeof(*s))) == NULL)
1247 err(EXIT_FAILURE, "calloc failed");
1249 s->newname = newname; /* needs to be free()'ed */
1254 s->loadable = loadable;
1259 insert_to_sec_list(ecp, s, 1);
1261 if (gelf_getshdr(os, &osh) == NULL)
1262 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1264 osh.sh_flags = flags;
1265 osh.sh_type = s->type;
1266 osh.sh_addr = s->vma;
1267 osh.sh_addralign = s->align;
1268 if (!gelf_update_shdr(os, &osh))
1269 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1271 add_to_shstrtab(ecp, name);
1273 if (buf != NULL && size != 0) {
1274 if ((od = elf_newdata(os)) == NULL)
1275 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1277 od->d_align = align;
1282 od->d_version = EV_CURRENT;
1286 * Clear SYMTAB_INTACT, as we probably need to update/add new
1287 * STT_SECTION symbols into the symbol table.
1289 ecp->flags &= ~SYMTAB_INTACT;
1295 * Insert sections specified by --add-section to the end of section list.
1298 insert_sections(struct elfcopy *ecp)
1305 /* Put these sections in the end of current list. */
1307 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1308 if (s->type != SHT_NOBITS && s->type != SHT_NULL)
1309 off = s->off + s->sz;
1314 STAILQ_FOREACH(sa, &ecp->v_sadd, sadd_list) {
1316 /* TODO: Add section header vma/lma, flag changes here */
1319 * The default section type for user added section is
1320 * SHT_PROGBITS. If the section name match certain patterns,
1321 * elfcopy will try to set a more appropriate section type.
1322 * However, data type is always set to ELF_T_BYTE and no
1323 * translation is performed by libelf.
1325 stype = SHT_PROGBITS;
1326 if (strcmp(sa->name, ".note") == 0 ||
1327 strncmp(sa->name, ".note.", strlen(".note.")) == 0)
1330 (void) create_external_section(ecp, sa->name, NULL, sa->content,
1331 sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0);
1336 add_to_shstrtab(struct elfcopy *ecp, const char *name)
1339 if (elftc_string_table_insert(ecp->shstrtab->strtab, name) == 0)
1340 errx(EXIT_FAILURE, "elftc_string_table_insert failed");
1344 update_shdr(struct elfcopy *ecp, int update_link)
1350 /* Finalize the section name string table (.shstrtab). */
1353 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) {
1357 if (gelf_getshdr(s->os, &osh) == NULL)
1358 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
1361 /* Find section name in string table and set sh_name. */
1362 osh.sh_name = elftc_string_table_lookup(ecp->shstrtab->strtab,
1366 * sh_link needs to be updated, since the index of the
1367 * linked section might have changed.
1369 if (update_link && osh.sh_link != 0)
1370 osh.sh_link = ecp->secndx[osh.sh_link];
1373 * sh_info of relocation section links to the section to which
1374 * its relocation info applies. So it may need update as well.
1376 if ((s->type == SHT_REL || s->type == SHT_RELA) &&
1378 osh.sh_info = ecp->secndx[osh.sh_info];
1381 * sh_info of SHT_GROUP section needs to point to the correct
1382 * string in the symbol table.
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];
1388 if (!gelf_update_shdr(s->os, &osh))
1389 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1392 elferr = elf_errno();
1394 errx(EXIT_FAILURE, "elf_nextscn failed: %s",
1395 elf_errmsg(elferr));
1399 init_shstrtab(struct elfcopy *ecp)
1404 size_t indx, sizehint;
1406 if (elf_getshdrstrndx(ecp->ein, &indx) == 0) {
1407 shstrtab = elf_getscn(ecp->ein, indx);
1408 if (shstrtab == NULL)
1409 errx(EXIT_FAILURE, "elf_getscn failed: %s",
1411 if (gelf_getshdr(shstrtab, &shdr) != &shdr)
1412 errx(EXIT_FAILURE, "gelf_getshdr failed: %s",
1414 sizehint = shdr.sh_size;
1416 /* Clear the error from elf_getshdrstrndx(3). */
1421 if ((ecp->shstrtab = calloc(1, sizeof(*ecp->shstrtab))) == NULL)
1422 err(EXIT_FAILURE, "calloc failed");
1424 s->name = ".shstrtab";
1429 s->type = SHT_STRTAB;
1431 s->strtab = elftc_string_table_create(sizehint);
1433 add_to_shstrtab(ecp, "");
1434 add_to_shstrtab(ecp, ".symtab");
1435 add_to_shstrtab(ecp, ".strtab");
1436 add_to_shstrtab(ecp, ".shstrtab");
1440 set_shstrtab(struct elfcopy *ecp)
1450 if (s->os == NULL) {
1451 /* Input object does not contain .shstrtab section */
1452 if ((s->os = elf_newscn(ecp->eout)) == NULL)
1453 errx(EXIT_FAILURE, "elf_newscn failed: %s",
1455 insert_to_sec_list(ecp, s, 1);
1458 if (gelf_getshdr(s->os, &sh) == NULL)
1459 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
1462 sh.sh_addralign = 1;
1463 sh.sh_offset = s->off;
1464 sh.sh_type = SHT_STRTAB;
1470 if ((data = elf_newdata(s->os)) == NULL)
1471 errx(EXIT_FAILURE, "elf_newdata() failed: %s",
1475 * If we don't have a symbol table, skip those a few bytes
1476 * which are reserved for this in the beginning of shstrtab.
1478 if (!(ecp->flags & SYMTAB_EXIST)) {
1479 elftc_string_table_remove(s->strtab, ".symtab");
1480 elftc_string_table_remove(s->strtab, ".strtab");
1483 image = elftc_string_table_image(s->strtab, &sz);
1487 if (!gelf_update_shdr(s->os, &sh))
1488 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s",
1492 data->d_buf = (void *)(uintptr_t)image;
1495 data->d_type = ELF_T_BYTE;
1496 data->d_version = EV_CURRENT;
1498 if (!elf_setshstrndx(ecp->eout, elf_ndxscn(s->os)))
1499 errx(EXIT_FAILURE, "elf_setshstrndx() failed: %s",
1504 add_section(struct elfcopy *ecp, const char *arg)
1512 if ((s = strchr(arg, '=')) == NULL)
1514 "illegal format for --add-section option");
1515 if ((sa = malloc(sizeof(*sa))) == NULL)
1516 err(EXIT_FAILURE, "malloc failed");
1519 if ((sa->name = malloc(len + 1)) == NULL)
1520 err(EXIT_FAILURE, "malloc failed");
1521 strncpy(sa->name, arg, len);
1522 sa->name[len] = '\0';
1525 if (stat(fn, &sb) == -1)
1526 err(EXIT_FAILURE, "stat failed");
1527 sa->size = sb.st_size;
1529 if ((sa->content = malloc(sa->size)) == NULL)
1530 err(EXIT_FAILURE, "malloc failed");
1531 if ((fp = fopen(fn, "r")) == NULL)
1532 err(EXIT_FAILURE, "can not open %s", fn);
1533 if (fread(sa->content, 1, sa->size, fp) == 0 ||
1535 err(EXIT_FAILURE, "fread failed");
1540 STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1541 ecp->flags |= SEC_ADD;
1545 free_sec_add(struct elfcopy *ecp)
1547 struct sec_add *sa, *sa_temp;
1549 STAILQ_FOREACH_SAFE(sa, &ecp->v_sadd, sadd_list, sa_temp) {
1550 STAILQ_REMOVE(&ecp->v_sadd, sa, sec_add, sadd_list);
1558 add_gnu_debuglink(struct elfcopy *ecp)
1567 if (ecp->debuglink == NULL)
1570 /* Read debug file content. */
1571 if ((sa = malloc(sizeof(*sa))) == NULL)
1572 err(EXIT_FAILURE, "malloc failed");
1573 if ((sa->name = strdup(".gnu_debuglink")) == NULL)
1574 err(EXIT_FAILURE, "strdup failed");
1575 if (stat(ecp->debuglink, &sb) == -1)
1576 err(EXIT_FAILURE, "stat failed");
1577 if (sb.st_size == 0)
1578 errx(EXIT_FAILURE, "empty debug link target %s",
1580 if ((buf = malloc(sb.st_size)) == NULL)
1581 err(EXIT_FAILURE, "malloc failed");
1582 if ((fp = fopen(ecp->debuglink, "r")) == NULL)
1583 err(EXIT_FAILURE, "can not open %s", ecp->debuglink);
1584 if (fread(buf, 1, sb.st_size, fp) == 0 ||
1586 err(EXIT_FAILURE, "fread failed");
1589 /* Calculate crc checksum. */
1590 crc = calc_crc32(buf, sb.st_size, 0xFFFFFFFF);
1593 /* Calculate section size and the offset to store crc checksum. */
1594 if ((fnbase = basename(ecp->debuglink)) == NULL)
1595 err(EXIT_FAILURE, "basename failed");
1596 crc_off = roundup(strlen(fnbase) + 1, 4);
1597 sa->size = crc_off + 4;
1599 /* Section content. */
1600 if ((sa->content = calloc(1, sa->size)) == NULL)
1601 err(EXIT_FAILURE, "malloc failed");
1602 strncpy(sa->content, fnbase, strlen(fnbase));
1603 if (ecp->oed == ELFDATA2LSB) {
1604 sa->content[crc_off] = crc & 0xFF;
1605 sa->content[crc_off + 1] = (crc >> 8) & 0xFF;
1606 sa->content[crc_off + 2] = (crc >> 16) & 0xFF;
1607 sa->content[crc_off + 3] = crc >> 24;
1609 sa->content[crc_off] = crc >> 24;
1610 sa->content[crc_off + 1] = (crc >> 16) & 0xFF;
1611 sa->content[crc_off + 2] = (crc >> 8) & 0xFF;
1612 sa->content[crc_off + 3] = crc & 0xFF;
1615 STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list);
1616 ecp->flags |= SEC_ADD;
1619 static uint32_t crctable[256] =
1621 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
1622 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
1623 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
1624 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
1625 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
1626 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
1627 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
1628 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
1629 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
1630 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
1631 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
1632 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
1633 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
1634 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
1635 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
1636 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
1637 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
1638 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
1639 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
1640 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
1641 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
1642 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
1643 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
1644 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
1645 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
1646 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
1647 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
1648 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
1649 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
1650 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
1651 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
1652 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
1653 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
1654 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
1655 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
1656 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
1657 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
1658 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
1659 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
1660 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
1661 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
1662 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
1663 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
1664 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
1665 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
1666 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
1667 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
1668 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
1669 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
1670 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
1671 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
1672 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
1673 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
1674 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
1675 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
1676 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
1677 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
1678 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
1679 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
1680 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
1681 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
1682 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
1683 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
1684 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
1688 calc_crc32(const char *p, size_t len, uint32_t crc)
1692 for (i = 0; i < len; i++) {
1693 crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8);
1696 return (crc ^ 0xFFFFFFFF);