|  | /* dwarf.h - DWARF support header file | 
|  | Copyright (C) 2005-2023 Free Software Foundation, Inc. | 
|  |  | 
|  | This file is part of GNU Binutils. | 
|  |  | 
|  | This program is free software; you can redistribute it and/or modify | 
|  | it under the terms of the GNU General Public License as published by | 
|  | the Free Software Foundation; either version 3 of the License, or | 
|  | (at your option) any later version. | 
|  |  | 
|  | This program is distributed in the hope that it will be useful, | 
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | GNU General Public License for more details. | 
|  |  | 
|  | You should have received a copy of the GNU General Public License | 
|  | along with this program; if not, write to the Free Software | 
|  | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | 
|  | MA 02110-1301, USA.  */ | 
|  |  | 
|  | #include "dwarf2.h" /* for enum dwarf_unit_type */ | 
|  |  | 
|  | /* Structure found in the .debug_line section.  */ | 
|  | typedef struct | 
|  | { | 
|  | uint64_t li_length; | 
|  | uint16_t li_version; | 
|  | uint8_t  li_address_size; | 
|  | uint8_t  li_segment_size; | 
|  | uint64_t li_prologue_length; | 
|  | uint8_t  li_min_insn_length; | 
|  | uint8_t  li_max_ops_per_insn; | 
|  | uint8_t  li_default_is_stmt; | 
|  | int8_t   li_line_base; | 
|  | uint8_t  li_line_range; | 
|  | uint8_t  li_opcode_base; | 
|  | /* Not part of the header.  4 for 32-bit dwarf, 8 for 64-bit.  */ | 
|  | unsigned int li_offset_size; | 
|  | } | 
|  | DWARF2_Internal_LineInfo; | 
|  |  | 
|  | /* Structure found in .debug_pubnames section.  */ | 
|  | typedef struct | 
|  | { | 
|  | uint64_t	 pn_length; | 
|  | unsigned short pn_version; | 
|  | uint64_t	 pn_offset; | 
|  | uint64_t	 pn_size; | 
|  | } | 
|  | DWARF2_Internal_PubNames; | 
|  |  | 
|  | /* Structure found in .debug_info section.  */ | 
|  | typedef struct | 
|  | { | 
|  | uint64_t	 cu_length; | 
|  | unsigned short cu_version; | 
|  | uint64_t	 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 | 
|  | { | 
|  | uint64_t	 ar_length; | 
|  | unsigned short ar_version; | 
|  | uint64_t	 ar_info_offset; | 
|  | unsigned char  ar_pointer_size; | 
|  | unsigned char  ar_segment_size; | 
|  | } | 
|  | DWARF2_Internal_ARange; | 
|  |  | 
|  | /* N.B. The order here must match the order in debug_displays.  */ | 
|  |  | 
|  | enum dwarf_section_display_enum | 
|  | { | 
|  | abbrev = 0, | 
|  | aranges, | 
|  | frame, | 
|  | info, | 
|  | line, | 
|  | pubnames, | 
|  | gnu_pubnames, | 
|  | eh_frame, | 
|  | macinfo, | 
|  | macro, | 
|  | str, | 
|  | line_str, | 
|  | loc, | 
|  | loclists, | 
|  | loclists_dwo, | 
|  | pubtypes, | 
|  | gnu_pubtypes, | 
|  | ranges, | 
|  | rnglists, | 
|  | rnglists_dwo, | 
|  | 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, | 
|  | debug_sup, | 
|  | separate_debug_str, | 
|  | note_gnu_build_id, | 
|  | max | 
|  | }; | 
|  |  | 
|  | struct dwarf_section | 
|  | { | 
|  | /* A debug section has a different name when it's stored compressed | 
|  | or not.  XCOFF DWARF section also have a special name. | 
|  | COMPRESSED_NAME, UNCOMPRESSED_NAME and XCOFF_NAME are the three | 
|  | 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 *                     xcoff_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; | 
|  | uint64_t                         address; | 
|  | uint64_t                         size; | 
|  | enum dwarf_section_display_enum  abbrev_sec; | 
|  | /* Used by clients to help them implement the reloc_at callback.  */ | 
|  | void *                           reloc_info; | 
|  | uint64_t                         num_relocs; | 
|  | }; | 
|  |  | 
|  | /* 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; | 
|  | bool relocate; | 
|  | }; | 
|  |  | 
|  | extern struct dwarf_section_display debug_displays []; | 
|  |  | 
|  | /* This structure records the information that | 
|  | we extract from the.debug_info section.  */ | 
|  | typedef struct | 
|  | { | 
|  | unsigned int   pointer_size; | 
|  | unsigned int   offset_size; | 
|  | int            dwarf_version; | 
|  | uint64_t	 cu_offset; | 
|  | uint64_t	 base_address; | 
|  | /* This field is filled in when reading the attribute DW_AT_GNU_addr_base and | 
|  | is used with the form DW_FORM_GNU_addr_index.  */ | 
|  | uint64_t	 addr_base; | 
|  | /* This field is filled in when reading the attribute DW_AT_GNU_ranges_base and | 
|  | is used when calculating ranges.  */ | 
|  | uint64_t	 ranges_base; | 
|  | /* This is an array of offsets to the location list table.  */ | 
|  | uint64_t *	 loc_offsets; | 
|  | /* This is an array of offsets to the location view table.  */ | 
|  | uint64_t *	 loc_views; | 
|  | int *          have_frame_base; | 
|  |  | 
|  | /* Information for associating location lists with CUs.  */ | 
|  | unsigned int   num_loc_offsets; | 
|  | unsigned int   max_loc_offsets; | 
|  | unsigned int   num_loc_views; | 
|  | uint64_t	 loclists_base; | 
|  |  | 
|  | /* List of .debug_ranges offsets seen in this .debug_info.  */ | 
|  | uint64_t *	 range_lists; | 
|  | unsigned int   num_range_lists; | 
|  | unsigned int   max_range_lists; | 
|  | uint64_t	 rnglists_base; | 
|  | uint64_t	 str_offsets_base; | 
|  | } | 
|  | debug_info; | 
|  |  | 
|  | 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_lines; | 
|  | extern int do_debug_pubnames; | 
|  | extern int do_debug_pubtypes; | 
|  | extern int do_debug_aranges; | 
|  | extern int do_debug_ranges; | 
|  | extern int do_debug_frames; | 
|  | 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; | 
|  | #ifdef HAVE_LIBDEBUGINFOD | 
|  | extern int use_debuginfod; | 
|  | #endif | 
|  | extern bool do_checks; | 
|  |  | 
|  | extern int dwarf_cutoff_level; | 
|  | extern unsigned long dwarf_start_die; | 
|  |  | 
|  | extern int dwarf_check; | 
|  |  | 
|  | 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 bool load_debug_section (enum dwarf_section_display_enum, void *); | 
|  | extern void free_debug_section (enum dwarf_section_display_enum); | 
|  | extern bool 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 int dwarf_select_sections_by_names (const char *); | 
|  | extern int dwarf_select_sections_by_letters (const char *); | 
|  | extern void dwarf_select_sections_all (void); | 
|  |  | 
|  | extern unsigned int * find_cu_tu_set (void *, unsigned int); | 
|  |  | 
|  | extern void * cmalloc (uint64_t, size_t); | 
|  | extern void * xcalloc2 (uint64_t, size_t); | 
|  | extern void * xcmalloc (uint64_t, size_t); | 
|  | extern void * xcrealloc (void *, uint64_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 bool reloc_at (struct dwarf_section *, uint64_t); | 
|  |  | 
|  | extern uint64_t read_leb128 (unsigned char *, const unsigned char *const, | 
|  | bool, unsigned int *, int *); | 
|  |  | 
|  | #if HAVE_LIBDEBUGINFOD | 
|  | extern unsigned char * get_build_id (void *); | 
|  | #endif | 
|  |  | 
|  | static inline void | 
|  | report_leb_status (int status) | 
|  | { | 
|  | if ((status & 1) != 0) | 
|  | error (_("end of data encountered whilst reading LEB\n")); | 
|  | else if ((status & 2) != 0) | 
|  | error (_("read LEB value is too large to store in destination variable\n")); | 
|  | } | 
|  |  | 
|  | #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								\ | 
|  | {								\ | 
|  | uint64_t _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);				\ | 
|  | }								\ | 
|  | while (0) | 
|  |  | 
|  | #define READ_SLEB(var, start, end)				\ | 
|  | do								\ | 
|  | {								\ | 
|  | int64_t _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);				\ | 
|  | }								\ | 
|  | while (0) |