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