/src/binutils-gdb/binutils/dwarf.h
Line | Count | Source |
1 | | /* dwarf.h - DWARF support header file |
2 | | Copyright (C) 2005-2023 Free Software Foundation, Inc. |
3 | | |
4 | | This file is part of GNU Binutils. |
5 | | |
6 | | This program is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU General Public License as published by |
8 | | the Free Software Foundation; either version 3 of the License, or |
9 | | (at your option) any later version. |
10 | | |
11 | | This program is distributed in the hope that it will be useful, |
12 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | GNU General Public License for more details. |
15 | | |
16 | | You should have received a copy of the GNU General Public License |
17 | | along with this program; if not, write to the Free Software |
18 | | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
19 | | MA 02110-1301, USA. */ |
20 | | |
21 | | #include "dwarf2.h" /* for enum dwarf_unit_type */ |
22 | | |
23 | | /* Structure found in the .debug_line section. */ |
24 | | typedef struct |
25 | | { |
26 | | uint64_t li_length; |
27 | | uint16_t li_version; |
28 | | uint8_t li_address_size; |
29 | | uint8_t li_segment_size; |
30 | | uint64_t li_prologue_length; |
31 | | uint8_t li_min_insn_length; |
32 | | uint8_t li_max_ops_per_insn; |
33 | | uint8_t li_default_is_stmt; |
34 | | int8_t li_line_base; |
35 | | uint8_t li_line_range; |
36 | | uint8_t li_opcode_base; |
37 | | /* Not part of the header. 4 for 32-bit dwarf, 8 for 64-bit. */ |
38 | | unsigned int li_offset_size; |
39 | | } |
40 | | DWARF2_Internal_LineInfo; |
41 | | |
42 | | /* Structure found in .debug_pubnames section. */ |
43 | | typedef struct |
44 | | { |
45 | | uint64_t pn_length; |
46 | | unsigned short pn_version; |
47 | | uint64_t pn_offset; |
48 | | uint64_t pn_size; |
49 | | } |
50 | | DWARF2_Internal_PubNames; |
51 | | |
52 | | /* Structure found in .debug_info section. */ |
53 | | typedef struct |
54 | | { |
55 | | uint64_t cu_length; |
56 | | unsigned short cu_version; |
57 | | uint64_t cu_abbrev_offset; |
58 | | unsigned char cu_pointer_size; |
59 | | enum dwarf_unit_type cu_unit_type; |
60 | | } |
61 | | DWARF2_Internal_CompUnit; |
62 | | |
63 | | /* Structure found in .debug_aranges section. */ |
64 | | typedef struct |
65 | | { |
66 | | uint64_t ar_length; |
67 | | unsigned short ar_version; |
68 | | uint64_t ar_info_offset; |
69 | | unsigned char ar_pointer_size; |
70 | | unsigned char ar_segment_size; |
71 | | } |
72 | | DWARF2_Internal_ARange; |
73 | | |
74 | | /* N.B. The order here must match the order in debug_displays. */ |
75 | | |
76 | | enum dwarf_section_display_enum |
77 | | { |
78 | | abbrev = 0, |
79 | | aranges, |
80 | | frame, |
81 | | info, |
82 | | line, |
83 | | pubnames, |
84 | | gnu_pubnames, |
85 | | eh_frame, |
86 | | macinfo, |
87 | | macro, |
88 | | str, |
89 | | line_str, |
90 | | loc, |
91 | | loclists, |
92 | | loclists_dwo, |
93 | | pubtypes, |
94 | | gnu_pubtypes, |
95 | | ranges, |
96 | | rnglists, |
97 | | rnglists_dwo, |
98 | | static_func, |
99 | | static_vars, |
100 | | types, |
101 | | weaknames, |
102 | | gdb_index, |
103 | | debug_names, |
104 | | trace_info, |
105 | | trace_abbrev, |
106 | | trace_aranges, |
107 | | info_dwo, |
108 | | abbrev_dwo, |
109 | | types_dwo, |
110 | | line_dwo, |
111 | | loc_dwo, |
112 | | macro_dwo, |
113 | | macinfo_dwo, |
114 | | str_dwo, |
115 | | str_index, |
116 | | str_index_dwo, |
117 | | debug_addr, |
118 | | dwp_cu_index, |
119 | | dwp_tu_index, |
120 | | gnu_debuglink, |
121 | | gnu_debugaltlink, |
122 | | debug_sup, |
123 | | separate_debug_str, |
124 | | note_gnu_build_id, |
125 | | max |
126 | | }; |
127 | | |
128 | | struct dwarf_section |
129 | | { |
130 | | /* A debug section has a different name when it's stored compressed |
131 | | or not. XCOFF DWARF section also have a special name. |
132 | | COMPRESSED_NAME, UNCOMPRESSED_NAME and XCOFF_NAME are the three |
133 | | possibilities. NAME is set to whichever one is used for this |
134 | | input file, as determined by load_debug_section(). */ |
135 | | const char * uncompressed_name; |
136 | | const char * compressed_name; |
137 | | const char * xcoff_name; |
138 | | const char * name; |
139 | | /* If non-NULL then FILENAME is the name of the separate debug info |
140 | | file containing the section. */ |
141 | | const char * filename; |
142 | | unsigned char * start; |
143 | | uint64_t address; |
144 | | uint64_t size; |
145 | | enum dwarf_section_display_enum abbrev_sec; |
146 | | /* Used by clients to help them implement the reloc_at callback. */ |
147 | | void * reloc_info; |
148 | | uint64_t num_relocs; |
149 | | }; |
150 | | |
151 | | /* A structure containing the name of a debug section |
152 | | and a pointer to a function that can decode it. */ |
153 | | struct dwarf_section_display |
154 | | { |
155 | | struct dwarf_section section; |
156 | | int (*display) (struct dwarf_section *, void *); |
157 | | int *enabled; |
158 | | bool relocate; |
159 | | }; |
160 | | |
161 | | extern struct dwarf_section_display debug_displays []; |
162 | | |
163 | | /* This structure records the information that |
164 | | we extract from the.debug_info section. */ |
165 | | typedef struct |
166 | | { |
167 | | unsigned int pointer_size; |
168 | | unsigned int offset_size; |
169 | | int dwarf_version; |
170 | | uint64_t cu_offset; |
171 | | uint64_t base_address; |
172 | | /* This field is filled in when reading the attribute DW_AT_GNU_addr_base and |
173 | | is used with the form DW_FORM_GNU_addr_index. */ |
174 | | uint64_t addr_base; |
175 | | /* This field is filled in when reading the attribute DW_AT_GNU_ranges_base and |
176 | | is used when calculating ranges. */ |
177 | | uint64_t ranges_base; |
178 | | /* This is an array of offsets to the location list table. */ |
179 | | uint64_t * loc_offsets; |
180 | | /* This is an array of offsets to the location view table. */ |
181 | | uint64_t * loc_views; |
182 | | int * have_frame_base; |
183 | | |
184 | | /* Information for associating location lists with CUs. */ |
185 | | unsigned int num_loc_offsets; |
186 | | unsigned int max_loc_offsets; |
187 | | unsigned int num_loc_views; |
188 | | uint64_t loclists_base; |
189 | | |
190 | | /* List of .debug_ranges offsets seen in this .debug_info. */ |
191 | | uint64_t * range_lists; |
192 | | unsigned int * range_versions; |
193 | | unsigned int num_range_lists; |
194 | | unsigned int max_range_lists; |
195 | | uint64_t rnglists_base; |
196 | | uint64_t str_offsets_base; |
197 | | } |
198 | | debug_info; |
199 | | |
200 | | typedef struct separate_info |
201 | | { |
202 | | void * handle; /* The pointer returned by open_debug_file(). */ |
203 | | const char * filename; |
204 | | struct separate_info * next; |
205 | | } separate_info; |
206 | | |
207 | | extern separate_info * first_separate_info; |
208 | | |
209 | | extern unsigned int eh_addr_size; |
210 | | |
211 | | extern int do_debug_info; |
212 | | extern int do_debug_abbrevs; |
213 | | extern int do_debug_lines; |
214 | | extern int do_debug_pubnames; |
215 | | extern int do_debug_pubtypes; |
216 | | extern int do_debug_aranges; |
217 | | extern int do_debug_ranges; |
218 | | extern int do_debug_frames; |
219 | | extern int do_debug_frames_interp; |
220 | | extern int do_debug_macinfo; |
221 | | extern int do_debug_str; |
222 | | extern int do_debug_str_offsets; |
223 | | extern int do_debug_loc; |
224 | | extern int do_gdb_index; |
225 | | extern int do_trace_info; |
226 | | extern int do_trace_abbrevs; |
227 | | extern int do_trace_aranges; |
228 | | extern int do_debug_addr; |
229 | | extern int do_debug_cu_index; |
230 | | extern int do_wide; |
231 | | extern int do_debug_links; |
232 | | extern int do_follow_links; |
233 | | #ifdef HAVE_LIBDEBUGINFOD |
234 | | extern int use_debuginfod; |
235 | | #endif |
236 | | extern bool do_checks; |
237 | | |
238 | | extern int dwarf_cutoff_level; |
239 | | extern unsigned long dwarf_start_die; |
240 | | |
241 | | extern int dwarf_check; |
242 | | |
243 | | extern void init_dwarf_regnames_by_elf_machine_code (unsigned int); |
244 | | extern void init_dwarf_regnames_by_bfd_arch_and_mach (enum bfd_architecture arch, |
245 | | unsigned long mach); |
246 | | |
247 | | extern bool load_debug_section (enum dwarf_section_display_enum, void *); |
248 | | extern void free_debug_section (enum dwarf_section_display_enum); |
249 | | extern bool load_separate_debug_files (void *, const char *); |
250 | | extern void close_debug_file (void *); |
251 | | extern void *open_debug_file (const char *); |
252 | | |
253 | | extern void free_debug_memory (void); |
254 | | |
255 | | extern int dwarf_select_sections_by_names (const char *); |
256 | | extern int dwarf_select_sections_by_letters (const char *); |
257 | | extern void dwarf_select_sections_all (void); |
258 | | |
259 | | extern unsigned int * find_cu_tu_set (void *, unsigned int); |
260 | | |
261 | | extern void * cmalloc (uint64_t, size_t); |
262 | | extern void * xcalloc2 (uint64_t, size_t); |
263 | | extern void * xcmalloc (uint64_t, size_t); |
264 | | extern void * xcrealloc (void *, uint64_t, size_t); |
265 | | |
266 | | /* A callback into the client. Returns TRUE if there is a |
267 | | relocation against the given debug section at the given |
268 | | offset. */ |
269 | | extern bool reloc_at (struct dwarf_section *, uint64_t); |
270 | | |
271 | | extern uint64_t read_leb128 (unsigned char *, const unsigned char *const, |
272 | | bool, unsigned int *, int *); |
273 | | |
274 | | #if HAVE_LIBDEBUGINFOD |
275 | | extern unsigned char * get_build_id (void *); |
276 | | #endif |
277 | | |
278 | | static inline void |
279 | | report_leb_status (int status) |
280 | 27.5M | { |
281 | 27.5M | if ((status & 1) != 0) |
282 | 17.0k | error (_("end of data encountered whilst reading LEB\n")); |
283 | 27.5M | else if ((status & 2) != 0) |
284 | 133k | error (_("read LEB value is too large to store in destination variable\n")); |
285 | 27.5M | } Unexecuted instantiation: fuzz_dwarf.c:report_leb_status dwarf.c:report_leb_status Line | Count | Source | 280 | 23.7M | { | 281 | 23.7M | if ((status & 1) != 0) | 282 | 13.5k | error (_("end of data encountered whilst reading LEB\n")); | 283 | 23.6M | else if ((status & 2) != 0) | 284 | 63.7k | error (_("read LEB value is too large to store in destination variable\n")); | 285 | 23.7M | } |
Unexecuted instantiation: fuzz_objdump.c:report_leb_status fuzz_readelf.c:report_leb_status Line | Count | Source | 280 | 3.82M | { | 281 | 3.82M | if ((status & 1) != 0) | 282 | 3.46k | error (_("end of data encountered whilst reading LEB\n")); | 283 | 3.81M | else if ((status & 2) != 0) | 284 | 70.0k | error (_("read LEB value is too large to store in destination variable\n")); | 285 | 3.82M | } |
|
286 | | |
287 | | #define SKIP_ULEB(start, end) \ |
288 | 485k | do \ |
289 | 485k | { \ |
290 | 485k | unsigned int _len; \ |
291 | 485k | read_leb128 (start, end, false, &_len, NULL); \ |
292 | 485k | start += _len; \ |
293 | 485k | } \ |
294 | 485k | while (0) |
295 | | |
296 | | #define SKIP_SLEB(start, end) \ |
297 | 21.4k | do \ |
298 | 21.4k | { \ |
299 | 21.4k | unsigned int _len; \ |
300 | 21.4k | read_leb128 (start, end, true, &_len, NULL); \ |
301 | 21.4k | start += _len; \ |
302 | 21.4k | } \ |
303 | 21.4k | while (0) |
304 | | |
305 | | #define READ_ULEB(var, start, end) \ |
306 | 27.3M | do \ |
307 | 27.3M | { \ |
308 | 27.3M | uint64_t _val; \ |
309 | 27.3M | unsigned int _len; \ |
310 | 27.3M | int _status; \ |
311 | 27.3M | \ |
312 | 27.3M | _val = read_leb128 (start, end, false, &_len, &_status); \ |
313 | 27.3M | start += _len; \ |
314 | 27.3M | (var) = _val; \ |
315 | 27.3M | if ((var) != _val) \ |
316 | 27.3M | _status |= 2; \ |
317 | 27.3M | report_leb_status (_status); \ |
318 | 27.3M | } \ |
319 | 27.3M | while (0) |
320 | | |
321 | | #define READ_SLEB(var, start, end) \ |
322 | 223k | do \ |
323 | 223k | { \ |
324 | 223k | int64_t _val; \ |
325 | 223k | unsigned int _len; \ |
326 | 223k | int _status; \ |
327 | 223k | \ |
328 | 223k | _val = read_leb128 (start, end, true, &_len, &_status); \ |
329 | 223k | start += _len; \ |
330 | 223k | (var) = _val; \ |
331 | 223k | if ((var) != _val) \ |
332 | 223k | _status |= 2; \ |
333 | 223k | report_leb_status (_status); \ |
334 | 223k | } \ |
335 | 223k | while (0) |