|
|
f453240 |
2006-09-19 Jakub Jelinek <jakub@redhat.com>
|
|
|
f453240 |
|
|
|
f453240 |
* strip.c (handle_elf): Formatting. If any relocation sections
|
|
|
f453240 |
stripped into separate debug info reference symtab that is kept,
|
|
|
f453240 |
emit symtab/strtab also into the separate debug info file.
|
|
|
f453240 |
|
|
|
f453240 |
--- elfutils/src/strip.c
|
|
|
f453240 |
+++ elfutils/src/strip.c
|
|
|
f453240 |
@@ -399,6 +399,7 @@ handle_elf (int fd, Elf *elf, const char
|
|
|
f453240 |
Elf_Scn *newscn;
|
|
|
f453240 |
struct Ebl_Strent *se;
|
|
|
f453240 |
Elf32_Word *newsymidx;
|
|
|
f453240 |
+ void *debug_data;
|
|
|
f453240 |
} *shdr_info = NULL;
|
|
|
f453240 |
Elf_Scn *scn;
|
|
|
f453240 |
size_t cnt;
|
|
|
f453240 |
@@ -826,8 +827,39 @@ handle_elf (int fd, Elf *elf, const char
|
|
|
f453240 |
The ones that are not removed in the stripped file are SHT_NOBITS. */
|
|
|
f453240 |
if (debug_fname != NULL)
|
|
|
f453240 |
{
|
|
|
f453240 |
+ /* libbfd and apps using it don't cope with separate debuginfo objects
|
|
|
f453240 |
+ with relocation sections against SHT_NOBITS .symtab/.strtab
|
|
|
f453240 |
+ - libbfd isn't able to look up the .symtab/.strtab in the stripped
|
|
|
f453240 |
+ object instead. As a workaround, emit .symtab/.strtab in both
|
|
|
f453240 |
+ places. */
|
|
|
f453240 |
for (cnt = 1; cnt < shnum; ++cnt)
|
|
|
f453240 |
{
|
|
|
f453240 |
+ if (shdr_info[cnt].idx == 0
|
|
|
f453240 |
+ && (shdr_info[cnt].shdr.sh_type == SHT_REL
|
|
|
f453240 |
+ || shdr_info[cnt].shdr.sh_type == SHT_RELA)
|
|
|
f453240 |
+ && (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
|
|
|
f453240 |
+ {
|
|
|
f453240 |
+ Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
|
|
|
f453240 |
+ struct shdr_info *si = &shdr_info[symtabidx];
|
|
|
f453240 |
+ si->debug_data = "";
|
|
|
f453240 |
+ shdr_info[si->old_sh_link].debug_data = "";
|
|
|
f453240 |
+ if (si->symtab_idx)
|
|
|
f453240 |
+ shdr_info[si->symtab_idx].debug_data = "";
|
|
|
f453240 |
+
|
|
|
f453240 |
+ if (si->shdr.sh_type != SHT_SYMTAB
|
|
|
f453240 |
+ || (si->shdr.sh_flags & SHF_ALLOC)
|
|
|
f453240 |
+ || shdr_info[si->old_sh_link].shdr.sh_type != SHT_STRTAB
|
|
|
f453240 |
+ || (shdr_info[si->old_sh_link].shdr.sh_flags & SHF_ALLOC)
|
|
|
f453240 |
+ || (si->symtab_idx
|
|
|
f453240 |
+ && (shdr_info[si->symtab_idx].shdr.sh_flags
|
|
|
f453240 |
+ & SHF_ALLOC)))
|
|
|
f453240 |
+ error (EXIT_FAILURE, 0,
|
|
|
f453240 |
+ gettext ("invalid symtab/strtab referenced by nonallocated section"));
|
|
|
f453240 |
+ }
|
|
|
f453240 |
+ }
|
|
|
f453240 |
+
|
|
|
f453240 |
+ for (cnt = 1; cnt < shnum; ++cnt)
|
|
|
f453240 |
+ {
|
|
|
f453240 |
scn = elf_newscn (debugelf);
|
|
|
f453240 |
if (scn == NULL)
|
|
|
f453240 |
error (EXIT_FAILURE, 0,
|
|
|
f453240 |
@@ -835,7 +867,8 @@ handle_elf (int fd, Elf *elf, const char
|
|
|
f453240 |
elf_errmsg (-1));
|
|
|
f453240 |
|
|
|
f453240 |
bool discard_section = (shdr_info[cnt].idx > 0
|
|
|
f453240 |
- && cnt != ehdr->e_shstrndx);
|
|
|
f453240 |
+ && cnt != ehdr->e_shstrndx
|
|
|
f453240 |
+ && shdr_info[cnt].debug_data == NULL);
|
|
|
f453240 |
|
|
|
f453240 |
/* Set the section header in the new file. */
|
|
|
f453240 |
GElf_Shdr debugshdr = shdr_info[cnt].shdr;
|
|
|
f453240 |
@@ -864,6 +897,13 @@ handle_elf (int fd, Elf *elf, const char
|
|
|
f453240 |
*debugdata = *shdr_info[cnt].data;
|
|
|
f453240 |
if (discard_section)
|
|
|
f453240 |
debugdata->d_buf = NULL;
|
|
|
f453240 |
+ else if (shdr_info[cnt].debug_data != NULL)
|
|
|
f453240 |
+ {
|
|
|
f453240 |
+ shdr_info[cnt].debug_data = xmalloc (debugdata->d_size);
|
|
|
f453240 |
+ memcpy (shdr_info[cnt].debug_data, debugdata->d_buf,
|
|
|
f453240 |
+ debugdata->d_size);
|
|
|
f453240 |
+ debugdata->d_buf = shdr_info[cnt].debug_data;
|
|
|
f453240 |
+ }
|
|
|
f453240 |
}
|
|
|
f453240 |
|
|
|
f453240 |
/* Finish the ELF header. Fill in the fields not handled by
|
|
|
f453240 |
@@ -1055,7 +1095,7 @@ handle_elf (int fd, Elf *elf, const char
|
|
|
f453240 |
shdr_info[shdr_info[cnt].shdr.sh_info].idx;
|
|
|
f453240 |
|
|
|
f453240 |
/* Get the data from the old file if necessary. We already
|
|
|
f453240 |
- created the data for the section header string table. */
|
|
|
f453240 |
+ created the data for the section header string table. */
|
|
|
f453240 |
if (cnt < shnum)
|
|
|
f453240 |
{
|
|
|
f453240 |
if (shdr_info[cnt].data == NULL)
|
|
|
f453240 |
@@ -1264,6 +1304,13 @@ handle_elf (int fd, Elf *elf, const char
|
|
|
f453240 |
if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
|
|
|
f453240 |
continue;
|
|
|
f453240 |
|
|
|
f453240 |
+ /* If the symbol table is not discarded, but additionally
|
|
|
f453240 |
+ duplicated in separate debug file and this section
|
|
|
f453240 |
+ is discarded, don't adjust anything. */
|
|
|
f453240 |
+ if (shdr_info[cnt].idx == 0
|
|
|
f453240 |
+ && shdr_info[shdr_info[cnt].old_sh_link].debug_data != NULL)
|
|
|
f453240 |
+ continue;
|
|
|
f453240 |
+
|
|
|
f453240 |
Elf32_Word *newsymidx
|
|
|
f453240 |
= shdr_info[shdr_info[cnt].old_sh_link].newsymidx;
|
|
|
f453240 |
Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
|
|
|
f453240 |
@@ -1322,6 +1369,13 @@ handle_elf (int fd, Elf *elf, const char
|
|
|
f453240 |
if (shdr_info[symtabidx].newsymidx == NULL)
|
|
|
f453240 |
continue;
|
|
|
f453240 |
|
|
|
f453240 |
+ /* If the symbol table is not discarded, but additionally
|
|
|
f453240 |
+ duplicated in separate debug file and this section
|
|
|
f453240 |
+ is discarded, don't adjust anything. */
|
|
|
f453240 |
+ if (shdr_info[cnt].idx == 0
|
|
|
f453240 |
+ && shdr_info[symtabidx].debug_data != NULL)
|
|
|
f453240 |
+ continue;
|
|
|
f453240 |
+
|
|
|
f453240 |
assert (shdr_info[cnt].idx > 0);
|
|
|
f453240 |
|
|
|
f453240 |
/* The hash section in the new file. */
|
|
|
f453240 |
@@ -1447,7 +1501,7 @@ handle_elf (int fd, Elf *elf, const char
|
|
|
f453240 |
chain[hidx] = inner;
|
|
|
f453240 |
}
|
|
|
f453240 |
}
|
|
|
f453240 |
- }
|
|
|
f453240 |
+ }
|
|
|
f453240 |
}
|
|
|
f453240 |
else if (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)
|
|
|
f453240 |
{
|
|
|
f453240 |
@@ -1460,6 +1514,13 @@ handle_elf (int fd, Elf *elf, const char
|
|
|
f453240 |
if (shdr_info[symtabidx].newsymidx == NULL)
|
|
|
f453240 |
continue;
|
|
|
f453240 |
|
|
|
f453240 |
+ /* If the symbol table is not discarded, but additionally
|
|
|
f453240 |
+ duplicated in separate debug file and this section
|
|
|
f453240 |
+ is discarded, don't adjust anything. */
|
|
|
f453240 |
+ if (shdr_info[cnt].idx == 0
|
|
|
f453240 |
+ && shdr_info[symtabidx].debug_data != NULL)
|
|
|
f453240 |
+ continue;
|
|
|
f453240 |
+
|
|
|
f453240 |
assert (shdr_info[cnt].idx > 0);
|
|
|
f453240 |
|
|
|
f453240 |
/* The symbol version section in the new file. */
|
|
|
f453240 |
@@ -1504,20 +1565,27 @@ handle_elf (int fd, Elf *elf, const char
|
|
|
f453240 |
else if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
|
|
|
f453240 |
{
|
|
|
f453240 |
/* Check whether the associated symbol table changed. */
|
|
|
f453240 |
- if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx != NULL)
|
|
|
f453240 |
- {
|
|
|
f453240 |
- /* Yes the symbol table changed. Update the section
|
|
|
f453240 |
- header of the section group. */
|
|
|
f453240 |
- scn = elf_getscn (newelf, shdr_info[cnt].idx);
|
|
|
f453240 |
- GElf_Shdr shdr_mem;
|
|
|
f453240 |
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
|
|
|
f453240 |
- assert (shdr != NULL);
|
|
|
f453240 |
+ if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
|
|
|
f453240 |
+ continue;
|
|
|
f453240 |
|
|
|
f453240 |
- size_t stabidx = shdr_info[cnt].old_sh_link;
|
|
|
f453240 |
- shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
|
|
|
f453240 |
+ /* If the symbol table is not discarded, but additionally
|
|
|
f453240 |
+ duplicated in separate debug file and this section
|
|
|
f453240 |
+ is discarded, don't adjust anything. */
|
|
|
f453240 |
+ if (shdr_info[cnt].idx == 0
|
|
|
f453240 |
+ && shdr_info[shdr_info[cnt].old_sh_link].debug_data != NULL)
|
|
|
f453240 |
+ continue;
|
|
|
f453240 |
|
|
|
f453240 |
- (void) gelf_update_shdr (scn, shdr);
|
|
|
f453240 |
- }
|
|
|
f453240 |
+ /* Yes the symbol table changed. Update the section
|
|
|
f453240 |
+ header of the section group. */
|
|
|
f453240 |
+ scn = elf_getscn (newelf, shdr_info[cnt].idx);
|
|
|
f453240 |
+ GElf_Shdr shdr_mem;
|
|
|
f453240 |
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
|
|
|
f453240 |
+ assert (shdr != NULL);
|
|
|
f453240 |
+
|
|
|
f453240 |
+ size_t stabidx = shdr_info[cnt].old_sh_link;
|
|
|
f453240 |
+ shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
|
|
|
f453240 |
+
|
|
|
f453240 |
+ (void) gelf_update_shdr (scn, shdr);
|
|
|
f453240 |
}
|
|
|
f453240 |
}
|
|
|
f453240 |
}
|
|
|
f453240 |
@@ -1647,7 +1715,10 @@ handle_elf (int fd, Elf *elf, const char
|
|
|
f453240 |
table indices. */
|
|
|
f453240 |
if (any_symtab_changes)
|
|
|
f453240 |
for (cnt = 1; cnt <= shdridx; ++cnt)
|
|
|
f453240 |
- free (shdr_info[cnt].newsymidx);
|
|
|
f453240 |
+ {
|
|
|
f453240 |
+ free (shdr_info[cnt].newsymidx);
|
|
|
f453240 |
+ free (shdr_info[cnt].debug_data);
|
|
|
f453240 |
+ }
|
|
|
f453240 |
|
|
|
f453240 |
/* Free the memory. */
|
|
|
f453240 |
if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
|
|
|
f453240 |
|
|
|
f453240 |
--- elfutils-0.124/tests/run-strip-test5.sh.~1~
|
|
|
f453240 |
+++ elfutils-0.124/tests/run-strip-test5.sh
|
|
|
f453240 |
@@ -1,5 +1,5 @@
|
|
|
f453240 |
original=testfile8
|
|
|
f453240 |
-stripped=testfile16
|
|
|
f453240 |
-debugfile=testfile16.debug
|
|
|
f453240 |
+stripped=testfile16.symtab
|
|
|
f453240 |
+debugfile=testfile16.symtab.debug
|
|
|
f453240 |
|
|
|
f453240 |
. $srcdir/run-strip-test.sh
|
|
|
f453240 |
|