diff options
| author | pgowda <pgowda.cve@gmail.com> | 2022-10-13 13:17:26 +0530 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-10-20 15:36:01 +0100 |
| commit | 1b2fb9a1a5516c80fef079c38e42066d70984773 (patch) | |
| tree | 6758b1a0c360ebfc98a69e9070143608576ff1fc | |
| parent | 6d80584e9f095537b8d3a2e37db3feb7c608dd69 (diff) | |
| download | poky-1b2fb9a1a5516c80fef079c38e42066d70984773.tar.gz | |
binutils : Fix CVE-2022-38128
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=f07c08e115e27cddf5a0030dc6332bbee1bd9c6a]
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=175b91507b83ad42607d2f6dadaf55b7b511bdbe]
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=695c6dfe7e85006b98c8b746f3fd5f913c94ebff]
(From OE-Core rev: 21fb0b441096ec8b5cfa1d5b645f9a3a2ace1e09)
Signed-off-by: pgowda <pgowda.cve@gmail.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
4 files changed, 884 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.38.inc b/meta/recipes-devtools/binutils/binutils-2.38.inc index fc88d4a79e..8259ec3232 100644 --- a/meta/recipes-devtools/binutils/binutils-2.38.inc +++ b/meta/recipes-devtools/binutils/binutils-2.38.inc | |||
| @@ -39,5 +39,8 @@ SRC_URI = "\ | |||
| 39 | file://0017-CVE-2022-38127-2.patch \ | 39 | file://0017-CVE-2022-38127-2.patch \ |
| 40 | file://0017-CVE-2022-38127-3.patch \ | 40 | file://0017-CVE-2022-38127-3.patch \ |
| 41 | file://0017-CVE-2022-38127-4.patch \ | 41 | file://0017-CVE-2022-38127-4.patch \ |
| 42 | file://0018-CVE-2022-38128-1.patch \ | ||
| 43 | file://0018-CVE-2022-38128-2.patch \ | ||
| 44 | file://0018-CVE-2022-38128-3.patch \ | ||
| 42 | " | 45 | " |
| 43 | S = "${WORKDIR}/git" | 46 | S = "${WORKDIR}/git" |
diff --git a/meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-1.patch b/meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-1.patch new file mode 100644 index 0000000000..0a490d86b3 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0018-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/0018-CVE-2022-38128-2.patch b/meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-2.patch new file mode 100644 index 0000000000..b867b04e96 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-2.patch | |||
| @@ -0,0 +1,436 @@ | |||
| 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 | @@ -954,38 +954,41 @@ record_abbrev_list_for_cu (dwarf_vma sta | ||
| 27 | next_free_abbrev_map_entry ++; | ||
| 28 | } | ||
| 29 | |||
| 30 | -static void | ||
| 31 | -free_all_abbrevs (void) | ||
| 32 | +static abbrev_list * | ||
| 33 | +free_abbrev_list (abbrev_list *list) | ||
| 34 | { | ||
| 35 | - abbrev_list * list; | ||
| 36 | + abbrev_entry *abbrv = list->first_abbrev; | ||
| 37 | |||
| 38 | - for (list = abbrev_lists; list != NULL;) | ||
| 39 | + while (abbrv) | ||
| 40 | { | ||
| 41 | - abbrev_list * next = list->next; | ||
| 42 | - abbrev_entry * abbrv; | ||
| 43 | + abbrev_attr *attr = abbrv->first_attr; | ||
| 44 | |||
| 45 | - for (abbrv = list->first_abbrev; abbrv != NULL;) | ||
| 46 | + while (attr) | ||
| 47 | { | ||
| 48 | - abbrev_entry * next_abbrev = abbrv->next; | ||
| 49 | - abbrev_attr * attr; | ||
| 50 | - | ||
| 51 | - for (attr = abbrv->first_attr; attr;) | ||
| 52 | - { | ||
| 53 | - abbrev_attr *next_attr = attr->next; | ||
| 54 | - | ||
| 55 | - free (attr); | ||
| 56 | - attr = next_attr; | ||
| 57 | - } | ||
| 58 | - | ||
| 59 | - free (abbrv); | ||
| 60 | - abbrv = next_abbrev; | ||
| 61 | + abbrev_attr *next_attr = attr->next; | ||
| 62 | + free (attr); | ||
| 63 | + attr = next_attr; | ||
| 64 | } | ||
| 65 | |||
| 66 | - free (list); | ||
| 67 | - list = next; | ||
| 68 | + abbrev_entry *next_abbrev = abbrv->next; | ||
| 69 | + free (abbrv); | ||
| 70 | + abbrv = next_abbrev; | ||
| 71 | } | ||
| 72 | |||
| 73 | - abbrev_lists = NULL; | ||
| 74 | + abbrev_list *next = list->next; | ||
| 75 | + free (list); | ||
| 76 | + return next; | ||
| 77 | +} | ||
| 78 | + | ||
| 79 | +static void | ||
| 80 | +free_all_abbrevs (void) | ||
| 81 | +{ | ||
| 82 | + while (abbrev_lists) | ||
| 83 | + abbrev_lists = free_abbrev_list (abbrev_lists); | ||
| 84 | + | ||
| 85 | + free (cu_abbrev_map); | ||
| 86 | + cu_abbrev_map = NULL; | ||
| 87 | + next_free_abbrev_map_entry = 0; | ||
| 88 | } | ||
| 89 | |||
| 90 | static abbrev_list * | ||
| 91 | @@ -1017,7 +1020,7 @@ find_abbrev_map_by_offset (dwarf_vma off | ||
| 92 | && cu_abbrev_map[i].end > offset) | ||
| 93 | return cu_abbrev_map + i; | ||
| 94 | |||
| 95 | - return NULL; | ||
| 96 | + return NULL; | ||
| 97 | } | ||
| 98 | |||
| 99 | static void | ||
| 100 | @@ -1140,7 +1143,7 @@ process_abbrev_set (struct dwarf_section | ||
| 101 | } | ||
| 102 | |||
| 103 | /* Report the missing single zero which ends the section. */ | ||
| 104 | - error (_(".debug_abbrev section not zero terminated\n")); | ||
| 105 | + error (_("%s section not zero terminated\n"), section->name); | ||
| 106 | |||
| 107 | free (list); | ||
| 108 | return NULL; | ||
| 109 | @@ -1917,7 +1920,7 @@ fetch_alt_indirect_string (dwarf_vma off | ||
| 110 | dwarf_vmatoa ("x", offset)); | ||
| 111 | return _("<offset is too big>"); | ||
| 112 | } | ||
| 113 | - | ||
| 114 | + | ||
| 115 | static const char * | ||
| 116 | get_AT_name (unsigned long attribute) | ||
| 117 | { | ||
| 118 | @@ -2199,7 +2202,8 @@ get_type_abbrev_from_form (unsigned long | ||
| 119 | case DW_FORM_ref4: | ||
| 120 | case DW_FORM_ref8: | ||
| 121 | case DW_FORM_ref_udata: | ||
| 122 | - if (uvalue + cu_offset > (size_t) (cu_end - section->start)) | ||
| 123 | + if (uvalue + cu_offset < uvalue | ||
| 124 | + || uvalue + cu_offset > (size_t) (cu_end - section->start)) | ||
| 125 | { | ||
| 126 | warn (_("Unable to resolve ref form: uvalue %lx + cu_offset %lx > CU size %lx\n"), | ||
| 127 | uvalue, (long) cu_offset, (long) (cu_end - section->start)); | ||
| 128 | @@ -2236,7 +2240,7 @@ get_type_abbrev_from_form (unsigned long | ||
| 129 | else | ||
| 130 | *map_return = NULL; | ||
| 131 | } | ||
| 132 | - | ||
| 133 | + | ||
| 134 | READ_ULEB (abbrev_number, data, section->start + section->size); | ||
| 135 | |||
| 136 | for (entry = map->list->first_abbrev; entry != NULL; entry = entry->next) | ||
| 137 | @@ -2837,7 +2841,7 @@ read_and_display_attr_value (unsigned lo | ||
| 138 | if (!do_loc) | ||
| 139 | printf ("%c<0x%s>", delimiter, dwarf_vmatoa ("x", uvalue + cu_offset)); | ||
| 140 | break; | ||
| 141 | - | ||
| 142 | + | ||
| 143 | default: | ||
| 144 | warn (_("Unrecognized form: 0x%lx\n"), form); | ||
| 145 | /* What to do? Consume a byte maybe? */ | ||
| 146 | @@ -3009,7 +3013,7 @@ read_and_display_attr_value (unsigned lo | ||
| 147 | case DW_FORM_strx3: | ||
| 148 | case DW_FORM_strx4: | ||
| 149 | add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, false, | ||
| 150 | - debug_info_p->str_offsets_base), | ||
| 151 | + debug_info_p->str_offsets_base), | ||
| 152 | cu_offset); | ||
| 153 | break; | ||
| 154 | case DW_FORM_string: | ||
| 155 | @@ -3043,7 +3047,7 @@ read_and_display_attr_value (unsigned lo | ||
| 156 | case DW_FORM_strx3: | ||
| 157 | case DW_FORM_strx4: | ||
| 158 | add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, false, | ||
| 159 | - debug_info_p->str_offsets_base), | ||
| 160 | + debug_info_p->str_offsets_base), | ||
| 161 | cu_offset); | ||
| 162 | break; | ||
| 163 | case DW_FORM_string: | ||
| 164 | @@ -3671,11 +3675,8 @@ process_debug_info (struct dwarf_section | ||
| 165 | introduce (section, false); | ||
| 166 | |||
| 167 | free_all_abbrevs (); | ||
| 168 | - free (cu_abbrev_map); | ||
| 169 | - cu_abbrev_map = NULL; | ||
| 170 | - next_free_abbrev_map_entry = 0; | ||
| 171 | |||
| 172 | - /* In order to be able to resolve DW_FORM_ref_attr forms we need | ||
| 173 | + /* In order to be able to resolve DW_FORM_ref_addr forms we need | ||
| 174 | to load *all* of the abbrevs for all CUs in this .debug_info | ||
| 175 | section. This does effectively mean that we (partially) read | ||
| 176 | every CU header twice. */ | ||
| 177 | @@ -4029,12 +4030,11 @@ process_debug_info (struct dwarf_section | ||
| 178 | |||
| 179 | /* Scan through the abbreviation list until we reach the | ||
| 180 | correct entry. */ | ||
| 181 | - if (list == NULL) | ||
| 182 | - continue; | ||
| 183 | - | ||
| 184 | - for (entry = list->first_abbrev; entry != NULL; entry = entry->next) | ||
| 185 | - if (entry->number == abbrev_number) | ||
| 186 | - break; | ||
| 187 | + entry = NULL; | ||
| 188 | + if (list != NULL) | ||
| 189 | + for (entry = list->first_abbrev; entry != NULL; entry = entry->next) | ||
| 190 | + if (entry->number == abbrev_number) | ||
| 191 | + break; | ||
| 192 | |||
| 193 | if (entry == NULL) | ||
| 194 | { | ||
| 195 | @@ -4442,7 +4442,7 @@ display_debug_sup (struct dwarf_section | ||
| 196 | |||
| 197 | SAFE_BYTE_GET_AND_INC (is_supplementary, start, 1, end); | ||
| 198 | if (is_supplementary != 0 && is_supplementary != 1) | ||
| 199 | - warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n")); | ||
| 200 | + warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n")); | ||
| 201 | |||
| 202 | sup_filename = start; | ||
| 203 | if (is_supplementary && sup_filename[0] != 0) | ||
| 204 | @@ -5621,7 +5621,7 @@ display_debug_lines_decoded (struct dwar | ||
| 205 | printf ("%s %11d %#18" DWARF_VMA_FMT "x", | ||
| 206 | newFileName, state_machine_regs.line, | ||
| 207 | state_machine_regs.address); | ||
| 208 | - } | ||
| 209 | + } | ||
| 210 | else | ||
| 211 | { | ||
| 212 | if (xop == -DW_LNE_end_sequence) | ||
| 213 | @@ -6075,7 +6075,7 @@ display_debug_macro (struct dwarf_sectio | ||
| 214 | load_debug_section_with_follow (str, file); | ||
| 215 | load_debug_section_with_follow (line, file); | ||
| 216 | load_debug_section_with_follow (str_index, file); | ||
| 217 | - | ||
| 218 | + | ||
| 219 | introduce (section, false); | ||
| 220 | |||
| 221 | while (curr < end) | ||
| 222 | @@ -6519,7 +6519,7 @@ display_loc_list (struct dwarf_section * | ||
| 223 | |||
| 224 | /* Check base address specifiers. */ | ||
| 225 | if (is_max_address (begin, pointer_size) | ||
| 226 | - && !is_max_address (end, pointer_size)) | ||
| 227 | + && !is_max_address (end, pointer_size)) | ||
| 228 | { | ||
| 229 | base_address = end; | ||
| 230 | print_dwarf_vma (begin, pointer_size); | ||
| 231 | @@ -6697,7 +6697,7 @@ display_loclists_list (struct dwarf_sect | ||
| 232 | case DW_LLE_default_location: | ||
| 233 | begin = end = 0; | ||
| 234 | break; | ||
| 235 | - | ||
| 236 | + | ||
| 237 | case DW_LLE_offset_pair: | ||
| 238 | READ_ULEB (begin, start, section_end); | ||
| 239 | begin += base_address; | ||
| 240 | @@ -6993,7 +6993,7 @@ display_offset_entry_loclists (struct dw | ||
| 241 | unsigned char * start = section->start; | ||
| 242 | unsigned char * const end = start + section->size; | ||
| 243 | |||
| 244 | - introduce (section, false); | ||
| 245 | + introduce (section, false); | ||
| 246 | |||
| 247 | do | ||
| 248 | { | ||
| 249 | @@ -7042,14 +7042,14 @@ display_offset_entry_loclists (struct dw | ||
| 250 | section->name, segment_selector_size); | ||
| 251 | return 0; | ||
| 252 | } | ||
| 253 | - | ||
| 254 | + | ||
| 255 | if (offset_entry_count == 0) | ||
| 256 | { | ||
| 257 | warn (_("The %s section contains a table without offset\n"), | ||
| 258 | section->name); | ||
| 259 | return 0; | ||
| 260 | } | ||
| 261 | - | ||
| 262 | + | ||
| 263 | printf (_("\n Offset Entries starting at 0x%lx:\n"), | ||
| 264 | (long)(start - section->start)); | ||
| 265 | |||
| 266 | @@ -8295,12 +8295,12 @@ display_debug_ranges (struct dwarf_secti | ||
| 267 | next = section_begin + offset + debug_info_p->rnglists_base; | ||
| 268 | |||
| 269 | /* If multiple DWARF entities reference the same range then we will | ||
| 270 | - have multiple entries in the `range_entries' list for the same | ||
| 271 | - offset. Thanks to the sort above these will all be consecutive in | ||
| 272 | - the `range_entries' list, so we can easily ignore duplicates | ||
| 273 | - here. */ | ||
| 274 | + have multiple entries in the `range_entries' list for the same | ||
| 275 | + offset. Thanks to the sort above these will all be consecutive in | ||
| 276 | + the `range_entries' list, so we can easily ignore duplicates | ||
| 277 | + here. */ | ||
| 278 | if (i > 0 && last_offset == offset) | ||
| 279 | - continue; | ||
| 280 | + continue; | ||
| 281 | last_offset = offset; | ||
| 282 | |||
| 283 | if (dwarf_check != 0 && i > 0) | ||
| 284 | @@ -10336,7 +10336,7 @@ display_debug_names (struct dwarf_sectio | ||
| 285 | break; | ||
| 286 | if (tagno >= 0) | ||
| 287 | printf ("%s<%lu>", | ||
| 288 | - (tagno == 0 && second_abbrev_tag == 0 ? " " : "\n\t"), | ||
| 289 | + (tagno == 0 && second_abbrev_tag == 0 ? " " : "\n\t"), | ||
| 290 | (unsigned long) abbrev_tag); | ||
| 291 | |||
| 292 | for (entry = abbrev_lookup; | ||
| 293 | @@ -10901,7 +10901,7 @@ process_cu_tu_index (struct dwarf_sectio | ||
| 294 | Check for integer overflow (can occur when size_t is 32-bit) | ||
| 295 | with overlarge ncols or nused values. */ | ||
| 296 | if (nused == -1u | ||
| 297 | - || _mul_overflow ((size_t) ncols, 4, &temp) | ||
| 298 | + || _mul_overflow ((size_t) ncols, 4, &temp) | ||
| 299 | || _mul_overflow ((size_t) nused + 1, temp, &total) | ||
| 300 | || total > (size_t) (limit - ppool)) | ||
| 301 | { | ||
| 302 | @@ -10909,7 +10909,7 @@ process_cu_tu_index (struct dwarf_sectio | ||
| 303 | section->name); | ||
| 304 | return 0; | ||
| 305 | } | ||
| 306 | - | ||
| 307 | + | ||
| 308 | if (do_display) | ||
| 309 | { | ||
| 310 | printf (_(" Offset table\n")); | ||
| 311 | @@ -11413,8 +11413,8 @@ add_separate_debug_file (const char * fi | ||
| 312 | |||
| 313 | static bool | ||
| 314 | debuginfod_fetch_separate_debug_info (struct dwarf_section * section, | ||
| 315 | - char ** filename, | ||
| 316 | - void * file) | ||
| 317 | + char ** filename, | ||
| 318 | + void * file) | ||
| 319 | { | ||
| 320 | size_t build_id_len; | ||
| 321 | unsigned char * build_id; | ||
| 322 | @@ -11432,14 +11432,14 @@ debuginfod_fetch_separate_debug_info (st | ||
| 323 | |||
| 324 | filelen = strnlen ((const char *)section->start, section->size); | ||
| 325 | if (filelen == section->size) | ||
| 326 | - /* Corrupt debugaltlink. */ | ||
| 327 | - return false; | ||
| 328 | + /* Corrupt debugaltlink. */ | ||
| 329 | + return false; | ||
| 330 | |||
| 331 | build_id = section->start + filelen + 1; | ||
| 332 | build_id_len = section->size - (filelen + 1); | ||
| 333 | |||
| 334 | if (build_id_len == 0) | ||
| 335 | - return false; | ||
| 336 | + return false; | ||
| 337 | } | ||
| 338 | else | ||
| 339 | return false; | ||
| 340 | @@ -11451,25 +11451,25 @@ debuginfod_fetch_separate_debug_info (st | ||
| 341 | |||
| 342 | client = debuginfod_begin (); | ||
| 343 | if (client == NULL) | ||
| 344 | - return false; | ||
| 345 | + return false; | ||
| 346 | |||
| 347 | /* Query debuginfod servers for the target file. If found its path | ||
| 348 | - will be stored in filename. */ | ||
| 349 | + will be stored in filename. */ | ||
| 350 | fd = debuginfod_find_debuginfo (client, build_id, build_id_len, filename); | ||
| 351 | debuginfod_end (client); | ||
| 352 | |||
| 353 | /* Only free build_id if we allocated space for a hex string | ||
| 354 | - in get_build_id (). */ | ||
| 355 | + in get_build_id (). */ | ||
| 356 | if (build_id_len == 0) | ||
| 357 | - free (build_id); | ||
| 358 | + free (build_id); | ||
| 359 | |||
| 360 | if (fd >= 0) | ||
| 361 | - { | ||
| 362 | - /* File successfully retrieved. Close fd since we want to | ||
| 363 | - use open_debug_file () on filename instead. */ | ||
| 364 | - close (fd); | ||
| 365 | - return true; | ||
| 366 | - } | ||
| 367 | + { | ||
| 368 | + /* File successfully retrieved. Close fd since we want to | ||
| 369 | + use open_debug_file () on filename instead. */ | ||
| 370 | + close (fd); | ||
| 371 | + return true; | ||
| 372 | + } | ||
| 373 | } | ||
| 374 | |||
| 375 | return false; | ||
| 376 | @@ -11482,7 +11482,7 @@ load_separate_debug_info (const char * | ||
| 377 | parse_func_type parse_func, | ||
| 378 | check_func_type check_func, | ||
| 379 | void * func_data, | ||
| 380 | - void * file ATTRIBUTE_UNUSED) | ||
| 381 | + void * file ATTRIBUTE_UNUSED) | ||
| 382 | { | ||
| 383 | const char * separate_filename; | ||
| 384 | char * debug_filename; | ||
| 385 | @@ -11597,11 +11597,11 @@ load_separate_debug_info (const char * | ||
| 386 | & tmp_filename, | ||
| 387 | file)) | ||
| 388 | { | ||
| 389 | - /* File successfully downloaded from server, replace | ||
| 390 | - debug_filename with the file's path. */ | ||
| 391 | - free (debug_filename); | ||
| 392 | - debug_filename = tmp_filename; | ||
| 393 | - goto found; | ||
| 394 | + /* File successfully downloaded from server, replace | ||
| 395 | + debug_filename with the file's path. */ | ||
| 396 | + free (debug_filename); | ||
| 397 | + debug_filename = tmp_filename; | ||
| 398 | + goto found; | ||
| 399 | } | ||
| 400 | } | ||
| 401 | #endif | ||
| 402 | @@ -11766,12 +11766,12 @@ load_build_id_debug_file (const char * m | ||
| 403 | /* In theory we should extract the contents of the section into | ||
| 404 | a note structure and then check the fields. For now though | ||
| 405 | just use hard coded offsets instead: | ||
| 406 | - | ||
| 407 | + | ||
| 408 | Field Bytes Contents | ||
| 409 | NSize 0...3 4 | ||
| 410 | DSize 4...7 8+ | ||
| 411 | Type 8..11 3 (NT_GNU_BUILD_ID) | ||
| 412 | - Name 12.15 GNU\0 | ||
| 413 | + Name 12.15 GNU\0 | ||
| 414 | Data 16.... */ | ||
| 415 | |||
| 416 | /* FIXME: Check the name size, name and type fields. */ | ||
| 417 | @@ -11783,7 +11783,7 @@ load_build_id_debug_file (const char * m | ||
| 418 | warn (_(".note.gnu.build-id data size is too small\n")); | ||
| 419 | return; | ||
| 420 | } | ||
| 421 | - | ||
| 422 | + | ||
| 423 | if (build_id_size > (section->size - 16)) | ||
| 424 | { | ||
| 425 | warn (_(".note.gnu.build-id data size is too bug\n")); | ||
| 426 | @@ -12075,10 +12075,6 @@ free_debug_memory (void) | ||
| 427 | |||
| 428 | free_all_abbrevs (); | ||
| 429 | |||
| 430 | - free (cu_abbrev_map); | ||
| 431 | - cu_abbrev_map = NULL; | ||
| 432 | - next_free_abbrev_map_entry = 0; | ||
| 433 | - | ||
| 434 | free (shndx_pool); | ||
| 435 | shndx_pool = NULL; | ||
| 436 | shndx_pool_size = 0; | ||
diff --git a/meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-3.patch b/meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-3.patch new file mode 100644 index 0000000000..04d06ed6b6 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0018-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 | } | ||
