/* dwarf.h - DWARF support header file
- Copyright 2005, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2005-2020 Free Software Foundation, Inc.
This file is part of GNU Binutils.
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
-typedef unsigned HOST_WIDEST_INT dwarf_vma;
-typedef unsigned HOST_WIDEST_INT dwarf_size_type;
+#include "dwarf2.h" /* for enum dwarf_unit_type */
-/* Structure found in the .debug_line section. */
-typedef struct
-{
- unsigned char li_length [4];
- unsigned char li_version [2];
- unsigned char li_prologue_length [4];
- unsigned char li_min_insn_length [1];
- unsigned char li_default_is_stmt [1];
- unsigned char li_line_base [1];
- unsigned char li_line_range [1];
- unsigned char li_opcode_base [1];
-}
-DWARF2_External_LineInfo;
+typedef unsigned HOST_WIDEST_INT dwarf_vma;
+typedef HOST_WIDEST_INT dwarf_signed_vma;
+typedef unsigned HOST_WIDEST_INT dwarf_size_type;
+/* Structure found in the .debug_line section. */
typedef struct
{
- bfd_vma li_length;
+ dwarf_vma li_length;
unsigned short li_version;
- unsigned int li_prologue_length;
+ unsigned char li_address_size;
+ unsigned char li_segment_size;
+ dwarf_vma li_prologue_length;
unsigned char li_min_insn_length;
unsigned char li_max_ops_per_insn;
unsigned char li_default_is_stmt;
int li_line_base;
unsigned char li_line_range;
unsigned char li_opcode_base;
+ unsigned int li_offset_size;
}
DWARF2_Internal_LineInfo;
/* Structure found in .debug_pubnames section. */
typedef struct
{
- unsigned char pn_length [4];
- unsigned char pn_version [2];
- unsigned char pn_offset [4];
- unsigned char pn_size [4];
-}
-DWARF2_External_PubNames;
-
-typedef struct
-{
- bfd_vma pn_length;
+ dwarf_vma pn_length;
unsigned short pn_version;
- bfd_vma pn_offset;
- bfd_vma pn_size;
+ dwarf_vma pn_offset;
+ dwarf_vma pn_size;
}
DWARF2_Internal_PubNames;
/* Structure found in .debug_info section. */
typedef struct
{
- unsigned char cu_length [4];
- unsigned char cu_version [2];
- unsigned char cu_abbrev_offset [4];
- unsigned char cu_pointer_size [1];
-}
-DWARF2_External_CompUnit;
-
-typedef struct
-{
- bfd_vma cu_length;
+ dwarf_vma cu_length;
unsigned short cu_version;
- bfd_vma cu_abbrev_offset;
+ dwarf_vma cu_abbrev_offset;
unsigned char cu_pointer_size;
+ enum dwarf_unit_type cu_unit_type;
}
DWARF2_Internal_CompUnit;
+/* Structure found in .debug_aranges section. */
typedef struct
{
- unsigned char ar_length [4];
- unsigned char ar_version [2];
- unsigned char ar_info_offset [4];
- unsigned char ar_pointer_size [1];
- unsigned char ar_segment_size [1];
-}
-DWARF2_External_ARange;
-
-typedef struct
-{
- bfd_vma ar_length;
+ dwarf_vma ar_length;
unsigned short ar_version;
- bfd_vma ar_info_offset;
+ dwarf_vma ar_info_offset;
unsigned char ar_pointer_size;
unsigned char ar_segment_size;
}
DWARF2_Internal_ARange;
-struct dwarf_section
-{
- /* A debug section has a different name when it's stored compressed
- or not. COMPRESSED_NAME and UNCOMPRESSED_NAME are the two
- possibilities. NAME is set to whichever one is used for this
- input file, as determined by load_debug_section(). */
- const char *uncompressed_name;
- const char *compressed_name;
- const char *name;
- unsigned char *start;
- dwarf_vma address;
- dwarf_size_type size;
-};
-
-/* A structure containing the name of a debug section
- and a pointer to a function that can decode it. */
-struct dwarf_section_display
-{
- struct dwarf_section section;
- int (*display) (struct dwarf_section *, void *);
- int *enabled;
- unsigned int relocate : 1;
-};
+/* N.B. The order here must match the order in debug_displays. */
enum dwarf_section_display_enum
{
info,
line,
pubnames,
+ gnu_pubnames,
eh_frame,
macinfo,
+ macro,
str,
+ line_str,
loc,
+ loclists,
pubtypes,
+ gnu_pubtypes,
ranges,
+ rnglists,
static_func,
static_vars,
types,
weaknames,
+ gdb_index,
+ debug_names,
trace_info,
trace_abbrev,
trace_aranges,
+ info_dwo,
+ abbrev_dwo,
+ types_dwo,
+ line_dwo,
+ loc_dwo,
+ macro_dwo,
+ macinfo_dwo,
+ str_dwo,
+ str_index,
+ str_index_dwo,
+ debug_addr,
+ dwp_cu_index,
+ dwp_tu_index,
+ gnu_debuglink,
+ gnu_debugaltlink,
+ separate_debug_str,
max
};
+struct dwarf_section
+{
+ /* A debug section has a different name when it's stored compressed
+ or not. COMPRESSED_NAME and UNCOMPRESSED_NAME are the two
+ possibilities. NAME is set to whichever one is used for this
+ input file, as determined by load_debug_section(). */
+ const char * uncompressed_name;
+ const char * compressed_name;
+ const char * name;
+ /* If non-NULL then FILENAME is the name of the separate debug info
+ file containing the section. */
+ const char * filename;
+ unsigned char * start;
+ dwarf_vma address;
+ dwarf_size_type size;
+ enum dwarf_section_display_enum abbrev_sec;
+ /* Used by clients to help them implement the reloc_at callback. */
+ void * reloc_info;
+ unsigned long num_relocs;
+ /* A spare field for random use. */
+ void * user_data;
+};
+
+/* A structure containing the name of a debug section
+ and a pointer to a function that can decode it. */
+struct dwarf_section_display
+{
+ struct dwarf_section section;
+ int (* display) (struct dwarf_section *, void *);
+ int * enabled;
+ bfd_boolean relocate;
+};
+
extern struct dwarf_section_display debug_displays [];
/* This structure records the information that
unsigned int pointer_size;
unsigned int offset_size;
int dwarf_version;
- bfd_vma cu_offset;
- bfd_vma base_address;
+ dwarf_vma cu_offset;
+ dwarf_vma base_address;
+ /* This field is filled in when reading the attribute DW_AT_GNU_addr_base and
+ is used with the form DW_AT_GNU_FORM_addr_index. */
+ dwarf_vma addr_base;
+ /* This field is filled in when reading the attribute DW_AT_GNU_ranges_base and
+ is used when calculating ranges. */
+ dwarf_vma ranges_base;
/* This is an array of offsets to the location list table. */
- bfd_vma *loc_offsets;
- int *have_frame_base;
+ dwarf_vma * loc_offsets;
+ /* This is an array of offsets to the location view table. */
+ dwarf_vma * loc_views;
+ int * have_frame_base;
unsigned int num_loc_offsets;
unsigned int max_loc_offsets;
+ unsigned int num_loc_views;
/* List of .debug_ranges offsets seen in this .debug_info. */
- bfd_vma *range_lists;
+ dwarf_vma * range_lists;
unsigned int num_range_lists;
unsigned int max_range_lists;
}
debug_info;
-extern int eh_addr_size;
+typedef struct separate_info
+{
+ void * handle; /* The pointer returned by open_debug_file(). */
+ const char * filename;
+ struct separate_info * next;
+} separate_info;
+
+extern separate_info * first_separate_info;
+
+extern unsigned int eh_addr_size;
extern int do_debug_info;
extern int do_debug_abbrevs;
extern int do_debug_frames_interp;
extern int do_debug_macinfo;
extern int do_debug_str;
+extern int do_debug_str_offsets;
extern int do_debug_loc;
extern int do_gdb_index;
extern int do_trace_info;
extern int do_trace_abbrevs;
extern int do_trace_aranges;
+extern int do_debug_addr;
+extern int do_debug_cu_index;
extern int do_wide;
+extern int do_debug_links;
+extern int do_follow_links;
+extern bfd_boolean do_checks;
+
+extern int dwarf_cutoff_level;
+extern unsigned long dwarf_start_die;
+
+extern int dwarf_check;
-extern void init_dwarf_regnames (unsigned int);
-extern void init_dwarf_regnames_i386 (void);
-extern void init_dwarf_regnames_x86_64 (void);
+extern void init_dwarf_regnames_by_elf_machine_code (unsigned int);
+extern void init_dwarf_regnames_by_bfd_arch_and_mach (enum bfd_architecture arch,
+ unsigned long mach);
-extern int load_debug_section (enum dwarf_section_display_enum,
- void *);
-extern void free_debug_section (enum dwarf_section_display_enum);
+extern bfd_boolean load_debug_section (enum dwarf_section_display_enum, void *);
+extern void free_debug_section (enum dwarf_section_display_enum);
+extern bfd_boolean load_separate_debug_files (void *, const char *);
+extern void close_debug_file (void *);
+extern void * open_debug_file (const char *);
extern void free_debug_memory (void);
extern void dwarf_select_sections_by_letters (const char *);
extern void dwarf_select_sections_all (void);
-void *cmalloc (size_t, size_t);
-void *xcmalloc (size_t, size_t);
-void *xcrealloc (void *, size_t, size_t);
+extern unsigned int * find_cu_tu_set (void *, unsigned int);
+
+extern void * cmalloc (size_t, size_t);
+extern void * xcalloc2 (size_t, size_t);
+extern void * xcmalloc (size_t, size_t);
+extern void * xcrealloc (void *, size_t, size_t);
+
+/* A callback into the client. Returns TRUE if there is a
+ relocation against the given debug section at the given
+ offset. */
+extern bfd_boolean reloc_at (struct dwarf_section *, dwarf_vma);
+
+extern dwarf_vma read_leb128 (unsigned char *, const unsigned char *const,
+ bfd_boolean, unsigned int *, int *);
+
+#if HAVE_LIBDEBUGINFOD
+extern unsigned char * get_build_id (void *);
+#endif
+
+static inline void
+report_leb_status (int status, const char *file, unsigned long lnum)
+{
+ if ((status & 1) != 0)
+ error (_("%s:%lu: end of data encountered whilst reading LEB\n"), file, lnum);
+ else if ((status & 2) != 0)
+ error (_("%s:%lu: read LEB value is too large to store in destination variable\n"), file, lnum);
+}
+
+#define SKIP_ULEB(start, end) \
+ do \
+ { \
+ unsigned int _len; \
+ read_leb128 (start, end, FALSE, &_len, NULL); \
+ start += _len; \
+ } \
+ while (0)
+
+#define SKIP_SLEB(start, end) \
+ do \
+ { \
+ unsigned int _len; \
+ read_leb128 (start, end, TRUE, &_len, NULL); \
+ start += _len; \
+ } \
+ while (0)
+
+#define READ_ULEB(var, start, end) \
+ do \
+ { \
+ dwarf_vma _val; \
+ unsigned int _len; \
+ int _status; \
+ \
+ _val = read_leb128 (start, end, FALSE, &_len, &_status); \
+ start += _len; \
+ (var) = _val; \
+ if ((var) != _val) \
+ _status |= 2; \
+ report_leb_status (_status, __FILE__, __LINE__); \
+ } \
+ while (0)
-bfd_vma read_leb128 (unsigned char *data,
- unsigned int *length_return, int sign);
+#define READ_SLEB(var, start, end) \
+ do \
+ { \
+ dwarf_signed_vma _val; \
+ unsigned int _len; \
+ int _status; \
+ \
+ _val = read_leb128 (start, end, TRUE, &_len, &_status); \
+ start += _len; \
+ (var) = _val; \
+ if ((var) != _val) \
+ _status |= 2; \
+ report_leb_status (_status, __FILE__, __LINE__); \
+ } \
+ while (0)