Coverage Report

Created: 2026-05-11 07:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/binutils/dwarf.h
Line
Count
Source
1
/* dwarf.h - DWARF support header file
2
   Copyright (C) 2005-2026 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_address_size;
70
  unsigned char  ar_segment_size;
71
}
72
DWARF2_Internal_ARange;
73
74
/* Forward declaration.  */
75
typedef struct generic_type generic_type;
76
typedef struct base_type base_type;
77
typedef struct type_def type_def;
78
typedef struct enum_constant enum_constant;
79
typedef struct enum_type enum_type;
80
typedef struct subrange_type subrange_type;
81
typedef struct tab_type tab_type;
82
typedef struct member_type member_type;
83
typedef struct member_parent member_parent;
84
typedef struct type_ptr type_ptr;
85
typedef struct type_ref type_ref;
86
typedef struct variable_type variable_type;
87
88
/* Structure used to optimize insertion of element in linked list.  */
89
struct base_type_l { base_type *head; base_type *tail; };
90
struct type_def_l  { type_def *head; type_def *tail;   };
91
struct enum_type_l { enum_type* head; enum_type* tail; };
92
struct tab_type_l  { tab_type *head; tab_type *tail;   };
93
struct type_ptr_l  { type_ptr *head; type_ptr *tail;   };
94
struct type_ref_l  { type_ref *head; type_ref *tail;   };
95
struct member_parent_l { member_parent *head; member_parent *tail; };
96
struct variable_type_l { variable_type *head; variable_type *tail;  };
97
98
enum field_type
99
{
100
  NO_TYPE,
101
  BASE_TYPE,
102
  TYPE_DEF,
103
  ENUM_TYPE,
104
  TAB_TYPE,
105
  MEMBER_PARENT,
106
  MEMBER_TYPE,
107
  TYPE_PTR,
108
  TYPE_REF,
109
  VARIABLE_TYPE
110
};
111
112
enum size_type
113
{
114
  UNSIGNED_S,
115
  SIGNED_S
116
};
117
118
/* Structure used to abstract all structure below.  */
119
struct generic_type
120
{
121
  union
122
    {
123
      base_type     *base_type;
124
      type_def      *type_def;
125
      enum_type     *enum_type;
126
      tab_type      *tab_type;
127
      member_parent *member_parent;
128
      member_type   *member_type;
129
      type_ptr      *type_ptr;
130
      type_ref      *type_ref;
131
      variable_type *variable_type;
132
    } die_type;
133
  enum field_type field_type;
134
};
135
136
/* Structure used to hold DW_TAG_base_type.  */
137
struct base_type
138
{
139
  uint64_t die_offset;
140
  union
141
    {
142
      uint64_t usize;
143
      int64_t  ssize;
144
    } size;
145
  const char *name;
146
  struct base_type *next;
147
  enum field_type field_type;
148
  enum size_type size_type;
149
};
150
151
/* Structure used to hold DW_TAG_typedef.  */
152
struct type_def
153
{
154
  generic_type ptr_type;
155
  uint64_t die_offset;
156
  /* This field holds the offset of the underlying DIE type in the DWARF info
157
     section.  */
158
  uint64_t ptr_die_offset;
159
  const char *name;
160
  struct type_def *next;
161
  enum field_type field_type;
162
};
163
164
/* Structure used to hold DW_TAG_enumerator.  */
165
struct enum_constant
166
{
167
  uint64_t die_offset;
168
  uint64_t value;
169
  const char *name;
170
  struct enum_constant *next;
171
};
172
173
/* Structure used to hold DW_TAG_enumeration.  */
174
struct enum_type
175
{
176
  uint64_t die_offset;
177
  union
178
    {
179
      uint64_t usize;
180
      int64_t  ssize;
181
    } size;
182
  const char *name;
183
  struct enum_constant *enum_const_head;
184
  struct enum_constant *enum_const_tail;
185
  struct enum_type *next;
186
  enum field_type field_type;
187
  enum size_type size_type;
188
};
189
190
/* Structure used to hold DW_TAG_subrange_type.  */
191
struct subrange_type
192
{
193
  uint64_t die_offset;
194
  union
195
    {
196
      uint64_t usize;
197
      int64_t  ssize;
198
    } size;
199
  struct subrange_type *next;
200
  enum size_type size_type;
201
};
202
203
/* Structure used to hold DW_TAG_array_type.  */
204
struct tab_type
205
{
206
  generic_type ptr_type;
207
  uint64_t die_offset;
208
  /* This field holds the offset of the underlying DIE type in the DWARF info
209
     section.  */
210
  uint64_t ptr_die_offset;
211
  subrange_type *subrange_head;
212
  subrange_type *subrange_tail;
213
  struct tab_type *next;
214
  enum field_type field_type;
215
};
216
217
/* Structure used to hold DW_TAG_member.  */
218
struct member_type
219
{
220
  generic_type ptr_type;
221
  uint64_t die_offset;
222
  /* This field holds the offset of the underlying DIE type in the DWARF info
223
     section.  */
224
  uint64_t ptr_die_offset;
225
  int64_t member_offset;
226
  const char *name;
227
  struct member_type *next;
228
  enum field_type field_type;
229
};
230
231
/* Structure used to hold either DW_TAG_structure_type or DW_TAG_union_type.  */
232
struct member_parent
233
{
234
  uint64_t die_offset;
235
  union
236
    {
237
      uint64_t usize;
238
      int64_t  ssize;
239
    } size;
240
  const char *name;
241
  member_type *member_head;
242
  member_type *member_tail;
243
  struct member_parent *next;
244
  enum size_type size_type;
245
  enum field_type field_type;
246
  enum
247
    {
248
      UNION_TYPE,
249
      STRUCT_TYPE
250
    } type;
251
  /* This field is set to true if the current DIE has DW_AT_declaration.  When
252
     this attribute is present the stucture/union is either incomplete,
253
     non-defining or in a separate entity.  */
254
  bool is_declaration;
255
  /* This field exists to avoid linking indefinitively nested structure.  It is
256
     set to true when the underlying type is known (linked).  */
257
  bool linked;
258
  /* This field exists to avoid displaying indefinitvely nested structure.  It
259
     is set to true when informations from member_parent are displayed.  */
260
  bool displayed;
261
};
262
263
/* Structure used to hold DW_TAG_pointer_type.  */
264
struct type_ptr
265
{
266
  generic_type ptr_type;
267
  uint64_t die_offset;
268
  /* This field holds the offset of the underlying DIE type in the DWARF info
269
     section.  */
270
  uint64_t ptr_die_offset;
271
  union
272
    {
273
      uint64_t usize;
274
      int64_t  ssize;
275
    } size;
276
  struct type_ptr *next;
277
  enum field_type field_type;
278
  enum size_type size_type;
279
};
280
281
/* Structure used to hold either DW_TAG_const_type or DW_TAG_volatile_type.  */
282
struct type_ref
283
{
284
  generic_type ptr_type;
285
  uint64_t die_offset;
286
  /* This field holds the offset of the underlying DIE type in the DWARF info
287
     section.  */
288
  uint64_t ptr_die_offset;
289
  struct type_ref *next;
290
  enum
291
    {
292
      CONST_TYPE,
293
      VOLATILE_TYPE
294
    } type;
295
  enum field_type field_type;
296
};
297
298
/* Structure used to hold either DW_TAG_variable_type.  */
299
struct variable_type
300
{
301
  generic_type ptr_type;
302
  uint64_t die_offset;
303
  /* This field holds the offset of the underlying DIE type in the DWARF info
304
     section.  */
305
  uint64_t ptr_die_offset;
306
  /* This field holds the value in DW_AT_location when the operaion is
307
     DW_OP_addr.  It represents the location within the virtual address space of
308
     the program.  */
309
  uint64_t location_addr;
310
  /* This field holds the total size of the variable.  */
311
  uint64_t total_size;
312
  const char *name;
313
  struct variable_type *next;
314
  enum field_type field_type;
315
  /* This field is set to true if DW_AT_location is present with DW_OP_addr
316
     operand.  */
317
  bool has_location_addr;
318
  /* This field is set to true if DW_AT_specification is present.  It represents
319
     an incomplete, non-defining, or separate declaration corresponding to a
320
     declaration.  */
321
  bool is_specification;
322
  /* This field is set to true if DW_AT_abstract_origin is present.  It
323
     represents an inlined instances of inline subprograms.  */
324
  bool is_abstract_origin;
325
};
326
327
/* N.B. The order here must match the order in debug_displays.  */
328
329
enum dwarf_section_display_enum
330
{
331
  abbrev = 0,
332
  aranges,
333
  frame,
334
  info,
335
  line,
336
  pubnames,
337
  gnu_pubnames,
338
  eh_frame,
339
  eh_frame_hdr,
340
  macinfo,
341
  macro,
342
  str,
343
  line_str,
344
  loc,
345
  loclists,
346
  loclists_dwo,
347
  pubtypes,
348
  gnu_pubtypes,
349
  ranges,
350
  rnglists,
351
  rnglists_dwo,
352
  static_func,
353
  static_vars,
354
  types,
355
  weaknames,
356
  gdb_index,
357
  debug_names,
358
  sframe,
359
  trace_info,
360
  trace_abbrev,
361
  trace_aranges,
362
  info_dwo,
363
  abbrev_dwo,
364
  types_dwo,
365
  line_dwo,
366
  loc_dwo,
367
  macro_dwo,
368
  macinfo_dwo,
369
  str_dwo,
370
  str_index,
371
  str_index_dwo,
372
  debug_addr,
373
  dwp_cu_index,
374
  dwp_tu_index,
375
  gnu_debuglink,
376
  gnu_debugaltlink,
377
  debug_sup,
378
  separate_debug_str,
379
  note_gnu_build_id,
380
  debug_variable_info,
381
  max
382
};
383
384
struct dwarf_section
385
{
386
  /* A debug section has a different name when it's stored compressed
387
     or not.  XCOFF DWARF section also have a special name.
388
     COMPRESSED_NAME, UNCOMPRESSED_NAME and XCOFF_NAME are the three
389
     possibilities.  NAME is set to whichever one is used for this
390
     input file, as determined by load_debug_section().  */
391
  const char *                     uncompressed_name;
392
  const char *                     compressed_name;
393
  const char *                     xcoff_name;
394
  const char *                     name;
395
  /* If non-NULL then FILENAME is the name of the separate debug info
396
     file containing the section.  */
397
  const char *                     filename;
398
  unsigned char *                  start;
399
  uint64_t                         address;
400
  uint64_t                         size;
401
  enum dwarf_section_display_enum  abbrev_sec;
402
  /* Used by clients to help them implement the reloc_at callback.  */
403
  void *                           reloc_info;
404
  uint64_t                         num_relocs;
405
};
406
407
/* A structure containing the name of a debug section
408
   and a pointer to a function that can decode it.  */
409
struct dwarf_section_display
410
{
411
  struct dwarf_section section;
412
  int (*display) (struct dwarf_section *, void *);
413
  int *enabled;
414
  bool relocate;
415
};
416
417
extern struct dwarf_section_display debug_displays [];
418
419
/* This structure records the information that
420
   we extract from the.debug_info section.  */
421
typedef struct
422
{
423
  unsigned int   pointer_size;
424
  unsigned int   offset_size;
425
  int            dwarf_version;
426
  uint64_t   cu_offset;
427
  uint64_t   base_address;
428
  /* This field is filled in when reading the attribute DW_AT_GNU_addr_base and
429
     is used with the form DW_FORM_GNU_addr_index.  */
430
  uint64_t   addr_base;
431
  /* This field is filled in when reading the attribute DW_AT_GNU_ranges_base and
432
     is used when calculating ranges.  */
433
  uint64_t   ranges_base;
434
  /* This is an array of offsets to the location list table.  */
435
  uint64_t *   loc_offsets;
436
  /* This is an array of offsets to the location view table.  */
437
  uint64_t *   loc_views;
438
  int *          have_frame_base;
439
440
  /* Information for associating location lists with CUs.  */
441
  unsigned int   num_loc_offsets;
442
  unsigned int   max_loc_offsets;
443
  unsigned int   num_loc_views;
444
  uint64_t   loclists_base;
445
446
  /* List of .debug_ranges offsets seen in this .debug_info.  */
447
  uint64_t *   range_lists;
448
  unsigned int   num_range_lists;
449
  unsigned int   max_range_lists;
450
  uint64_t   rnglists_base;
451
  uint64_t   str_offsets_base;
452
}
453
debug_info;
454
455
typedef struct separate_info
456
{
457
  void *                  handle;    /* The pointer returned by open_debug_file().  */
458
  const char *            filename;
459
  struct separate_info *  next;
460
} separate_info;
461
462
extern separate_info * first_separate_info;
463
464
extern unsigned int eh_addr_size;
465
extern const char * separate_debug_info_dir;
466
467
extern int do_debug_info;
468
extern int do_debug_abbrevs;
469
extern int do_debug_lines;
470
extern int do_debug_pubnames;
471
extern int do_debug_pubtypes;
472
extern int do_debug_aranges;
473
extern int do_debug_ranges;
474
extern int do_debug_frames;
475
extern int do_debug_frames_interp;
476
extern int do_debug_macinfo;
477
extern int do_debug_str;
478
extern int do_debug_str_offsets;
479
extern int do_debug_loc;
480
extern int do_gdb_index;
481
extern int do_trace_info;
482
extern int do_trace_abbrevs;
483
extern int do_trace_aranges;
484
extern int do_debug_addr;
485
extern int do_debug_cu_index;
486
extern int do_wide;
487
extern int do_debug_links;
488
extern int do_follow_links;
489
#ifdef HAVE_LIBDEBUGINFOD
490
extern int use_debuginfod;
491
#endif
492
extern bool do_checks;
493
494
extern int dwarf_cutoff_level;
495
extern unsigned long dwarf_start_die;
496
497
extern int dwarf_check;
498
499
extern void init_dwarf_by_elf_machine_code (unsigned int);
500
extern void init_dwarf_by_bfd_arch_and_mach (enum bfd_architecture arch,
501
               unsigned long mach);
502
503
extern bool load_debug_section (enum dwarf_section_display_enum, void *);
504
extern void free_debug_section (enum dwarf_section_display_enum);
505
extern bool load_separate_debug_files (void *, const char *);
506
extern void close_debug_file (void *);
507
extern void *open_debug_file (const char *);
508
extern void resolve_and_display_variable_info (void);
509
510
extern void free_debug_memory (void);
511
extern void free_mapping_info_struct (void);
512
513
extern int dwarf_select_sections_by_names (const char *);
514
extern int dwarf_select_sections_by_letters (const char *);
515
extern void dwarf_select_sections_all (void);
516
517
extern unsigned int * find_cu_tu_set (void *, unsigned int);
518
519
extern void * cmalloc (uint64_t, size_t);
520
extern void * xcalloc2 (uint64_t, size_t);
521
extern void * xcmalloc (uint64_t, size_t);
522
extern void * xcrealloc (void *, uint64_t, size_t);
523
524
/* A callback into the client.  Returns TRUE if there is a
525
   relocation against the given debug section at the given
526
   offset.  */
527
extern bool reloc_at (struct dwarf_section *, uint64_t);
528
529
extern uint64_t read_leb128 (const unsigned char *, const unsigned char *const,
530
           bool, unsigned int *, int *);
531
532
#if HAVE_LIBDEBUGINFOD
533
extern unsigned char * get_build_id (void *);
534
#endif
535
536
static inline void
537
report_leb_status (int status)
538
2.83M
{
539
2.83M
  if ((status & 1) != 0)
540
1.69k
    error (_("end of data encountered whilst reading LEB\n"));
541
2.83M
  else if ((status & 2) != 0)
542
25.5k
    error (_("read LEB value is too large to store in destination variable\n"));
543
2.83M
}
Unexecuted instantiation: fuzz_objdump.c:report_leb_status
dwarf.c:report_leb_status
Line
Count
Source
538
1.91M
{
539
1.91M
  if ((status & 1) != 0)
540
443
    error (_("end of data encountered whilst reading LEB\n"));
541
1.91M
  else if ((status & 2) != 0)
542
6.06k
    error (_("read LEB value is too large to store in destination variable\n"));
543
1.91M
}
fuzz_readelf.c:report_leb_status
Line
Count
Source
538
919k
{
539
919k
  if ((status & 1) != 0)
540
1.25k
    error (_("end of data encountered whilst reading LEB\n"));
541
918k
  else if ((status & 2) != 0)
542
19.4k
    error (_("read LEB value is too large to store in destination variable\n"));
543
919k
}
Unexecuted instantiation: fuzz_dwarf.c:report_leb_status
544
545
#define SKIP_ULEB(start, end)         \
546
19.3k
  do                \
547
19.3k
    {               \
548
19.3k
      unsigned int _len;          \
549
19.3k
      read_leb128 (start, end, false, &_len, NULL);   \
550
19.3k
      start += _len;            \
551
19.3k
    }                \
552
19.3k
  while (0)
553
554
#define SKIP_SLEB(start, end)         \
555
847
  do                \
556
847
    {               \
557
847
      unsigned int _len;          \
558
847
      read_leb128 (start, end, true, &_len, NULL);    \
559
847
      start += _len;            \
560
847
    }                \
561
847
  while (0)
562
563
#define READ_ULEB(var, start, end)        \
564
2.83M
  do                \
565
2.83M
    {               \
566
2.83M
      uint64_t _val;            \
567
2.83M
      unsigned int _len;          \
568
2.83M
      int _status;            \
569
2.83M
                \
570
2.83M
      _val = read_leb128 (start, end, false, &_len, &_status);  \
571
2.83M
      start += _len;            \
572
2.83M
      (var) = _val;           \
573
2.83M
      if ((var) != _val)         \
574
2.83M
  _status |= 2;           \
575
2.83M
      report_leb_status (_status);        \
576
2.83M
    }                \
577
2.83M
  while (0)
578
579
#define READ_SLEB(var, start, end)        \
580
5.57k
  do                \
581
5.57k
    {               \
582
5.57k
      int64_t _val;           \
583
5.57k
      unsigned int _len;          \
584
5.57k
      int _status;            \
585
5.57k
                \
586
5.57k
      _val = read_leb128 (start, end, true, &_len, &_status); \
587
5.57k
      start += _len;            \
588
5.57k
      (var) = _val;           \
589
5.57k
      if ((var) != _val)         \
590
5.57k
  _status |= 2;           \
591
5.57k
      report_leb_status (_status);        \
592
5.57k
    }               \
593
5.57k
  while (0)