Annotation of /trunk/elfutils/patches/elfutils-0.125-strip-copy-symtab.patch
Parent Directory | Revision Log
Revision 144 -
(hide annotations)
(download)
Tue May 8 20:06:05 2007 UTC (17 years, 4 months ago) by niro
File size: 7212 byte(s)
Tue May 8 20:06:05 2007 UTC (17 years, 4 months ago) by niro
File size: 7212 byte(s)
-import
1 | niro | 144 | 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; | ||
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) | ||
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. */ | ||
26 | for (cnt = 1; cnt < shnum; ++cnt) | ||
27 | { | ||
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 | + | ||
52 | + for (cnt = 1; cnt < shnum; ++cnt) | ||
53 | + { | ||
54 | scn = elf_newscn (debugelf); | ||
55 | if (scn == NULL) | ||
56 | error (EXIT_FAILURE, 0, | ||
57 | @@ -835,7 +867,8 @@ handle_elf (int fd, Elf *elf, const char | ||
58 | elf_errmsg (-1)); | ||
59 | |||
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); | ||
64 | |||
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; | ||
69 | if (discard_section) | ||
70 | debugdata->d_buf = NULL; | ||
71 | + else if (shdr_info[cnt].debug_data != NULL) | ||
72 | + { | ||
73 | + shdr_info[cnt].debug_data = xmalloc (debugdata->d_size); | ||
74 | + memcpy (shdr_info[cnt].debug_data, debugdata->d_buf, | ||
75 | + debugdata->d_size); | ||
76 | + debugdata->d_buf = shdr_info[cnt].debug_data; | ||
77 | + } | ||
78 | } | ||
79 | |||
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; | ||
83 | |||
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. */ | ||
87 | if (cnt < shnum) | ||
88 | { | ||
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) | ||
92 | continue; | ||
93 | |||
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) | ||
99 | + continue; | ||
100 | + | ||
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) | ||
106 | continue; | ||
107 | |||
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) | ||
113 | + continue; | ||
114 | + | ||
115 | assert (shdr_info[cnt].idx > 0); | ||
116 | |||
117 | /* The hash section in the new file. */ | ||
118 | @@ -1447,7 +1501,7 @@ handle_elf (int fd, Elf *elf, const char | ||
119 | chain[hidx] = inner; | ||
120 | } | ||
121 | } | ||
122 | - } | ||
123 | + } | ||
124 | } | ||
125 | else if (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym) | ||
126 | { | ||
127 | @@ -1460,6 +1514,13 @@ handle_elf (int fd, Elf *elf, const char | ||
128 | if (shdr_info[symtabidx].newsymidx == NULL) | ||
129 | continue; | ||
130 | |||
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) | ||
136 | + continue; | ||
137 | + | ||
138 | assert (shdr_info[cnt].idx > 0); | ||
139 | |||
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) | ||
143 | { | ||
144 | /* Check whether the associated symbol table changed. */ | ||
145 | - if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx != NULL) | ||
146 | - { | ||
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) | ||
154 | + continue; | ||
155 | |||
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) | ||
163 | + continue; | ||
164 | |||
165 | - (void) gelf_update_shdr (scn, shdr); | ||
166 | - } | ||
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); | ||
173 | + | ||
174 | + size_t stabidx = shdr_info[cnt].old_sh_link; | ||
175 | + shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info]; | ||
176 | + | ||
177 | + (void) gelf_update_shdr (scn, shdr); | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | @@ -1647,7 +1715,10 @@ handle_elf (int fd, Elf *elf, const char | ||
182 | table indices. */ | ||
183 | if (any_symtab_changes) | ||
184 | for (cnt = 1; cnt <= shdridx; ++cnt) | ||
185 | - free (shdr_info[cnt].newsymidx); | ||
186 | + { | ||
187 | + free (shdr_info[cnt].newsymidx); | ||
188 | + free (shdr_info[cnt].debug_data); | ||
189 | + } | ||
190 | |||
191 | /* Free the memory. */ | ||
192 | if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC) | ||
193 | |||
194 | --- elfutils-0.124/tests/run-strip-test5.sh.~1~ | ||
195 | +++ elfutils-0.124/tests/run-strip-test5.sh | ||
196 | @@ -1,5 +1,5 @@ | ||
197 | original=testfile8 | ||
198 | -stripped=testfile16 | ||
199 | -debugfile=testfile16.debug | ||
200 | +stripped=testfile16.symtab | ||
201 | +debugfile=testfile16.symtab.debug | ||
202 | |||
203 | . $srcdir/run-strip-test.sh | ||
204 |