From: Roland McGrath Date: Wed, 5 Jan 2011 03:29:24 +0000 (-0800) Subject: strip: Add --strip-sections option. X-Git-Tag: elfutils-0.151~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0b9d1fb534604a9ba19999cd8ce8e7efce28da24;p=thirdparty%2Felfutils.git strip: Add --strip-sections option. --- diff --git a/src/ChangeLog b/src/ChangeLog index 7a151927a..9d42c55e8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2011-01-04 Roland McGrath + + * strip.c (remove_shdrs): New variable. + (options, parse_opt): Grok --strip-sections to set it. + (handle_elf): When that's set, truncate off .shstrtab and shdrs. + 2010-11-10 Roland McGrath * findtextrel.c (process_file): Don't assume order of sections. diff --git a/src/strip.c b/src/strip.c index 7b2b889a8..9b2d24a3e 100644 --- a/src/strip.c +++ b/src/strip.c @@ -65,6 +65,7 @@ ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; /* Values for the parameters which have no short form. */ #define OPT_REMOVE_COMMENT 0x100 #define OPT_PERMISSIVE 0x101 +#define OPT_STRIP_SECTIONS 0x102 /* Definitions of arguments for argp functions. */ @@ -80,6 +81,8 @@ static const struct argp_option options[] = { "strip-debug", 'g', NULL, 0, N_("Remove all debugging symbols"), 0 }, { NULL, 'd', NULL, OPTION_ALIAS, NULL, 0 }, { NULL, 'S', NULL, OPTION_ALIAS, NULL, 0 }, + { "strip-sections", OPT_STRIP_SECTIONS, NULL, 0, + N_("Remove section headers (not recommended)"), 0 }, { "preserve-dates", 'p', NULL, 0, N_("Copy modified/access timestamps to the output"), 0 }, { "remove-comment", OPT_REMOVE_COMMENT, NULL, 0, @@ -140,6 +143,9 @@ static bool remove_comment; /* If true remove all debug sections. */ static bool remove_debug; +/* If true remove all section headers. */ +static bool remove_shdrs; + /* If true relax some ELF rules for input files. */ static bool permissive; @@ -268,6 +274,10 @@ parse_opt (int key, char *arg, struct argp_state *state) remove_debug = true; break; + case OPT_STRIP_SECTIONS: + remove_shdrs = true; + break; + case OPT_PERMISSIVE: permissive = true; break; @@ -1639,6 +1649,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, newehdr->e_entry = ehdr->e_entry; newehdr->e_flags = ehdr->e_flags; newehdr->e_phoff = ehdr->e_phoff; + /* We need to position the section header table. */ const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT); newehdr->e_shoff = ((shdr_info[shdridx].shdr.sh_offset @@ -1692,6 +1703,53 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, result = 1; } + if (remove_shdrs) + { + /* libelf can't cope without the section headers being properly intact. + So we just let it write them normally, and then we nuke them later. */ + + if (newehdr->e_ident[EI_CLASS] == ELFCLASS32) + { + assert (offsetof (Elf32_Ehdr, e_shentsize) + sizeof (Elf32_Half) + == offsetof (Elf32_Ehdr, e_shnum)); + assert (offsetof (Elf32_Ehdr, e_shnum) + sizeof (Elf32_Half) + == offsetof (Elf32_Ehdr, e_shstrndx)); + const Elf32_Off zero_off = 0; + const Elf32_Half zero[3] = { 0, 0, SHN_UNDEF }; + if (pwrite_retry (fd, &zero_off, sizeof zero_off, + offsetof (Elf32_Ehdr, e_shoff)) != sizeof zero_off + || (pwrite_retry (fd, zero, sizeof zero, + offsetof (Elf32_Ehdr, e_shentsize)) + != sizeof zero) + || ftruncate64 (fd, shdr_info[shdridx].shdr.sh_offset) < 0) + { + error (0, errno, gettext ("while writing '%s'"), + fname); + result = 1; + } + } + else + { + assert (offsetof (Elf64_Ehdr, e_shentsize) + sizeof (Elf64_Half) + == offsetof (Elf64_Ehdr, e_shnum)); + assert (offsetof (Elf64_Ehdr, e_shnum) + sizeof (Elf64_Half) + == offsetof (Elf64_Ehdr, e_shstrndx)); + const Elf64_Off zero_off = 0; + const Elf64_Half zero[3] = { 0, 0, SHN_UNDEF }; + if (pwrite_retry (fd, &zero_off, sizeof zero_off, + offsetof (Elf64_Ehdr, e_shoff)) != sizeof zero_off + || (pwrite_retry (fd, zero, sizeof zero, + offsetof (Elf64_Ehdr, e_shentsize)) + != sizeof zero) + || ftruncate64 (fd, shdr_info[shdridx].shdr.sh_offset) < 0) + { + error (0, errno, gettext ("while writing '%s'"), + fname); + result = 1; + } + } + } + fail_close: if (shdr_info != NULL) {