diff options
Diffstat (limited to 'src/unstrip.c')
-rw-r--r-- | src/unstrip.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/src/unstrip.c b/src/unstrip.c index 82bcdd87..d40df97d 100644 --- a/src/unstrip.c +++ b/src/unstrip.c @@ -1,5 +1,5 @@ /* Combine stripped files with separate symbols and debug information. - Copyright (C) 2007-2012, 2014 Red Hat, Inc. + Copyright (C) 2007-2012, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Roland McGrath <roland@redhat.com>, 2007. @@ -1709,9 +1709,52 @@ more sections in stripped file than debug file -- arguments reversed?")); symstrdata = elf_getdata (unstripped_strtab, NULL); Elf_Data *shndxdata = NULL; /* XXX */ + /* If symtab and the section header table share the string table + add the section names to the strtab and then (after finalizing) + fixup the section header sh_names. Also dispose of the old data. */ + struct Ebl_Strent *unstripped_strent[unstripped_shnum - 1]; + if (unstripped_shstrndx == elf_ndxscn (unstripped_strtab)) + { + for (size_t i = 0; i < unstripped_shnum - 1; ++i) + { + Elf_Scn *sec = elf_getscn (unstripped, i + 1); + GElf_Shdr mem; + GElf_Shdr *hdr = gelf_getshdr (sec, &mem); + const char *name = get_section_name (i + 1, hdr, shstrtab); + unstripped_strent[i + 1] = ebl_strtabadd (symstrtab, name, 0); + ELF_CHECK (unstripped_strent[i + 1] != NULL, + _("cannot add section name to string table: %s")); + } + + if (strtab != NULL) + { + ebl_strtabfree (strtab); + free (strtab_data->d_buf); + strtab = NULL; + } + } + ebl_strtabfinalize (symstrtab, symstrdata); elf_flagdata (symstrdata, ELF_C_SET, ELF_F_DIRTY); + /* And update the section header names if necessary. */ + if (unstripped_shstrndx == elf_ndxscn (unstripped_strtab)) + { + for (size_t i = 0; i < unstripped_shnum - 1; ++i) + { + Elf_Scn *sec = elf_getscn (unstripped, i + 1); + GElf_Shdr mem; + GElf_Shdr *hdr = gelf_getshdr (sec, &mem); + shdr->sh_name = ebl_strtaboffset (unstripped_strent[i + 1]); + update_shdr (sec, hdr); + } + } + + /* Now update the symtab shdr. Reload symtab shdr because sh_name + might have changed above. */ + shdr = gelf_getshdr (unstripped_symtab, &shdr_mem); + ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); + shdr->sh_size = symdata->d_size = (1 + nsym) * shdr->sh_entsize; symdata->d_buf = xmalloc (symdata->d_size); |