/* Copyright (C) 2021-2024 Free Software Foundation, Inc. Contributed by Oracle. 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, 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, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _DWARFLIB_H_ #define _DWARFLIB_H_ #include "dwarf2.h" class ElfReloc; class Dwr_type; class SourceFile; template class Vector; template class DbeArray; template class DefaultMap; typedef uint64_t ULEB128; typedef int64_t SLEB128; typedef unsigned short Dwarf_Half; typedef unsigned char Dwarf_Small; typedef uint64_t Dwarf_Off; typedef uint64_t Dwarf_Addr; typedef uint64_t Dwarf_Unsigned; typedef int64_t Dwarf_Die; typedef int32_t Dwarf_Debug; typedef int32_t Dwarf_Attribute; class DwrSec { public: DwrSec (unsigned char *_data, uint64_t _size, bool _need_swap_endian, bool _addr32); DwrSec (DwrSec *secp, uint64_t _offset); ~DwrSec (); unsigned char Get_8 (); unsigned short Get_16 (); uint32_t Get_32 (); uint64_t Get_64 (); uint64_t GetRef (); uint64_t GetADDR (); uint64_t GetADDR_32 (); uint64_t GetADDR_64 (); uint64_t GetLong (); uint64_t ReadLength (); SLEB128 GetSLEB128 (); ULEB128 GetULEB128 (); char *GetString (); char *GetData (uint64_t len); uint32_t Get_24 (); uint64_t get_value (int dw_form); void dump (char *msg); inline uint32_t GetULEB128_32 () { return (uint32_t) GetULEB128 (); } bool inRange (uint64_t left, uint64_t right) { return (offset >= left) && (offset < right); }; ElfReloc *reloc; uint64_t sizeSec; uint64_t size; uint64_t offset; bool fmt64; bool addr32; bool need_swap_endian; int address_size; int segment_selector_size; // DWARF 5 private: bool isCopy; unsigned char *data; bool bounds_violation (uint64_t sz); }; class DwrFileName { public: DwrFileName (char *_fname); ~DwrFileName (); uint64_t timestamp; uint64_t file_size; int dir_index; char *fname; char *path; bool isUsed; }; class DwrLine { public: DwrLine (); ~DwrLine (); uint64_t address; uint32_t file; uint32_t line; uint32_t column; }; class DwrInlinedSubr { public: DwrInlinedSubr (int64_t _abstract_origin, uint64_t _low_pc, uint64_t _high_pc, int _file, int _line, int _level); void dump (); int64_t abstract_origin; uint64_t low_pc; uint64_t high_pc; int file; int line; int level; }; class DwrLineRegs { public: DwrLineRegs (Dwarf *_dwarf, DwrSec *_secp, char *dirName); ~DwrLineRegs (); char *getPath (int fn); Vector *get_lines (); void dump (); Vector *file_names; private: void DoExtendedOpcode (); void DoStandardOpcode (int opcode); void DoSpecialOpcode (int opcode); void EmitLine (); void reset (); Vector *read_file_names_dwarf5 (); Dwarf *dwarf; char *fname; uint64_t dir_index; uint64_t timestamp; uint64_t file_size; uint64_t address; int file; int line; int column; Dwarf_Half version; uint64_t op_index_register; Dwarf_Small maximum_operations_per_instruction; Dwarf_Small minimum_instruction_length; Dwarf_Small default_is_stmt; Dwarf_Small line_range; Dwarf_Small opcode_base; signed char line_base; bool is_stmt; bool basic_block; bool end_sequence; Vector *lines; Vector *dir_names; Dwarf_Small *standard_opcode_length; DwrSec *debug_lineSec; uint64_t header_length; uint64_t opcode_start; }; typedef struct Dwr_Attr { union { char *str; unsigned char *block; uint64_t offset; int64_t val; } u; uint64_t len; // length of u.str int at_form; int at_name; } Dwr_Attr; typedef struct Dwr_Tag { public: Dwr_Attr *get_attr (Dwarf_Half attr); void dump (); DbeArray *abbrevAtForm; int64_t die; int64_t offset; int firstAttribute; int lastAttribute; int tag; int hasChild; int num; int level; } Dwr_Tag; enum { DW_DLV_OK, DW_DLV_NO_ENTRY, DW_DLV_ERROR, DW_DLV_BAD_ELF, DW_DLV_NO_DWARF, DW_DLV_WRONG_ARG }; typedef struct DwrLocation { uint64_t offset; uint64_t lc_number; uint64_t lc_number2; uint32_t op; } DwrLocation; typedef struct DwrAbbrevTable { int64_t offset; int firstAtForm; int lastAtForm; int code; int tag; bool hasChild; } DwrAbbrevTable; class Dwarf_cnt { public: Dwarf_cnt (); int64_t cu_offset; int64_t parent; int64_t size; Module *module; char *name; Function *func; Function *fortranMAIN; datatype_t *dtype; DwrInlinedSubr *inlinedSubr; DefaultMap *dwr_types; int level; Dwr_type *get_dwr_type (int64_t cu_die_offset); Dwr_type *put_dwr_type (int64_t cu_die_offset, int tag); Dwr_type *put_dwr_type (Dwr_Tag *dwrTag); }; class DwrCU { public: DwrCU (Dwarf *_dwarf); ~DwrCU (); Module *parse_cu_header (LoadObject *lo); void parseChild (Dwarf_cnt *ctx); void read_hwcprof_info (Dwarf_cnt *ctx); void map_dwarf_lines (Module *mod); int set_die (Dwarf_Die die); DwrLineRegs *get_dwrLineReg (); static char *at2str (int tag); static char *form2str (int tag); static char *tag2str (int tag); static char *lnct2str (int ty); uint64_t cu_header_offset; uint64_t cu_offset; uint64_t next_cu_offset; Vector *dwrInlinedSubrs; Vector *srcFiles; bool isMemop; bool isGNU; private: void build_abbrevTable (DwrSec *debug_abbrevSec, uint64_t stmt_list_offset); Function *append_Function (Dwarf_cnt *ctx); void parse_inlined_subroutine (Dwarf_cnt *ctx); uint64_t get_low_pc (); uint64_t get_high_pc (uint64_t low_pc); DwrLocation *dwr_get_location (DwrSec *secp, DwrLocation *lp); int read_data_attr (Dwarf_Half attr, int64_t *retVal); int read_ref_attr (Dwarf_Half attr, int64_t *retVal); char *get_linkage_name (); char *Dwarf_string (Dwarf_Half attr); int64_t Dwarf_data (Dwarf_Half attr); int64_t Dwarf_ref (Dwarf_Half attr); DwrSec *Dwarf_block (Dwarf_Half attr); Dwarf_Addr Dwarf_addr (Dwarf_Half attr); Dwarf_Addr Dwarf_location (Dwarf_Attribute attr); Sp_lang_code Dwarf_lang (); Dwarf *dwarf; DwrSec *debug_infoSec; uint64_t debug_abbrev_offset; uint64_t stmt_list_offset; // offset in .debug_line section (DW_AT_stmt_list) char *comp_dir; // compilation directory (DW_AT_comp_dir) Module *module; int unit_type; Dwarf_Half version; Dwarf_Small address_size; Dwr_Tag dwrTag; DwrLineRegs *dwrLineReg; DbeArray *abbrevTable; DbeArray *abbrevAtForm; }; #endif /* _DWARFLIB_H_ */