diff options
4 files changed, 984 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.39.inc b/meta/recipes-devtools/binutils/binutils-2.39.inc index e4fdb73243..b040e57037 100644 --- a/meta/recipes-devtools/binutils/binutils-2.39.inc +++ b/meta/recipes-devtools/binutils/binutils-2.39.inc | |||
@@ -32,6 +32,9 @@ SRC_URI = "\ | |||
32 | file://0011-Check-for-clang-before-checking-gcc-version.patch \ | 32 | file://0011-Check-for-clang-before-checking-gcc-version.patch \ |
33 | file://0012-Only-generate-an-RPATH-entry-if-LD_RUN_PATH-is-not-e.patch \ | 33 | file://0012-Only-generate-an-RPATH-entry-if-LD_RUN_PATH-is-not-e.patch \ |
34 | file://0013-CVE-2022-38533.patch \ | 34 | file://0013-CVE-2022-38533.patch \ |
35 | file://0014-CVE-2022-38128-1.patch \ | ||
36 | file://0014-CVE-2022-38128-2.patch \ | ||
37 | file://0014-CVE-2022-38128-3.patch \ | ||
35 | " | 38 | " |
36 | S = "${WORKDIR}/git" | 39 | S = "${WORKDIR}/git" |
37 | # Already in 2.39 branch | 40 | # Already in 2.39 branch |
diff --git a/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-1.patch b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-1.patch new file mode 100644 index 0000000000..0a490d86b3 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-1.patch | |||
@@ -0,0 +1,350 @@ | |||
1 | From f07c08e115e27cddf5a0030dc6332bbee1bd9c6a Mon Sep 17 00:00:00 2001 | ||
2 | From: Alan Modra <amodra@gmail.com> | ||
3 | Date: Thu, 21 Jul 2022 08:38:14 +0930 | ||
4 | Subject: [PATCH] binutils/dwarf.c: abbrev caching | ||
5 | |||
6 | I'm inclined to think that abbrev caching is counter-productive. The | ||
7 | time taken to search the list of abbrevs converted to internal form is | ||
8 | non-zero, and it's easy to decode the raw abbrevs. It's especially | ||
9 | silly to cache empty lists of decoded abbrevs (happens with zero | ||
10 | padding in .debug_abbrev), or abbrevs as they are displayed when there | ||
11 | is no further use of those abbrevs. This patch stops caching in those | ||
12 | cases. | ||
13 | |||
14 | * dwarf.c (record_abbrev_list_for_cu): Add free_list param. | ||
15 | Put abbrevs on abbrev_lists here. | ||
16 | (new_abbrev_list): Delete function. | ||
17 | (process_abbrev_set): Return newly allocated list. Move | ||
18 | abbrev base, offset and size checking to.. | ||
19 | (find_and_process_abbrev_set): ..here, new function. Handle | ||
20 | lookup of cached abbrevs here, and calculate start and end | ||
21 | for process_abbrev_set. Return free_list if newly alloc'd. | ||
22 | (process_debug_info): Consolidate cached list lookup, new list | ||
23 | alloc and processing into find_and_process_abbrev_set call. | ||
24 | Free list when not cached. | ||
25 | (display_debug_abbrev): Similarly. | ||
26 | |||
27 | Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=f07c08e115e27cddf5a0030dc6332bbee1bd9c6a] | ||
28 | |||
29 | Signed-off-by: Pgowda <pgowda.cve@gmail.com> | ||
30 | --- | ||
31 | binutils/dwarf.c | 208 +++++++++++++++++++++++++---------------------- | ||
32 | 1 file changed, 110 insertions(+), 98 deletions(-) | ||
33 | |||
34 | diff --git a/binutils/dwarf.c b/binutils/dwarf.c | ||
35 | index 267ed3bb382..2fc352f74c5 100644 | ||
36 | --- a/binutils/dwarf.c | ||
37 | +++ b/binutils/dwarf.c | ||
38 | @@ -882,8 +882,15 @@ static unsigned long next_free_abbrev_m | ||
39 | #define ABBREV_MAP_ENTRIES_INCREMENT 8 | ||
40 | |||
41 | static void | ||
42 | -record_abbrev_list_for_cu (dwarf_vma start, dwarf_vma end, abbrev_list * list) | ||
43 | +record_abbrev_list_for_cu (dwarf_vma start, dwarf_vma end, | ||
44 | + abbrev_list *list, abbrev_list *free_list) | ||
45 | { | ||
46 | + if (free_list != NULL) | ||
47 | + { | ||
48 | + list->next = abbrev_lists; | ||
49 | + abbrev_lists = list; | ||
50 | + } | ||
51 | + | ||
52 | if (cu_abbrev_map == NULL) | ||
53 | { | ||
54 | num_abbrev_map_entries = INITIAL_NUM_ABBREV_MAP_ENTRIES; | ||
55 | @@ -936,20 +943,6 @@ free_all_abbrevs (void) | ||
56 | } | ||
57 | |||
58 | static abbrev_list * | ||
59 | -new_abbrev_list (dwarf_vma abbrev_base, dwarf_vma abbrev_offset) | ||
60 | -{ | ||
61 | - abbrev_list * list = (abbrev_list *) xcalloc (sizeof * list, 1); | ||
62 | - | ||
63 | - list->abbrev_base = abbrev_base; | ||
64 | - list->abbrev_offset = abbrev_offset; | ||
65 | - | ||
66 | - list->next = abbrev_lists; | ||
67 | - abbrev_lists = list; | ||
68 | - | ||
69 | - return list; | ||
70 | -} | ||
71 | - | ||
72 | -static abbrev_list * | ||
73 | find_abbrev_list_by_abbrev_offset (dwarf_vma abbrev_base, | ||
74 | dwarf_vma abbrev_offset) | ||
75 | { | ||
76 | @@ -966,7 +959,7 @@ find_abbrev_list_by_abbrev_offset (dwarf | ||
77 | /* Find the abbreviation map for the CU that includes OFFSET. | ||
78 | OFFSET is an absolute offset from the start of the .debug_info section. */ | ||
79 | /* FIXME: This function is going to slow down readelf & objdump. | ||
80 | - Consider using a better algorithm to mitigate this effect. */ | ||
81 | + Not caching abbrevs is likely the answer. */ | ||
82 | |||
83 | static abbrev_map * | ||
84 | find_abbrev_map_by_offset (dwarf_vma offset) | ||
85 | @@ -1033,40 +1026,18 @@ add_abbrev_attr (unsigned long attrib | ||
86 | list->last_abbrev->last_attr = attr; | ||
87 | } | ||
88 | |||
89 | -/* Processes the (partial) contents of a .debug_abbrev section. | ||
90 | - Returns NULL if the end of the section was encountered. | ||
91 | - Returns the address after the last byte read if the end of | ||
92 | - an abbreviation set was found. */ | ||
93 | +/* Return processed (partial) contents of a .debug_abbrev section. | ||
94 | + Returns NULL on errors. */ | ||
95 | |||
96 | -static unsigned char * | ||
97 | +static abbrev_list * | ||
98 | process_abbrev_set (struct dwarf_section *section, | ||
99 | - dwarf_vma abbrev_base, | ||
100 | - dwarf_vma abbrev_size, | ||
101 | - dwarf_vma abbrev_offset, | ||
102 | - abbrev_list *list) | ||
103 | + unsigned char *start, | ||
104 | + unsigned char *end) | ||
105 | { | ||
106 | - if (abbrev_base >= section->size | ||
107 | - || abbrev_size > section->size - abbrev_base) | ||
108 | - { | ||
109 | - /* PR 17531: file:4bcd9ce9. */ | ||
110 | - warn (_("Debug info is corrupted, abbrev size (%lx) is larger than " | ||
111 | - "abbrev section size (%lx)\n"), | ||
112 | - (unsigned long) (abbrev_base + abbrev_size), | ||
113 | - (unsigned long) section->size); | ||
114 | - return NULL; | ||
115 | - } | ||
116 | - if (abbrev_offset >= abbrev_size) | ||
117 | - { | ||
118 | - warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than " | ||
119 | - "abbrev section size (%lx)\n"), | ||
120 | - (unsigned long) abbrev_offset, | ||
121 | - (unsigned long) abbrev_size); | ||
122 | - return NULL; | ||
123 | - } | ||
124 | + abbrev_list *list = xmalloc (sizeof (*list)); | ||
125 | + list->first_abbrev = NULL; | ||
126 | + list->last_abbrev = NULL; | ||
127 | |||
128 | - unsigned char *start = section->start + abbrev_base; | ||
129 | - unsigned char *end = start + abbrev_size; | ||
130 | - start += abbrev_offset; | ||
131 | while (start < end) | ||
132 | { | ||
133 | unsigned long entry; | ||
134 | @@ -1079,14 +1050,18 @@ process_abbrev_set (struct dwarf_section | ||
135 | /* A single zero is supposed to end the set according | ||
136 | to the standard. If there's more, then signal that to | ||
137 | the caller. */ | ||
138 | - if (start == end) | ||
139 | - return NULL; | ||
140 | - if (entry == 0) | ||
141 | - return start; | ||
142 | + if (start == end || entry == 0) | ||
143 | + { | ||
144 | + list->start_of_next_abbrevs = start != end ? start : NULL; | ||
145 | + return list; | ||
146 | + } | ||
147 | |||
148 | READ_ULEB (tag, start, end); | ||
149 | if (start == end) | ||
150 | - return NULL; | ||
151 | + { | ||
152 | + free (list); | ||
153 | + return NULL; | ||
154 | + } | ||
155 | |||
156 | children = *start++; | ||
157 | |||
158 | @@ -1121,9 +1096,67 @@ process_abbrev_set (struct dwarf_section | ||
159 | /* Report the missing single zero which ends the section. */ | ||
160 | error (_(".debug_abbrev section not zero terminated\n")); | ||
161 | |||
162 | + free (list); | ||
163 | return NULL; | ||
164 | } | ||
165 | |||
166 | +/* Return a sequence of abbrevs in SECTION starting at ABBREV_BASE | ||
167 | + plus ABBREV_OFFSET and finishing at ABBREV_BASE + ABBREV_SIZE. | ||
168 | + If FREE_LIST is non-NULL search the already decoded abbrevs on | ||
169 | + abbrev_lists first and if found set *FREE_LIST to NULL. If | ||
170 | + searching doesn't find a matching abbrev, set *FREE_LIST to the | ||
171 | + newly allocated list. If FREE_LIST is NULL, no search is done and | ||
172 | + the returned abbrev_list is always newly allocated. */ | ||
173 | + | ||
174 | +static abbrev_list * | ||
175 | +find_and_process_abbrev_set (struct dwarf_section *section, | ||
176 | + dwarf_vma abbrev_base, | ||
177 | + dwarf_vma abbrev_size, | ||
178 | + dwarf_vma abbrev_offset, | ||
179 | + abbrev_list **free_list) | ||
180 | +{ | ||
181 | + if (free_list) | ||
182 | + *free_list = NULL; | ||
183 | + | ||
184 | + if (abbrev_base >= section->size | ||
185 | + || abbrev_size > section->size - abbrev_base) | ||
186 | + { | ||
187 | + /* PR 17531: file:4bcd9ce9. */ | ||
188 | + warn (_("Debug info is corrupted, abbrev size (%lx) is larger than " | ||
189 | + "abbrev section size (%lx)\n"), | ||
190 | + (unsigned long) (abbrev_base + abbrev_size), | ||
191 | + (unsigned long) section->size); | ||
192 | + return NULL; | ||
193 | + } | ||
194 | + if (abbrev_offset >= abbrev_size) | ||
195 | + { | ||
196 | + warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than " | ||
197 | + "abbrev section size (%lx)\n"), | ||
198 | + (unsigned long) abbrev_offset, | ||
199 | + (unsigned long) abbrev_size); | ||
200 | + return NULL; | ||
201 | + } | ||
202 | + | ||
203 | + unsigned char *start = section->start + abbrev_base + abbrev_offset; | ||
204 | + unsigned char *end = section->start + abbrev_base + abbrev_size; | ||
205 | + abbrev_list *list = NULL; | ||
206 | + if (free_list) | ||
207 | + list = find_abbrev_list_by_abbrev_offset (abbrev_base, abbrev_offset); | ||
208 | + if (list == NULL) | ||
209 | + { | ||
210 | + list = process_abbrev_set (section, start, end); | ||
211 | + if (list) | ||
212 | + { | ||
213 | + list->abbrev_base = abbrev_base; | ||
214 | + list->abbrev_offset = abbrev_offset; | ||
215 | + list->next = NULL; | ||
216 | + } | ||
217 | + if (free_list) | ||
218 | + *free_list = list; | ||
219 | + } | ||
220 | + return list; | ||
221 | +} | ||
222 | + | ||
223 | static const char * | ||
224 | get_TAG_name (unsigned long tag) | ||
225 | { | ||
226 | @@ -3670,7 +3703,6 @@ process_debug_info (struct dwarf_section | ||
227 | dwarf_vma cu_offset; | ||
228 | unsigned int offset_size; | ||
229 | struct cu_tu_set * this_set; | ||
230 | - abbrev_list * list; | ||
231 | unsigned char *end_cu; | ||
232 | |||
233 | hdrptr = start; | ||
234 | @@ -3726,22 +3758,18 @@ process_debug_info (struct dwarf_section | ||
235 | abbrev_size = this_set->section_sizes [DW_SECT_ABBREV]; | ||
236 | } | ||
237 | |||
238 | - list = find_abbrev_list_by_abbrev_offset (abbrev_base, | ||
239 | - compunit.cu_abbrev_offset); | ||
240 | - if (list == NULL) | ||
241 | - { | ||
242 | - unsigned char * next; | ||
243 | - | ||
244 | - list = new_abbrev_list (abbrev_base, | ||
245 | - compunit.cu_abbrev_offset); | ||
246 | - next = process_abbrev_set (&debug_displays[abbrev_sec].section, | ||
247 | - abbrev_base, abbrev_size, | ||
248 | - compunit.cu_abbrev_offset, list); | ||
249 | - list->start_of_next_abbrevs = next; | ||
250 | - } | ||
251 | - | ||
252 | + abbrev_list *list; | ||
253 | + abbrev_list *free_list; | ||
254 | + list = find_and_process_abbrev_set (&debug_displays[abbrev_sec].section, | ||
255 | + abbrev_base, abbrev_size, | ||
256 | + compunit.cu_abbrev_offset, | ||
257 | + &free_list); | ||
258 | start = end_cu; | ||
259 | - record_abbrev_list_for_cu (cu_offset, start - section_begin, list); | ||
260 | + if (list != NULL && list->first_abbrev != NULL) | ||
261 | + record_abbrev_list_for_cu (cu_offset, start - section_begin, | ||
262 | + list, free_list); | ||
263 | + else if (free_list != NULL) | ||
264 | + free_abbrev_list (free_list); | ||
265 | } | ||
266 | |||
267 | for (start = section_begin, unit = 0; start < end; unit++) | ||
268 | @@ -3757,7 +3785,6 @@ process_debug_info (struct dwarf_section | ||
269 | struct cu_tu_set *this_set; | ||
270 | dwarf_vma abbrev_base; | ||
271 | size_t abbrev_size; | ||
272 | - abbrev_list * list = NULL; | ||
273 | unsigned char *end_cu; | ||
274 | |||
275 | hdrptr = start; | ||
276 | @@ -3936,20 +3963,10 @@ process_debug_info (struct dwarf_section | ||
277 | } | ||
278 | |||
279 | /* Process the abbrevs used by this compilation unit. */ | ||
280 | - list = find_abbrev_list_by_abbrev_offset (abbrev_base, | ||
281 | - compunit.cu_abbrev_offset); | ||
282 | - if (list == NULL) | ||
283 | - { | ||
284 | - unsigned char *next; | ||
285 | - | ||
286 | - list = new_abbrev_list (abbrev_base, | ||
287 | - compunit.cu_abbrev_offset); | ||
288 | - next = process_abbrev_set (&debug_displays[abbrev_sec].section, | ||
289 | - abbrev_base, abbrev_size, | ||
290 | - compunit.cu_abbrev_offset, list); | ||
291 | - list->start_of_next_abbrevs = next; | ||
292 | - } | ||
293 | - | ||
294 | + abbrev_list *list; | ||
295 | + list = find_and_process_abbrev_set (&debug_displays[abbrev_sec].section, | ||
296 | + abbrev_base, abbrev_size, | ||
297 | + compunit.cu_abbrev_offset, NULL); | ||
298 | level = 0; | ||
299 | last_level = level; | ||
300 | saved_level = -1; | ||
301 | @@ -4128,6 +4145,8 @@ process_debug_info (struct dwarf_section | ||
302 | if (entry->children) | ||
303 | ++level; | ||
304 | } | ||
305 | + if (list != NULL) | ||
306 | + free_abbrev_list (list); | ||
307 | } | ||
308 | |||
309 | /* Set num_debug_info_entries here so that it can be used to check if | ||
310 | @@ -6353,24 +6372,15 @@ display_debug_abbrev (struct dwarf_secti | ||
311 | |||
312 | do | ||
313 | { | ||
314 | - abbrev_list * list; | ||
315 | - dwarf_vma offset; | ||
316 | - | ||
317 | - offset = start - section->start; | ||
318 | - list = find_abbrev_list_by_abbrev_offset (0, offset); | ||
319 | + dwarf_vma offset = start - section->start; | ||
320 | + abbrev_list *list = find_and_process_abbrev_set (section, 0, | ||
321 | + section->size, offset, | ||
322 | + NULL); | ||
323 | if (list == NULL) | ||
324 | - { | ||
325 | - list = new_abbrev_list (0, offset); | ||
326 | - start = process_abbrev_set (section, 0, section->size, offset, list); | ||
327 | - list->start_of_next_abbrevs = start; | ||
328 | - } | ||
329 | - else | ||
330 | - start = list->start_of_next_abbrevs; | ||
331 | - | ||
332 | - if (list->first_abbrev == NULL) | ||
333 | - continue; | ||
334 | + break; | ||
335 | |||
336 | - printf (_(" Number TAG (0x%lx)\n"), (long) offset); | ||
337 | + if (list->first_abbrev) | ||
338 | + printf (_(" Number TAG (0x%lx)\n"), (long) offset); | ||
339 | |||
340 | for (entry = list->first_abbrev; entry; entry = entry->next) | ||
341 | { | ||
342 | @@ -6391,6 +6401,8 @@ display_debug_abbrev (struct dwarf_secti | ||
343 | putchar ('\n'); | ||
344 | } | ||
345 | } | ||
346 | + start = list->start_of_next_abbrevs; | ||
347 | + free_abbrev_list (list); | ||
348 | } | ||
349 | while (start); | ||
350 | |||
diff --git a/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-2.patch b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-2.patch new file mode 100644 index 0000000000..e30b4d86e1 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-2.patch | |||
@@ -0,0 +1,536 @@ | |||
1 | From 175b91507b83ad42607d2f6dadaf55b7b511bdbe Mon Sep 17 00:00:00 2001 | ||
2 | From: Alan Modra <amodra@gmail.com> | ||
3 | Date: Wed, 20 Jul 2022 18:28:50 +0930 | ||
4 | Subject: [PATCH] miscellaneous dwarf.c tidies | ||
5 | |||
6 | * dwarf.c: Leading and trailing whitespace fixes. | ||
7 | (free_abbrev_list): New function. | ||
8 | (free_all_abbrevs): Use the above. Free cu_abbrev_map here too. | ||
9 | (process_abbrev_set): Print actual section name on error. | ||
10 | (get_type_abbrev_from_form): Add overflow check. | ||
11 | (free_debug_memory): Don't free cu_abbrev_map here.. | ||
12 | (process_debug_info): ..or here. Warn on another case of not | ||
13 | finding a neeeded abbrev. | ||
14 | |||
15 | Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=175b91507b83ad42607d2f6dadaf55b7b511bdbe] | ||
16 | |||
17 | Signed-off-by: Pgowda <pgowda.cve@gmail.com> | ||
18 | --- | ||
19 | binutils/dwarf.c | 216 +++++++++++++++++++++++------------------------ | ||
20 | 1 file changed, 106 insertions(+), 110 deletions(-) | ||
21 | |||
22 | diff --git a/binutils/dwarf.c b/binutils/dwarf.c | ||
23 | index 2b1eec49422..267ed3bb382 100644 | ||
24 | --- a/binutils/dwarf.c | ||
25 | +++ b/binutils/dwarf.c | ||
26 | @@ -806,7 +806,7 @@ fetch_indexed_value (dwarf_vma idx, | ||
27 | pointer_size = 4; | ||
28 | bias = 12; | ||
29 | } | ||
30 | - | ||
31 | + | ||
32 | dwarf_vma offset = idx * pointer_size; | ||
33 | |||
34 | /* Offsets are biased by the size of the section header | ||
35 | @@ -908,38 +908,41 @@ record_abbrev_list_for_cu (dwarf_vma sta | ||
36 | next_free_abbrev_map_entry ++; | ||
37 | } | ||
38 | |||
39 | -static void | ||
40 | -free_all_abbrevs (void) | ||
41 | +static abbrev_list * | ||
42 | +free_abbrev_list (abbrev_list *list) | ||
43 | { | ||
44 | - abbrev_list * list; | ||
45 | + abbrev_entry *abbrv = list->first_abbrev; | ||
46 | |||
47 | - for (list = abbrev_lists; list != NULL;) | ||
48 | + while (abbrv) | ||
49 | { | ||
50 | - abbrev_list * next = list->next; | ||
51 | - abbrev_entry * abbrv; | ||
52 | + abbrev_attr *attr = abbrv->first_attr; | ||
53 | |||
54 | - for (abbrv = list->first_abbrev; abbrv != NULL;) | ||
55 | + while (attr) | ||
56 | { | ||
57 | - abbrev_entry * next_abbrev = abbrv->next; | ||
58 | - abbrev_attr * attr; | ||
59 | - | ||
60 | - for (attr = abbrv->first_attr; attr;) | ||
61 | - { | ||
62 | - abbrev_attr *next_attr = attr->next; | ||
63 | - | ||
64 | - free (attr); | ||
65 | - attr = next_attr; | ||
66 | - } | ||
67 | - | ||
68 | - free (abbrv); | ||
69 | - abbrv = next_abbrev; | ||
70 | + abbrev_attr *next_attr = attr->next; | ||
71 | + free (attr); | ||
72 | + attr = next_attr; | ||
73 | } | ||
74 | |||
75 | - free (list); | ||
76 | - list = next; | ||
77 | + abbrev_entry *next_abbrev = abbrv->next; | ||
78 | + free (abbrv); | ||
79 | + abbrv = next_abbrev; | ||
80 | } | ||
81 | |||
82 | - abbrev_lists = NULL; | ||
83 | + abbrev_list *next = list->next; | ||
84 | + free (list); | ||
85 | + return next; | ||
86 | +} | ||
87 | + | ||
88 | +static void | ||
89 | +free_all_abbrevs (void) | ||
90 | +{ | ||
91 | + while (abbrev_lists) | ||
92 | + abbrev_lists = free_abbrev_list (abbrev_lists); | ||
93 | + | ||
94 | + free (cu_abbrev_map); | ||
95 | + cu_abbrev_map = NULL; | ||
96 | + next_free_abbrev_map_entry = 0; | ||
97 | } | ||
98 | |||
99 | static abbrev_list * | ||
100 | @@ -971,7 +974,7 @@ find_abbrev_map_by_offset (dwarf_vma off | ||
101 | && cu_abbrev_map[i].end > offset) | ||
102 | return cu_abbrev_map + i; | ||
103 | |||
104 | - return NULL; | ||
105 | + return NULL; | ||
106 | } | ||
107 | |||
108 | static void | ||
109 | @@ -1094,7 +1097,7 @@ process_abbrev_set (struct dwarf_section | ||
110 | } | ||
111 | |||
112 | /* Report the missing single zero which ends the section. */ | ||
113 | - error (_(".debug_abbrev section not zero terminated\n")); | ||
114 | + error (_("%s section not zero terminated\n"), section->name); | ||
115 | |||
116 | free (list); | ||
117 | return NULL; | ||
118 | @@ -1875,7 +1878,7 @@ fetch_alt_indirect_string (dwarf_vma off | ||
119 | dwarf_vmatoa ("x", offset)); | ||
120 | return _("<offset is too big>"); | ||
121 | } | ||
122 | - | ||
123 | + | ||
124 | static const char * | ||
125 | get_AT_name (unsigned long attribute) | ||
126 | { | ||
127 | @@ -2157,7 +2160,8 @@ get_type_abbrev_from_form (unsigned long | ||
128 | case DW_FORM_ref4: | ||
129 | case DW_FORM_ref8: | ||
130 | case DW_FORM_ref_udata: | ||
131 | - if (uvalue + cu_offset > (size_t) (cu_end - section->start)) | ||
132 | + if (uvalue + cu_offset < uvalue | ||
133 | + || uvalue + cu_offset > (size_t) (cu_end - section->start)) | ||
134 | { | ||
135 | warn (_("Unable to resolve ref form: uvalue %lx + cu_offset %lx > CU size %lx\n"), | ||
136 | uvalue, (long) cu_offset, (long) (cu_end - section->start)); | ||
137 | @@ -2194,7 +2198,7 @@ get_type_abbrev_from_form (unsigned long | ||
138 | else | ||
139 | *map_return = NULL; | ||
140 | } | ||
141 | - | ||
142 | + | ||
143 | READ_ULEB (abbrev_number, data, section->start + section->size); | ||
144 | |||
145 | for (entry = map->list->first_abbrev; entry != NULL; entry = entry->next) | ||
146 | @@ -2783,10 +2787,10 @@ read_and_display_attr_value (unsigned lo | ||
147 | if (form == DW_FORM_loclistx) | ||
148 | { | ||
149 | if (dwo) | ||
150 | - { | ||
151 | - index = fetch_indexed_value (uvalue, loclists_dwo, 0); | ||
152 | - index += (offset_size == 8) ? 20 : 12; | ||
153 | - } | ||
154 | + { | ||
155 | + index = fetch_indexed_value (uvalue, loclists_dwo, 0); | ||
156 | + index += (offset_size == 8) ? 20 : 12; | ||
157 | + } | ||
158 | else if (debug_info_p == NULL) | ||
159 | { | ||
160 | index = fetch_indexed_value (uvalue, loclists, 0); | ||
161 | @@ -2804,21 +2808,21 @@ read_and_display_attr_value (unsigned lo | ||
162 | else if (form == DW_FORM_rnglistx) | ||
163 | { | ||
164 | if (dwo) | ||
165 | - { | ||
166 | - index = fetch_indexed_value (uvalue, rnglists_dwo, 0); | ||
167 | - index += (offset_size == 8) ? 20 : 12; | ||
168 | - } | ||
169 | + { | ||
170 | + index = fetch_indexed_value (uvalue, rnglists_dwo, 0); | ||
171 | + index += (offset_size == 8) ? 20 : 12; | ||
172 | + } | ||
173 | else | ||
174 | - { | ||
175 | - if (debug_info_p == NULL) | ||
176 | - base = 0; | ||
177 | - else | ||
178 | - base = debug_info_p->rnglists_base; | ||
179 | - /* We do not have a cached value this time, so we perform the | ||
180 | - computation manually. */ | ||
181 | - index = fetch_indexed_value (uvalue, rnglists, base); | ||
182 | - index += base; | ||
183 | - } | ||
184 | + { | ||
185 | + if (debug_info_p == NULL) | ||
186 | + base = 0; | ||
187 | + else | ||
188 | + base = debug_info_p->rnglists_base; | ||
189 | + /* We do not have a cached value this time, so we perform the | ||
190 | + computation manually. */ | ||
191 | + index = fetch_indexed_value (uvalue, rnglists, base); | ||
192 | + index += base; | ||
193 | + } | ||
194 | } | ||
195 | else | ||
196 | { | ||
197 | @@ -2844,7 +2848,7 @@ read_and_display_attr_value (unsigned lo | ||
198 | if (!do_loc) | ||
199 | printf ("%c<0x%s>", delimiter, dwarf_vmatoa ("x", uvalue + cu_offset)); | ||
200 | break; | ||
201 | - | ||
202 | + | ||
203 | default: | ||
204 | warn (_("Unrecognized form: 0x%lx\n"), form); | ||
205 | /* What to do? Consume a byte maybe? */ | ||
206 | @@ -2869,9 +2873,9 @@ read_and_display_attr_value (unsigned lo | ||
207 | case DW_AT_rnglists_base: | ||
208 | if (debug_info_p->rnglists_base) | ||
209 | warn (_("CU @ 0x%s has multiple rnglists_base values (0x%s and 0x%s)"), | ||
210 | - dwarf_vmatoa ("x", debug_info_p->cu_offset), | ||
211 | - dwarf_vmatoa ("x", debug_info_p->rnglists_base), | ||
212 | - dwarf_vmatoa ("x", uvalue)); | ||
213 | + dwarf_vmatoa ("x", debug_info_p->cu_offset), | ||
214 | + dwarf_vmatoa ("x", debug_info_p->rnglists_base), | ||
215 | + dwarf_vmatoa ("x", uvalue)); | ||
216 | debug_info_p->rnglists_base = uvalue; | ||
217 | break; | ||
218 | case DW_AT_str_offsets_base: | ||
219 | @@ -3021,7 +3025,7 @@ read_and_display_attr_value (unsigned lo | ||
220 | case DW_FORM_strx3: | ||
221 | case DW_FORM_strx4: | ||
222 | add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, false, | ||
223 | - debug_info_p->str_offsets_base), | ||
224 | + debug_info_p->str_offsets_base), | ||
225 | cu_offset); | ||
226 | break; | ||
227 | case DW_FORM_string: | ||
228 | @@ -3055,7 +3059,7 @@ read_and_display_attr_value (unsigned lo | ||
229 | case DW_FORM_strx3: | ||
230 | case DW_FORM_strx4: | ||
231 | add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, false, | ||
232 | - debug_info_p->str_offsets_base), | ||
233 | + debug_info_p->str_offsets_base), | ||
234 | cu_offset); | ||
235 | break; | ||
236 | case DW_FORM_string: | ||
237 | @@ -3686,11 +3690,8 @@ process_debug_info (struct dwarf_section | ||
238 | introduce (section, false); | ||
239 | |||
240 | free_all_abbrevs (); | ||
241 | - free (cu_abbrev_map); | ||
242 | - cu_abbrev_map = NULL; | ||
243 | - next_free_abbrev_map_entry = 0; | ||
244 | |||
245 | - /* In order to be able to resolve DW_FORM_ref_attr forms we need | ||
246 | + /* In order to be able to resolve DW_FORM_ref_addr forms we need | ||
247 | to load *all* of the abbrevs for all CUs in this .debug_info | ||
248 | section. This does effectively mean that we (partially) read | ||
249 | every CU header twice. */ | ||
250 | @@ -4045,12 +4046,11 @@ process_debug_info (struct dwarf_section | ||
251 | |||
252 | /* Scan through the abbreviation list until we reach the | ||
253 | correct entry. */ | ||
254 | - if (list == NULL) | ||
255 | - continue; | ||
256 | - | ||
257 | - for (entry = list->first_abbrev; entry != NULL; entry = entry->next) | ||
258 | - if (entry->number == abbrev_number) | ||
259 | - break; | ||
260 | + entry = NULL; | ||
261 | + if (list != NULL) | ||
262 | + for (entry = list->first_abbrev; entry != NULL; entry = entry->next) | ||
263 | + if (entry->number == abbrev_number) | ||
264 | + break; | ||
265 | |||
266 | if (entry == NULL) | ||
267 | { | ||
268 | @@ -4074,7 +4074,7 @@ process_debug_info (struct dwarf_section | ||
269 | break; | ||
270 | case DW_TAG_compile_unit: | ||
271 | case DW_TAG_skeleton_unit: | ||
272 | - need_base_address = 1; | ||
273 | + need_base_address = 1; | ||
274 | need_dwo_info = do_loc; | ||
275 | break; | ||
276 | case DW_TAG_entry_point: | ||
277 | @@ -4459,7 +4459,7 @@ display_debug_sup (struct dwarf_section | ||
278 | |||
279 | SAFE_BYTE_GET_AND_INC (is_supplementary, start, 1, end); | ||
280 | if (is_supplementary != 0 && is_supplementary != 1) | ||
281 | - warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n")); | ||
282 | + warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n")); | ||
283 | |||
284 | sup_filename = start; | ||
285 | if (is_supplementary && sup_filename[0] != 0) | ||
286 | @@ -5638,7 +5638,7 @@ display_debug_lines_decoded (struct dwar | ||
287 | printf ("%s %11d %#18" DWARF_VMA_FMT "x", | ||
288 | newFileName, state_machine_regs.line, | ||
289 | state_machine_regs.address); | ||
290 | - } | ||
291 | + } | ||
292 | else | ||
293 | { | ||
294 | if (xop == -DW_LNE_end_sequence) | ||
295 | @@ -6092,7 +6092,7 @@ display_debug_macro (struct dwarf_sectio | ||
296 | load_debug_section_with_follow (str, file); | ||
297 | load_debug_section_with_follow (line, file); | ||
298 | load_debug_section_with_follow (str_index, file); | ||
299 | - | ||
300 | + | ||
301 | introduce (section, false); | ||
302 | |||
303 | while (curr < end) | ||
304 | @@ -6537,7 +6537,7 @@ display_loc_list (struct dwarf_section * | ||
305 | |||
306 | /* Check base address specifiers. */ | ||
307 | if (is_max_address (begin, pointer_size) | ||
308 | - && !is_max_address (end, pointer_size)) | ||
309 | + && !is_max_address (end, pointer_size)) | ||
310 | { | ||
311 | base_address = end; | ||
312 | print_dwarf_vma (begin, pointer_size); | ||
313 | @@ -6715,7 +6715,7 @@ display_loclists_list (struct dwarf_sect | ||
314 | case DW_LLE_default_location: | ||
315 | begin = end = 0; | ||
316 | break; | ||
317 | - | ||
318 | + | ||
319 | case DW_LLE_offset_pair: | ||
320 | READ_ULEB (begin, start, section_end); | ||
321 | begin += base_address; | ||
322 | @@ -7011,7 +7011,7 @@ display_offset_entry_loclists (struct dw | ||
323 | unsigned char * start = section->start; | ||
324 | unsigned char * const end = start + section->size; | ||
325 | |||
326 | - introduce (section, false); | ||
327 | + introduce (section, false); | ||
328 | |||
329 | do | ||
330 | { | ||
331 | @@ -7060,14 +7060,14 @@ display_offset_entry_loclists (struct dw | ||
332 | section->name, segment_selector_size); | ||
333 | return 0; | ||
334 | } | ||
335 | - | ||
336 | + | ||
337 | if (offset_entry_count == 0) | ||
338 | { | ||
339 | warn (_("The %s section contains a table without offset\n"), | ||
340 | section->name); | ||
341 | return 0; | ||
342 | } | ||
343 | - | ||
344 | + | ||
345 | printf (_("\n Offset Entries starting at 0x%lx:\n"), | ||
346 | (long)(start - section->start)); | ||
347 | |||
348 | @@ -8229,7 +8229,7 @@ display_debug_rnglists (struct dwarf_sec | ||
349 | start = display_debug_rnglists_list | ||
350 | (start, end, address_size, offset, 0, offset_size); | ||
351 | if (start >= end) | ||
352 | - break; | ||
353 | + break; | ||
354 | } | ||
355 | |||
356 | start = end; | ||
357 | @@ -8347,12 +8347,12 @@ display_debug_ranges (struct dwarf_secti | ||
358 | next = section_begin + offset + debug_info_p->rnglists_base; | ||
359 | |||
360 | /* If multiple DWARF entities reference the same range then we will | ||
361 | - have multiple entries in the `range_entries' list for the same | ||
362 | - offset. Thanks to the sort above these will all be consecutive in | ||
363 | - the `range_entries' list, so we can easily ignore duplicates | ||
364 | - here. */ | ||
365 | + have multiple entries in the `range_entries' list for the same | ||
366 | + offset. Thanks to the sort above these will all be consecutive in | ||
367 | + the `range_entries' list, so we can easily ignore duplicates | ||
368 | + here. */ | ||
369 | if (i > 0 && last_offset == offset) | ||
370 | - continue; | ||
371 | + continue; | ||
372 | last_offset = offset; | ||
373 | |||
374 | if (dwarf_check != 0 && i > 0) | ||
375 | @@ -10286,7 +10286,7 @@ display_debug_names (struct dwarf_sectio | ||
376 | printf (_("Out of %lu items there are %zu bucket clashes" | ||
377 | " (longest of %zu entries).\n"), | ||
378 | (unsigned long) name_count, hash_clash_count, longest_clash); | ||
379 | - | ||
380 | + | ||
381 | if (name_count != buckets_filled + hash_clash_count) | ||
382 | warn (_("The name_count (%lu) is not the same as the used bucket_count (%lu) + the hash clash count (%lu)"), | ||
383 | (unsigned long) name_count, | ||
384 | @@ -10390,7 +10390,7 @@ display_debug_names (struct dwarf_sectio | ||
385 | break; | ||
386 | if (tagno >= 0) | ||
387 | printf ("%s<%lu>", | ||
388 | - (tagno == 0 && second_abbrev_tag == 0 ? " " : "\n\t"), | ||
389 | + (tagno == 0 && second_abbrev_tag == 0 ? " " : "\n\t"), | ||
390 | (unsigned long) abbrev_tag); | ||
391 | |||
392 | for (entry = abbrev_lookup; | ||
393 | @@ -10919,7 +10919,7 @@ process_cu_tu_index (struct dwarf_sectio | ||
394 | Check for integer overflow (can occur when size_t is 32-bit) | ||
395 | with overlarge ncols or nused values. */ | ||
396 | if (nused == -1u | ||
397 | - || _mul_overflow ((size_t) ncols, 4, &temp) | ||
398 | + || _mul_overflow ((size_t) ncols, 4, &temp) | ||
399 | || _mul_overflow ((size_t) nused + 1, temp, &total) | ||
400 | || total > (size_t) (limit - ppool)) | ||
401 | { | ||
402 | @@ -10927,7 +10927,7 @@ process_cu_tu_index (struct dwarf_sectio | ||
403 | section->name); | ||
404 | return 0; | ||
405 | } | ||
406 | - | ||
407 | + | ||
408 | if (do_display) | ||
409 | { | ||
410 | printf (_(" Offset table\n")); | ||
411 | @@ -11431,8 +11431,8 @@ add_separate_debug_file (const char * fi | ||
412 | |||
413 | static bool | ||
414 | debuginfod_fetch_separate_debug_info (struct dwarf_section * section, | ||
415 | - char ** filename, | ||
416 | - void * file) | ||
417 | + char ** filename, | ||
418 | + void * file) | ||
419 | { | ||
420 | size_t build_id_len; | ||
421 | unsigned char * build_id; | ||
422 | @@ -11450,14 +11450,14 @@ debuginfod_fetch_separate_debug_info (st | ||
423 | |||
424 | filelen = strnlen ((const char *)section->start, section->size); | ||
425 | if (filelen == section->size) | ||
426 | - /* Corrupt debugaltlink. */ | ||
427 | - return false; | ||
428 | + /* Corrupt debugaltlink. */ | ||
429 | + return false; | ||
430 | |||
431 | build_id = section->start + filelen + 1; | ||
432 | build_id_len = section->size - (filelen + 1); | ||
433 | |||
434 | if (build_id_len == 0) | ||
435 | - return false; | ||
436 | + return false; | ||
437 | } | ||
438 | else | ||
439 | return false; | ||
440 | @@ -11469,25 +11469,25 @@ debuginfod_fetch_separate_debug_info (st | ||
441 | |||
442 | client = debuginfod_begin (); | ||
443 | if (client == NULL) | ||
444 | - return false; | ||
445 | + return false; | ||
446 | |||
447 | /* Query debuginfod servers for the target file. If found its path | ||
448 | - will be stored in filename. */ | ||
449 | + will be stored in filename. */ | ||
450 | fd = debuginfod_find_debuginfo (client, build_id, build_id_len, filename); | ||
451 | debuginfod_end (client); | ||
452 | |||
453 | /* Only free build_id if we allocated space for a hex string | ||
454 | - in get_build_id (). */ | ||
455 | + in get_build_id (). */ | ||
456 | if (build_id_len == 0) | ||
457 | - free (build_id); | ||
458 | + free (build_id); | ||
459 | |||
460 | if (fd >= 0) | ||
461 | - { | ||
462 | - /* File successfully retrieved. Close fd since we want to | ||
463 | - use open_debug_file () on filename instead. */ | ||
464 | - close (fd); | ||
465 | - return true; | ||
466 | - } | ||
467 | + { | ||
468 | + /* File successfully retrieved. Close fd since we want to | ||
469 | + use open_debug_file () on filename instead. */ | ||
470 | + close (fd); | ||
471 | + return true; | ||
472 | + } | ||
473 | } | ||
474 | |||
475 | return false; | ||
476 | @@ -11500,7 +11500,7 @@ load_separate_debug_info (const char * | ||
477 | parse_func_type parse_func, | ||
478 | check_func_type check_func, | ||
479 | void * func_data, | ||
480 | - void * file ATTRIBUTE_UNUSED) | ||
481 | + void * file ATTRIBUTE_UNUSED) | ||
482 | { | ||
483 | const char * separate_filename; | ||
484 | char * debug_filename; | ||
485 | @@ -11616,11 +11616,11 @@ load_separate_debug_info (const char * | ||
486 | & tmp_filename, | ||
487 | file)) | ||
488 | { | ||
489 | - /* File successfully downloaded from server, replace | ||
490 | - debug_filename with the file's path. */ | ||
491 | - free (debug_filename); | ||
492 | - debug_filename = tmp_filename; | ||
493 | - goto found; | ||
494 | + /* File successfully downloaded from server, replace | ||
495 | + debug_filename with the file's path. */ | ||
496 | + free (debug_filename); | ||
497 | + debug_filename = tmp_filename; | ||
498 | + goto found; | ||
499 | } | ||
500 | } | ||
501 | #endif | ||
502 | @@ -11787,12 +11787,12 @@ load_build_id_debug_file (const char * m | ||
503 | /* In theory we should extract the contents of the section into | ||
504 | a note structure and then check the fields. For now though | ||
505 | just use hard coded offsets instead: | ||
506 | - | ||
507 | + | ||
508 | Field Bytes Contents | ||
509 | NSize 0...3 4 | ||
510 | DSize 4...7 8+ | ||
511 | Type 8..11 3 (NT_GNU_BUILD_ID) | ||
512 | - Name 12.15 GNU\0 | ||
513 | + Name 12.15 GNU\0 | ||
514 | Data 16.... */ | ||
515 | |||
516 | /* FIXME: Check the name size, name and type fields. */ | ||
517 | @@ -11804,7 +11804,7 @@ load_build_id_debug_file (const char * m | ||
518 | warn (_(".note.gnu.build-id data size is too small\n")); | ||
519 | return; | ||
520 | } | ||
521 | - | ||
522 | + | ||
523 | if (build_id_size > (section->size - 16)) | ||
524 | { | ||
525 | warn (_(".note.gnu.build-id data size is too bug\n")); | ||
526 | @@ -12100,10 +12100,6 @@ free_debug_memory (void) | ||
527 | |||
528 | free_all_abbrevs (); | ||
529 | |||
530 | - free (cu_abbrev_map); | ||
531 | - cu_abbrev_map = NULL; | ||
532 | - next_free_abbrev_map_entry = 0; | ||
533 | - | ||
534 | free (shndx_pool); | ||
535 | shndx_pool = NULL; | ||
536 | shndx_pool_size = 0; | ||
diff --git a/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-3.patch b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-3.patch new file mode 100644 index 0000000000..04d06ed6b6 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-3.patch | |||
@@ -0,0 +1,95 @@ | |||
1 | From 695c6dfe7e85006b98c8b746f3fd5f913c94ebff Mon Sep 17 00:00:00 2001 | ||
2 | From: Alan Modra <amodra@gmail.com> | ||
3 | Date: Thu, 21 Jul 2022 09:56:15 +0930 | ||
4 | Subject: [PATCH] PR29370, infinite loop in display_debug_abbrev | ||
5 | |||
6 | The PR29370 testcase is a fuzzed object file with multiple | ||
7 | .trace_abbrev sections. Multiple .trace_abbrev or .debug_abbrev | ||
8 | sections are not a violation of the DWARF standard. The DWARF5 | ||
9 | standard even gives an example of multiple .debug_abbrev sections | ||
10 | contained in groups. Caching and lookup of processed abbrevs thus | ||
11 | needs to be done by section and offset rather than base and offset. | ||
12 | (Why base anyway?) Or, since section contents are kept, by a pointer | ||
13 | into the contents. | ||
14 | |||
15 | PR 29370 | ||
16 | * dwarf.c (struct abbrev_list): Replace abbrev_base and | ||
17 | abbrev_offset with raw field. | ||
18 | (find_abbrev_list_by_abbrev_offset): Delete. | ||
19 | (find_abbrev_list_by_raw_abbrev): New function. | ||
20 | (process_abbrev_set): Set list->raw and list->next. | ||
21 | (find_and_process_abbrev_set): Replace abbrev list lookup with | ||
22 | new function. Don't set list abbrev_base, abbrev_offset or next. | ||
23 | |||
24 | Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=695c6dfe7e85006b98c8b746f3fd5f913c94ebff] | ||
25 | |||
26 | Signed-off-by: Pgowda <pgowda.cve@gmail.com> | ||
27 | --- | ||
28 | binutils/dwarf.c | 19 ++++++------------- | ||
29 | 1 file changed, 6 insertions(+), 13 deletions(-) | ||
30 | |||
31 | diff --git a/binutils/dwarf.c b/binutils/dwarf.c | ||
32 | index 2fc352f74c5..99fb3566994 100644 | ||
33 | --- a/binutils/dwarf.c | ||
34 | +++ b/binutils/dwarf.c | ||
35 | @@ -856,8 +856,7 @@ typedef struct abbrev_list | ||
36 | { | ||
37 | abbrev_entry * first_abbrev; | ||
38 | abbrev_entry * last_abbrev; | ||
39 | - dwarf_vma abbrev_base; | ||
40 | - dwarf_vma abbrev_offset; | ||
41 | + unsigned char * raw; | ||
42 | struct abbrev_list * next; | ||
43 | unsigned char * start_of_next_abbrevs; | ||
44 | } | ||
45 | @@ -946,14 +945,12 @@ free_all_abbrevs (void) | ||
46 | } | ||
47 | |||
48 | static abbrev_list * | ||
49 | -find_abbrev_list_by_abbrev_offset (dwarf_vma abbrev_base, | ||
50 | - dwarf_vma abbrev_offset) | ||
51 | +find_abbrev_list_by_raw_abbrev (unsigned char *raw) | ||
52 | { | ||
53 | abbrev_list * list; | ||
54 | |||
55 | for (list = abbrev_lists; list != NULL; list = list->next) | ||
56 | - if (list->abbrev_base == abbrev_base | ||
57 | - && list->abbrev_offset == abbrev_offset) | ||
58 | + if (list->raw == raw) | ||
59 | return list; | ||
60 | |||
61 | return NULL; | ||
62 | @@ -1040,6 +1037,7 @@ process_abbrev_set (struct dwarf_section | ||
63 | abbrev_list *list = xmalloc (sizeof (*list)); | ||
64 | list->first_abbrev = NULL; | ||
65 | list->last_abbrev = NULL; | ||
66 | + list->raw = start; | ||
67 | |||
68 | while (start < end) | ||
69 | { | ||
70 | @@ -1055,6 +1053,7 @@ process_abbrev_set (struct dwarf_section | ||
71 | the caller. */ | ||
72 | if (start == end || entry == 0) | ||
73 | { | ||
74 | + list->next = NULL; | ||
75 | list->start_of_next_abbrevs = start != end ? start : NULL; | ||
76 | return list; | ||
77 | } | ||
78 | @@ -1144,16 +1143,10 @@ find_and_process_abbrev_set (struct dwar | ||
79 | unsigned char *end = section->start + abbrev_base + abbrev_size; | ||
80 | abbrev_list *list = NULL; | ||
81 | if (free_list) | ||
82 | - list = find_abbrev_list_by_abbrev_offset (abbrev_base, abbrev_offset); | ||
83 | + list = find_abbrev_list_by_raw_abbrev (start); | ||
84 | if (list == NULL) | ||
85 | { | ||
86 | list = process_abbrev_set (section, start, end); | ||
87 | - if (list) | ||
88 | - { | ||
89 | - list->abbrev_base = abbrev_base; | ||
90 | - list->abbrev_offset = abbrev_offset; | ||
91 | - list->next = NULL; | ||
92 | - } | ||
93 | if (free_list) | ||
94 | *free_list = list; | ||
95 | } | ||