1 2006-09-19 Jakub Jelinek <jakub@redhat.com>
3 * strip.c (handle_elf): Formatting. If any relocation sections
4 stripped into separate debug info reference symtab that is kept,
5 emit symtab/strtab also into the separate debug info file.
7 --- elfutils/src/strip.c
8 +++ elfutils/src/strip.c
9 @@ -399,6 +399,7 @@ handle_elf (int fd, Elf *elf, const char
11 struct Ebl_Strent *se;
12 Elf32_Word *newsymidx;
17 @@ -826,6 +827,37 @@ handle_elf (int fd, Elf *elf, const char
18 The ones that are not removed in the stripped file are SHT_NOBITS. */
19 if (debug_fname != NULL)
21 + /* libbfd and apps using it don't cope with separate debuginfo objects
22 + with relocation sections against SHT_NOBITS .symtab/.strtab
23 + - libbfd isn't able to look up the .symtab/.strtab in the stripped
24 + object instead. As a workaround, emit .symtab/.strtab in both
26 + for (cnt = 1; cnt < shnum; ++cnt)
28 + if (shdr_info[cnt].idx == 0
29 + && (shdr_info[cnt].shdr.sh_type == SHT_REL
30 + || shdr_info[cnt].shdr.sh_type == SHT_RELA)
31 + && (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
33 + Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
34 + struct shdr_info *si = &shdr_info[symtabidx];
35 + si->debug_data = "";
36 + shdr_info[si->old_sh_link].debug_data = "";
38 + shdr_info[si->symtab_idx].debug_data = "";
40 + if (si->shdr.sh_type != SHT_SYMTAB
41 + || (si->shdr.sh_flags & SHF_ALLOC)
42 + || shdr_info[si->old_sh_link].shdr.sh_type != SHT_STRTAB
43 + || (shdr_info[si->old_sh_link].shdr.sh_flags & SHF_ALLOC)
45 + && (shdr_info[si->symtab_idx].shdr.sh_flags
47 + error (EXIT_FAILURE, 0,
48 + gettext ("invalid symtab/strtab referenced by nonallocated section"));
52 for (cnt = 1; cnt < shnum; ++cnt)
54 scn = elf_newscn (debugelf);
55 @@ -835,6 +867,7 @@ handle_elf (int fd, Elf *elf, const char
58 bool discard_section = (shdr_info[cnt].idx > 0
59 + && shdr_info[cnt].debug_data == NULL
60 && shdr_info[cnt].shdr.sh_type != SHT_NOTE
61 && cnt != ehdr->e_shstrndx);
63 @@ -865,6 +898,13 @@ handle_elf (int fd, Elf *elf, const char
64 *debugdata = *shdr_info[cnt].data;
66 debugdata->d_buf = NULL;
67 + else if (shdr_info[cnt].debug_data != NULL)
69 + shdr_info[cnt].debug_data = xmalloc (debugdata->d_size);
70 + memcpy (shdr_info[cnt].debug_data, debugdata->d_buf,
72 + debugdata->d_buf = shdr_info[cnt].debug_data;
76 /* Finish the ELF header. Fill in the fields not handled by
77 @@ -1056,7 +1096,7 @@ handle_elf (int fd, Elf *elf, const char
78 shdr_info[shdr_info[cnt].shdr.sh_info].idx;
80 /* Get the data from the old file if necessary. We already
81 - created the data for the section header string table. */
82 + created the data for the section header string table. */
85 if (shdr_info[cnt].data == NULL)
86 @@ -1283,6 +1323,13 @@ handle_elf (int fd, Elf *elf, const char
87 if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
90 + /* If the symbol table is not discarded, but additionally
91 + duplicated in separate debug file and this section
92 + is discarded, don't adjust anything. */
93 + if (shdr_info[cnt].idx == 0
94 + && shdr_info[shdr_info[cnt].old_sh_link].debug_data != NULL)
98 = shdr_info[shdr_info[cnt].old_sh_link].newsymidx;
99 Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
100 @@ -1341,6 +1388,13 @@ handle_elf (int fd, Elf *elf, const char
101 if (shdr_info[symtabidx].newsymidx == NULL)
104 + /* If the symbol table is not discarded, but additionally
105 + duplicated in separate debug file and this section
106 + is discarded, don't adjust anything. */
107 + if (shdr_info[cnt].idx == 0
108 + && shdr_info[symtabidx].debug_data != NULL)
111 assert (shdr_info[cnt].idx > 0);
113 /* The hash section in the new file. */
114 @@ -1460,7 +1514,7 @@ handle_elf (int fd, Elf *elf, const char
121 else if (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)
123 @@ -1473,6 +1527,13 @@ handle_elf (int fd, Elf *elf, const char
124 if (shdr_info[symtabidx].newsymidx == NULL)
127 + /* If the symbol table is not discarded, but additionally
128 + duplicated in separate debug file and this section
129 + is discarded, don't adjust anything. */
130 + if (shdr_info[cnt].idx == 0
131 + && shdr_info[symtabidx].debug_data != NULL)
134 assert (shdr_info[cnt].idx > 0);
136 /* The symbol version section in the new file. */
137 @@ -1515,20 +1576,27 @@ handle_elf (int fd, Elf *elf, const char
138 else if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
140 /* Check whether the associated symbol table changed. */
141 - if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx != NULL)
143 - /* Yes the symbol table changed. Update the section
144 - header of the section group. */
145 - scn = elf_getscn (newelf, shdr_info[cnt].idx);
146 - GElf_Shdr shdr_mem;
147 - GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
148 - assert (shdr != NULL);
149 + if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
152 - size_t stabidx = shdr_info[cnt].old_sh_link;
153 - shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
154 + /* If the symbol table is not discarded, but additionally
155 + duplicated in separate debug file and this section
156 + is discarded, don't adjust anything. */
157 + if (shdr_info[cnt].idx == 0
158 + && shdr_info[shdr_info[cnt].old_sh_link].debug_data != NULL)
161 - (void) gelf_update_shdr (scn, shdr);
163 + /* Yes the symbol table changed. Update the section
164 + header of the section group. */
165 + scn = elf_getscn (newelf, shdr_info[cnt].idx);
166 + GElf_Shdr shdr_mem;
167 + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
168 + assert (shdr != NULL);
170 + size_t stabidx = shdr_info[cnt].old_sh_link;
171 + shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
173 + (void) gelf_update_shdr (scn, shdr);
177 @@ -1658,7 +1726,10 @@ handle_elf (int fd, Elf *elf, const char
179 if (any_symtab_changes)
180 for (cnt = 1; cnt <= shdridx; ++cnt)
181 - free (shdr_info[cnt].newsymidx);
183 + free (shdr_info[cnt].newsymidx);
184 + free (shdr_info[cnt].debug_data);
187 /* Free the memory. */
188 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
189 --- elfutils/tests/run-strip-test5.sh.~1~
190 +++ elfutils/tests/run-strip-test5.sh
194 -debugfile=testfile16.debug
195 +stripped=testfile16.symtab
196 +debugfile=testfile16.symtab.debug
198 . $srcdir/run-strip-test.sh