]>
Commit | Line | Data |
---|---|---|
5cf1fa4c JB |
1 | 2006-09-19 Jakub Jelinek <jakub@redhat.com> |
2 | ||
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. | |
6 | ||
7 | --- elfutils/src/strip.c | |
8 | +++ elfutils/src/strip.c | |
9 | @@ -399,6 +399,7 @@ handle_elf (int fd, Elf *elf, const char | |
10 | Elf_Scn *newscn; | |
11 | struct Ebl_Strent *se; | |
12 | Elf32_Word *newsymidx; | |
13 | + void *debug_data; | |
14 | } *shdr_info = NULL; | |
15 | Elf_Scn *scn; | |
16 | size_t cnt; | |
9bd92250 | 17 | @@ -826,6 +827,37 @@ handle_elf (int fd, Elf *elf, const char |
5cf1fa4c JB |
18 | The ones that are not removed in the stripped file are SHT_NOBITS. */ |
19 | if (debug_fname != NULL) | |
20 | { | |
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 | |
25 | + places. */ | |
9bd92250 JB |
26 | + for (cnt = 1; cnt < shnum; ++cnt) |
27 | + { | |
5cf1fa4c JB |
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) | |
32 | + { | |
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 = ""; | |
37 | + if (si->symtab_idx) | |
38 | + shdr_info[si->symtab_idx].debug_data = ""; | |
39 | + | |
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) | |
44 | + || (si->symtab_idx | |
45 | + && (shdr_info[si->symtab_idx].shdr.sh_flags | |
46 | + & SHF_ALLOC))) | |
47 | + error (EXIT_FAILURE, 0, | |
48 | + gettext ("invalid symtab/strtab referenced by nonallocated section")); | |
49 | + } | |
50 | + } | |
51 | + | |
9bd92250 JB |
52 | for (cnt = 1; cnt < shnum; ++cnt) |
53 | { | |
5cf1fa4c | 54 | scn = elf_newscn (debugelf); |
9bd92250 | 55 | @@ -835,6 +867,7 @@ handle_elf (int fd, Elf *elf, const char |
5cf1fa4c JB |
56 | elf_errmsg (-1)); |
57 | ||
58 | bool discard_section = (shdr_info[cnt].idx > 0 | |
9bd92250 JB |
59 | + && shdr_info[cnt].debug_data == NULL |
60 | && shdr_info[cnt].shdr.sh_type != SHT_NOTE | |
61 | && cnt != ehdr->e_shstrndx); | |
5cf1fa4c | 62 | |
9bd92250 | 63 | @@ -865,6 +898,13 @@ handle_elf (int fd, Elf *elf, const char |
5cf1fa4c JB |
64 | *debugdata = *shdr_info[cnt].data; |
65 | if (discard_section) | |
66 | debugdata->d_buf = NULL; | |
67 | + else if (shdr_info[cnt].debug_data != NULL) | |
68 | + { | |
69 | + shdr_info[cnt].debug_data = xmalloc (debugdata->d_size); | |
70 | + memcpy (shdr_info[cnt].debug_data, debugdata->d_buf, | |
71 | + debugdata->d_size); | |
72 | + debugdata->d_buf = shdr_info[cnt].debug_data; | |
73 | + } | |
74 | } | |
75 | ||
76 | /* Finish the ELF header. Fill in the fields not handled by | |
9bd92250 | 77 | @@ -1056,7 +1096,7 @@ handle_elf (int fd, Elf *elf, const char |
5cf1fa4c JB |
78 | shdr_info[shdr_info[cnt].shdr.sh_info].idx; |
79 | ||
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. */ | |
83 | if (cnt < shnum) | |
84 | { | |
85 | if (shdr_info[cnt].data == NULL) | |
9bd92250 | 86 | @@ -1283,6 +1323,13 @@ handle_elf (int fd, Elf *elf, const char |
5cf1fa4c JB |
87 | if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL) |
88 | continue; | |
89 | ||
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) | |
95 | + continue; | |
96 | + | |
97 | Elf32_Word *newsymidx | |
98 | = shdr_info[shdr_info[cnt].old_sh_link].newsymidx; | |
99 | Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0 | |
9bd92250 | 100 | @@ -1341,6 +1388,13 @@ handle_elf (int fd, Elf *elf, const char |
5cf1fa4c JB |
101 | if (shdr_info[symtabidx].newsymidx == NULL) |
102 | continue; | |
103 | ||
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) | |
109 | + continue; | |
110 | + | |
111 | assert (shdr_info[cnt].idx > 0); | |
112 | ||
113 | /* The hash section in the new file. */ | |
9bd92250 | 114 | @@ -1460,7 +1514,7 @@ handle_elf (int fd, Elf *elf, const char |
5cf1fa4c JB |
115 | chain[hidx] = inner; |
116 | } | |
117 | } | |
118 | - } | |
119 | + } | |
120 | } | |
121 | else if (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym) | |
122 | { | |
9bd92250 | 123 | @@ -1473,6 +1527,13 @@ handle_elf (int fd, Elf *elf, const char |
5cf1fa4c JB |
124 | if (shdr_info[symtabidx].newsymidx == NULL) |
125 | continue; | |
126 | ||
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) | |
132 | + continue; | |
133 | + | |
134 | assert (shdr_info[cnt].idx > 0); | |
135 | ||
136 | /* The symbol version section in the new file. */ | |
9bd92250 | 137 | @@ -1515,20 +1576,27 @@ handle_elf (int fd, Elf *elf, const char |
5cf1fa4c JB |
138 | else if (shdr_info[cnt].shdr.sh_type == SHT_GROUP) |
139 | { | |
140 | /* Check whether the associated symbol table changed. */ | |
141 | - if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx != NULL) | |
142 | - { | |
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) | |
150 | + continue; | |
151 | ||
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) | |
159 | + continue; | |
160 | ||
161 | - (void) gelf_update_shdr (scn, shdr); | |
162 | - } | |
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); | |
169 | + | |
170 | + size_t stabidx = shdr_info[cnt].old_sh_link; | |
171 | + shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info]; | |
172 | + | |
173 | + (void) gelf_update_shdr (scn, shdr); | |
174 | } | |
175 | } | |
176 | } | |
9bd92250 | 177 | @@ -1658,7 +1726,10 @@ handle_elf (int fd, Elf *elf, const char |
5cf1fa4c JB |
178 | table indices. */ |
179 | if (any_symtab_changes) | |
180 | for (cnt = 1; cnt <= shdridx; ++cnt) | |
181 | - free (shdr_info[cnt].newsymidx); | |
182 | + { | |
183 | + free (shdr_info[cnt].newsymidx); | |
184 | + free (shdr_info[cnt].debug_data); | |
185 | + } | |
186 | ||
187 | /* Free the memory. */ | |
188 | if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC) | |
9bd92250 JB |
189 | --- elfutils/tests/run-strip-test5.sh.~1~ |
190 | +++ elfutils/tests/run-strip-test5.sh | |
191 | @@ -1,5 +1,5 @@ | |
192 | original=testfile8 | |
193 | -stripped=testfile16 | |
194 | -debugfile=testfile16.debug | |
195 | +stripped=testfile16.symtab | |
196 | +debugfile=testfile16.symtab.debug | |
197 | ||
198 | . $srcdir/run-strip-test.sh | |
5cf1fa4c | 199 |