blob: 04d06ed6b6fe82e0c18e6619e41cff61f9a404cf [file] [log] [blame]
Andrew Geissler87f5cff2022-09-30 13:13:31 -05001From 695c6dfe7e85006b98c8b746f3fd5f913c94ebff Mon Sep 17 00:00:00 2001
2From: Alan Modra <amodra@gmail.com>
3Date: Thu, 21 Jul 2022 09:56:15 +0930
4Subject: [PATCH] PR29370, infinite loop in display_debug_abbrev
5
6The PR29370 testcase is a fuzzed object file with multiple
7.trace_abbrev sections. Multiple .trace_abbrev or .debug_abbrev
8sections are not a violation of the DWARF standard. The DWARF5
9standard even gives an example of multiple .debug_abbrev sections
10contained in groups. Caching and lookup of processed abbrevs thus
11needs 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
13into 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
24Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=695c6dfe7e85006b98c8b746f3fd5f913c94ebff]
25
26Signed-off-by: Pgowda <pgowda.cve@gmail.com>
27---
28 binutils/dwarf.c | 19 ++++++-------------
29 1 file changed, 6 insertions(+), 13 deletions(-)
30
31diff --git a/binutils/dwarf.c b/binutils/dwarf.c
32index 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 }