summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/binutils/binutils/0017-CVE-2022-38127-2.patch
blob: 0583bfcfabb755f870d6f6458f97f46383902c2f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
From ec41dd75c866599fc03c390c6afb5736c159c0ff Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
Date: Tue, 21 Jun 2022 16:37:27 +0100
Subject: [PATCH] Binutils support for dwarf-5 (location and range lists
 related)

	* dwarf.h (struct debug_info): Add rnglists_base field.
	* dwarf.c (read_and_display_attr_value): Read attribute DW_AT_rnglists_base.
	(display_debug_rnglists_list): While handling DW_RLE_base_addressx,
  	DW_RLE_startx_endx, DW_RLE_startx_length items, pass the proper parameter
	value to fetch_indexed_addr(), i.e. fetch the proper entry in .debug_addr section.
	(display_debug_ranges): Add rnglists_base to the .debug_rnglists base address.
	(load_separate_debug_files): Load .debug_addr section, if exists.

Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=ec41dd75c866599fc03c390c6afb5736c159c0ff]

Signed-off-by: Pgowda <pgowda.cve@gmail.com>
---
 binutils/ChangeLog | 10 +++++++++
 binutils/dwarf.c   | 53 ++++++++++++++++++++++++++++++++++------------
 binutils/dwarf.h   |  1 +
 3 files changed, 51 insertions(+), 13 deletions(-)

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index cb2523af1f3..30b64ac68a8 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -2812,7 +2812,12 @@ read_and_display_attr_value (unsigned lo
 		  dwarf_vmatoa ("x", debug_info_p->cu_offset));
 	  debug_info_p->loclists_base = uvalue;
 	  break;
-
+	case DW_AT_rnglists_base:
+	  if (debug_info_p->rnglists_base)
+	    warn (_("CU @ 0x%s has multiple rnglists_base values"),
+	          dwarf_vmatoa ("x", debug_info_p->cu_offset));
+	  debug_info_p->rnglists_base = uvalue;
+	  break;
 	case DW_AT_frame_base:
 	  have_frame_base = 1;
 	  /* Fall through.  */
@@ -3303,6 +3308,7 @@ read_and_display_attr_value (unsigned lo
       /* Fall through.  */
     case DW_AT_location:
     case DW_AT_loclists_base:
+    case DW_AT_rnglists_base:
     case DW_AT_string_length:
     case DW_AT_return_addr:
     case DW_AT_data_member_location:
@@ -3322,7 +3328,10 @@ read_and_display_attr_value (unsigned lo
 	   && (form == DW_FORM_data4 || form == DW_FORM_data8))
 	  || form == DW_FORM_sec_offset
 	  || form == DW_FORM_loclistx)
-	printf (_(" (location list)"));
+	{
+	  if (attribute != DW_AT_rnglists_base)
+	    printf (_(" (location list)"));
+	}
       /* Fall through.  */
     case DW_AT_allocated:
     case DW_AT_associated:
@@ -3809,6 +3818,7 @@ process_debug_info (struct dwarf_section
 	  debug_information [unit].range_lists = NULL;
 	  debug_information [unit].max_range_lists= 0;
 	  debug_information [unit].num_range_lists = 0;
+	  debug_information [unit].rnglists_base = 0;
 	}
 
       if (!do_loc && dwarf_start_die == 0)
@@ -7932,9 +7942,16 @@ display_debug_rnglists_list (unsigned ch
 			     unsigned char * finish,
 			     unsigned int    pointer_size,
 			     dwarf_vma       offset,
-			     dwarf_vma       base_address)
+			     dwarf_vma       base_address,
+			     unsigned int    offset_size)
 {
   unsigned char *next = start;
+  unsigned int debug_addr_section_hdr_len;
+
+  if (offset_size == 4)
+    debug_addr_section_hdr_len = 8;
+  else
+    debug_addr_section_hdr_len = 16;
 
   while (1)
     {
@@ -7964,20 +7981,24 @@ display_debug_rnglists_list (unsigned ch
 	  READ_ULEB (base_address, start, finish);
 	  print_dwarf_vma (base_address, pointer_size);
 	  printf (_("(base address index) "));
-	  base_address = fetch_indexed_addr (base_address, pointer_size);
+	  base_address = fetch_indexed_addr ((base_address * pointer_size)
+			                     + debug_addr_section_hdr_len, pointer_size);
 	  print_dwarf_vma (base_address, pointer_size);
 	  printf (_("(base address)\n"));
 	  break;
 	case DW_RLE_startx_endx:
 	  READ_ULEB (begin, start, finish);
 	  READ_ULEB (end, start, finish);
-	  begin = fetch_indexed_addr (begin, pointer_size);
-	  end   = fetch_indexed_addr (begin, pointer_size);
+	  begin = fetch_indexed_addr ((begin * pointer_size)
+			              + debug_addr_section_hdr_len, pointer_size);
+	  end   = fetch_indexed_addr ((begin * pointer_size)
+			              + debug_addr_section_hdr_len, pointer_size);
 	  break;
 	case DW_RLE_startx_length:
 	  READ_ULEB (begin, start, finish);
 	  READ_ULEB (length, start, finish);
-	  begin = fetch_indexed_addr (begin, pointer_size);
+	  begin = fetch_indexed_addr ((begin * pointer_size)
+			              + debug_addr_section_hdr_len, pointer_size);
 	  end = begin + length;
 	  break;
 	case DW_RLE_offset_pair:
@@ -8003,6 +8024,7 @@ display_debug_rnglists_list (unsigned ch
 	  rlet = DW_RLE_end_of_list;
 	  break;
 	}
+
       if (rlet == DW_RLE_end_of_list)
 	break;
       if (rlet == DW_RLE_base_address || rlet == DW_RLE_base_addressx)
@@ -8043,6 +8065,7 @@ display_debug_ranges (struct dwarf_secti
   /* Initialize it due to a false compiler warning.  */
   unsigned char         address_size = 0;
   dwarf_vma             last_offset = 0;
+  unsigned int          offset_size = 0;
 
   if (bytes == 0)
     {
@@ -8054,10 +8077,10 @@ display_debug_ranges (struct dwarf_secti
 
   if (is_rnglists)
     {
-      dwarf_vma initial_length;
-      unsigned char segment_selector_size;
-      unsigned int offset_size, offset_entry_count;
-      unsigned short version;
+      dwarf_vma       initial_length;
+      unsigned char   segment_selector_size;
+      unsigned int    offset_entry_count;
+      unsigned short  version;
 
       /* Get and check the length of the block.  */
       SAFE_BYTE_GET_AND_INC (initial_length, start, 4, finish);
@@ -8230,7 +8253,8 @@ display_debug_ranges (struct dwarf_secti
 		(unsigned long) offset, i);
 	  continue;
 	}
-      next = section_begin + offset;
+
+      next = section_begin + offset + debug_info_p->rnglists_base;
 
       /* If multiple DWARF entities reference the same range then we will
          have multiple entries in the `range_entries' list for the same
@@ -8262,7 +8286,7 @@ display_debug_ranges (struct dwarf_secti
 
       if (is_rnglists)
 	display_debug_rnglists_list
-	  (start, finish, pointer_size, offset, base_address);
+	  (start, finish, pointer_size, offset, base_address, offset_size);
       else
 	display_debug_ranges_list
 	  (start, finish, pointer_size, offset, base_address);
@@ -11911,6 +11935,9 @@ load_separate_debug_files (void * file,
       && load_debug_section (abbrev, file)
       && load_debug_section (info, file))
     {
+      /* Load the .debug_addr section, if it exists.  */
+      load_debug_section (debug_addr, file);
+
       free_dwo_info ();
 
       if (process_debug_info (& debug_displays[info].section, file, abbrev,
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 040e674c6ce..8a89c08e7c2 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -192,6 +192,7 @@ typedef struct
   dwarf_vma *    range_lists;
   unsigned int   num_range_lists;
   unsigned int   max_range_lists;
+  dwarf_vma      rnglists_base;
 }
 debug_info;