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,8 +827,39 @@ 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);
56 error (EXIT_FAILURE, 0,
57 @@ -835,7 +867,8 @@ handle_elf (int fd, Elf *elf, const char
60 bool discard_section = (shdr_info[cnt].idx > 0
61 - && cnt != ehdr->e_shstrndx);
62 + && cnt != ehdr->e_shstrndx
63 + && shdr_info[cnt].debug_data == NULL);
65 /* Set the section header in the new file. */
66 GElf_Shdr debugshdr = shdr_info[cnt].shdr;
67 @@ -864,6 +897,13 @@ handle_elf (int fd, Elf *elf, const char
68 *debugdata = *shdr_info[cnt].data;
70 debugdata->d_buf = NULL;
71 + else if (shdr_info[cnt].debug_data != NULL)
73 + shdr_info[cnt].debug_data = xmalloc (debugdata->d_size);
74 + memcpy (shdr_info[cnt].debug_data, debugdata->d_buf,
76 + debugdata->d_buf = shdr_info[cnt].debug_data;
80 /* Finish the ELF header. Fill in the fields not handled by
81 @@ -1055,7 +1095,7 @@ handle_elf (int fd, Elf *elf, const char
82 shdr_info[shdr_info[cnt].shdr.sh_info].idx;
84 /* Get the data from the old file if necessary. We already
85 - created the data for the section header string table. */
86 + created the data for the section header string table. */
89 if (shdr_info[cnt].data == NULL)
90 @@ -1264,6 +1304,13 @@ handle_elf (int fd, Elf *elf, const char
91 if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
94 + /* If the symbol table is not discarded, but additionally
95 + duplicated in separate debug file and this section
96 + is discarded, don't adjust anything. */
97 + if (shdr_info[cnt].idx == 0
98 + && shdr_info[shdr_info[cnt].old_sh_link].debug_data != NULL)
101 Elf32_Word *newsymidx
102 = shdr_info[shdr_info[cnt].old_sh_link].newsymidx;
103 Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
104 @@ -1322,6 +1369,13 @@ handle_elf (int fd, Elf *elf, const char
105 if (shdr_info[symtabidx].newsymidx == NULL)
108 + /* If the symbol table is not discarded, but additionally
109 + duplicated in separate debug file and this section
110 + is discarded, don't adjust anything. */
111 + if (shdr_info[cnt].idx == 0
112 + && shdr_info[symtabidx].debug_data != NULL)
115 assert (shdr_info[cnt].idx > 0);
117 /* The hash section in the new file. */
118 @@ -1447,7 +1501,7 @@ handle_elf (int fd, Elf *elf, const char
125 else if (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)
127 @@ -1460,6 +1514,13 @@ handle_elf (int fd, Elf *elf, const char
128 if (shdr_info[symtabidx].newsymidx == NULL)
131 + /* If the symbol table is not discarded, but additionally
132 + duplicated in separate debug file and this section
133 + is discarded, don't adjust anything. */
134 + if (shdr_info[cnt].idx == 0
135 + && shdr_info[symtabidx].debug_data != NULL)
138 assert (shdr_info[cnt].idx > 0);
140 /* The symbol version section in the new file. */
141 @@ -1504,20 +1565,27 @@ handle_elf (int fd, Elf *elf, const char
142 else if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
144 /* Check whether the associated symbol table changed. */
145 - if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx != NULL)
147 - /* Yes the symbol table changed. Update the section
148 - header of the section group. */
149 - scn = elf_getscn (newelf, shdr_info[cnt].idx);
150 - GElf_Shdr shdr_mem;
151 - GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
152 - assert (shdr != NULL);
153 + if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
156 - size_t stabidx = shdr_info[cnt].old_sh_link;
157 - shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
158 + /* If the symbol table is not discarded, but additionally
159 + duplicated in separate debug file and this section
160 + is discarded, don't adjust anything. */
161 + if (shdr_info[cnt].idx == 0
162 + && shdr_info[shdr_info[cnt].old_sh_link].debug_data != NULL)
165 - (void) gelf_update_shdr (scn, shdr);
167 + /* Yes the symbol table changed. Update the section
168 + header of the section group. */
169 + scn = elf_getscn (newelf, shdr_info[cnt].idx);
170 + GElf_Shdr shdr_mem;
171 + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
172 + assert (shdr != NULL);
174 + size_t stabidx = shdr_info[cnt].old_sh_link;
175 + shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
177 + (void) gelf_update_shdr (scn, shdr);
181 @@ -1647,7 +1715,10 @@ handle_elf (int fd, Elf *elf, const char
183 if (any_symtab_changes)
184 for (cnt = 1; cnt <= shdridx; ++cnt)
185 - free (shdr_info[cnt].newsymidx);
187 + free (shdr_info[cnt].newsymidx);
188 + free (shdr_info[cnt].debug_data);
191 /* Free the memory. */
192 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)