+++ /dev/null
-2006-09-19 Jakub Jelinek <jakub@redhat.com>
-
- * 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,6 +827,37 @@ 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);
-@@ -835,6 +867,7 @@ handle_elf (int fd, Elf *elf, const char
- elf_errmsg (-1));
-
- bool discard_section = (shdr_info[cnt].idx > 0
-+ && shdr_info[cnt].debug_data == NULL
- && shdr_info[cnt].shdr.sh_type != SHT_NOTE
- && cnt != ehdr->e_shstrndx);
-
-@@ -865,6 +898,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
-@@ -1056,7 +1096,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)
-@@ -1283,6 +1323,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
-@@ -1341,6 +1388,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. */
-@@ -1460,7 +1514,7 @@ handle_elf (int fd, Elf *elf, const char
- chain[hidx] = inner;
- }
- }
-- }
-+ }
- }
- else if (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)
- {
-@@ -1473,6 +1527,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. */
-@@ -1515,20 +1576,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);
- }
- }
- }
-@@ -1658,7 +1726,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/tests/run-strip-test5.sh.~1~
-+++ elfutils/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
-