SOURCES: elfutils-strip-copy-symtab.patch (NEW) - from FC, with te...
qboosh
qboosh at pld-linux.org
Fri Nov 17 17:45:22 CET 2006
Author: qboosh Date: Fri Nov 17 16:45:22 2006 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- from FC, with tests part omitted
---- Files affected:
SOURCES:
elfutils-strip-copy-symtab.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/elfutils-strip-copy-symtab.patch
diff -u /dev/null SOURCES/elfutils-strip-copy-symtab.patch:1.1
--- /dev/null Fri Nov 17 17:45:22 2006
+++ SOURCES/elfutils-strip-copy-symtab.patch Fri Nov 17 17:45:17 2006
@@ -0,0 +1,193 @@
+2006-09-19 Jakub Jelinek <jakub at 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,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)
+
================================================================
More information about the pld-cvs-commit
mailing list