1/* Copyright (C) 2021-2024 Free Software Foundation, Inc. 2 Contributed by Oracle. 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, or (at your option) 9 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, 51 Franklin Street - Fifth Floor, Boston, 19 MA 02110-1301, USA. */ 20 21#ifndef _DWARFLIB_H_ 22#define _DWARFLIB_H_ 23 24#include "dwarf2.h" 25 26class ElfReloc; 27class Dwr_type; 28class SourceFile; 29 30template <class ITEM> class Vector; 31template <class ITEM> class DbeArray; 32template <typename Key_t, typename Value_t> class DefaultMap; 33 34typedef uint64_t ULEB128; 35typedef int64_t SLEB128; 36typedef unsigned short Dwarf_Half; 37typedef unsigned char Dwarf_Small; 38typedef uint64_t Dwarf_Off; 39typedef uint64_t Dwarf_Addr; 40typedef uint64_t Dwarf_Unsigned; 41typedef int64_t Dwarf_Die; 42typedef int32_t Dwarf_Debug; 43typedef int32_t Dwarf_Attribute; 44 45 46class DwrSec 47{ 48public: 49 DwrSec (unsigned char *_data, uint64_t _size, bool _need_swap_endian, bool _addr32); 50 DwrSec (DwrSec *secp, uint64_t _offset); 51 ~DwrSec (); 52 unsigned char Get_8 (); 53 unsigned short Get_16 (); 54 uint32_t Get_32 (); 55 uint64_t Get_64 (); 56 uint64_t GetRef (); 57 uint64_t GetADDR (); 58 uint64_t GetADDR_32 (); 59 uint64_t GetADDR_64 (); 60 uint64_t GetLong (); 61 uint64_t ReadLength (); 62 SLEB128 GetSLEB128 (); 63 ULEB128 GetULEB128 (); 64 char *GetString (); 65 char *GetData (uint64_t len); 66 uint32_t Get_24 (); 67 uint64_t get_value (int dw_form); 68 void dump (char *msg); 69 70 inline uint32_t 71 GetULEB128_32 () 72 { 73 return (uint32_t) GetULEB128 (); 74 } 75 76 bool 77 inRange (uint64_t left, uint64_t right) 78 { 79 return (offset >= left) && (offset < right); 80 }; 81 82 ElfReloc *reloc; 83 uint64_t sizeSec; 84 uint64_t size; 85 uint64_t offset; 86 bool fmt64; 87 bool addr32; 88 bool need_swap_endian; 89 int address_size; 90 int segment_selector_size; // DWARF 5 91 92private: 93 bool isCopy; 94 unsigned char *data; 95 bool bounds_violation (uint64_t sz); 96}; 97 98class DwrFileName 99{ 100public: 101 DwrFileName (char *_fname); 102 ~DwrFileName (); 103 uint64_t timestamp; 104 uint64_t file_size; 105 int dir_index; 106 char *fname; 107 char *path; 108 bool isUsed; 109}; 110 111class DwrLine 112{ 113public: 114 DwrLine (); 115 ~DwrLine (); 116 uint64_t address; 117 uint32_t file; 118 uint32_t line; 119 uint32_t column; 120}; 121 122class DwrInlinedSubr 123{ 124public: 125 DwrInlinedSubr (int64_t _abstract_origin, uint64_t _low_pc, uint64_t _high_pc, 126 int _file, int _line, int _level); 127 void dump (); 128 int64_t abstract_origin; 129 uint64_t low_pc; 130 uint64_t high_pc; 131 int file; 132 int line; 133 int level; 134}; 135 136class DwrLineRegs 137{ 138public: 139 DwrLineRegs (Dwarf *_dwarf, DwrSec *_secp, char *dirName); 140 ~DwrLineRegs (); 141 char *getPath (int fn); 142 Vector<DwrLine *> *get_lines (); 143 void dump (); 144 145 Vector<DwrFileName *> *file_names; 146 147private: 148 void DoExtendedOpcode (); 149 void DoStandardOpcode (int opcode); 150 void DoSpecialOpcode (int opcode); 151 void EmitLine (); 152 void reset (); 153 Vector <DwrFileName *> *read_file_names_dwarf5 (); 154 155 Dwarf *dwarf; 156 char *fname; 157 uint64_t dir_index; 158 uint64_t timestamp; 159 uint64_t file_size; 160 uint64_t address; 161 int file; 162 int line; 163 int column; 164 Dwarf_Half version; 165 uint64_t op_index_register; 166 Dwarf_Small maximum_operations_per_instruction; 167 Dwarf_Small minimum_instruction_length; 168 Dwarf_Small default_is_stmt; 169 Dwarf_Small line_range; 170 Dwarf_Small opcode_base; 171 signed char line_base; 172 bool is_stmt; 173 bool basic_block; 174 bool end_sequence; 175 Vector<DwrLine *> *lines; 176 Vector<DwrFileName *> *dir_names; 177 Dwarf_Small *standard_opcode_length; 178 DwrSec *debug_lineSec; 179 uint64_t header_length; 180 uint64_t opcode_start; 181}; 182 183typedef struct Dwr_Attr 184{ 185 union 186 { 187 char *str; 188 unsigned char *block; 189 uint64_t offset; 190 int64_t val; 191 } u; 192 uint64_t len; // length of u.str 193 int at_form; 194 int at_name; 195} Dwr_Attr; 196 197typedef struct Dwr_Tag 198{ 199public: 200 Dwr_Attr *get_attr (Dwarf_Half attr); 201 void dump (); 202 203 DbeArray<Dwr_Attr> *abbrevAtForm; 204 int64_t die; 205 int64_t offset; 206 int firstAttribute; 207 int lastAttribute; 208 int tag; 209 int hasChild; 210 int num; 211 int level; 212} Dwr_Tag; 213 214enum 215{ 216 DW_DLV_OK, 217 DW_DLV_NO_ENTRY, 218 DW_DLV_ERROR, 219 DW_DLV_BAD_ELF, 220 DW_DLV_NO_DWARF, 221 DW_DLV_WRONG_ARG 222}; 223 224typedef struct DwrLocation 225{ 226 uint64_t offset; 227 uint64_t lc_number; 228 uint64_t lc_number2; 229 uint32_t op; 230} DwrLocation; 231 232typedef struct DwrAbbrevTable 233{ 234 int64_t offset; 235 int firstAtForm; 236 int lastAtForm; 237 int code; 238 int tag; 239 bool hasChild; 240} DwrAbbrevTable; 241 242class Dwarf_cnt 243{ 244public: 245 Dwarf_cnt (); 246 int64_t cu_offset; 247 int64_t parent; 248 int64_t size; 249 Module *module; 250 char *name; 251 Function *func; 252 Function *fortranMAIN; 253 datatype_t *dtype; 254 DwrInlinedSubr *inlinedSubr; 255 DefaultMap <int64_t, Dwr_type*> *dwr_types; 256 int level; 257 258 Dwr_type *get_dwr_type (int64_t cu_die_offset); 259 Dwr_type *put_dwr_type (int64_t cu_die_offset, int tag); 260 Dwr_type *put_dwr_type (Dwr_Tag *dwrTag); 261}; 262 263class DwrCU 264{ 265public: 266 DwrCU (Dwarf *_dwarf); 267 ~DwrCU (); 268 Module *parse_cu_header (LoadObject *lo); 269 void parseChild (Dwarf_cnt *ctx); 270 void read_hwcprof_info (Dwarf_cnt *ctx); 271 void map_dwarf_lines (Module *mod); 272 int set_die (Dwarf_Die die); 273 DwrLineRegs *get_dwrLineReg (); 274 275 static char *at2str (int tag); 276 static char *form2str (int tag); 277 static char *tag2str (int tag); 278 static char *lnct2str (int ty); 279 280 uint64_t cu_header_offset; 281 uint64_t cu_offset; 282 uint64_t next_cu_offset; 283 Vector<DwrInlinedSubr*> *dwrInlinedSubrs; 284 Vector<SourceFile *> *srcFiles; 285 bool isMemop; 286 bool isGNU; 287 288private: 289 void build_abbrevTable (DwrSec *debug_abbrevSec, uint64_t stmt_list_offset); 290 Function *append_Function (Dwarf_cnt *ctx); 291 void parse_inlined_subroutine (Dwarf_cnt *ctx); 292 uint64_t get_low_pc (); 293 uint64_t get_high_pc (uint64_t low_pc); 294 DwrLocation *dwr_get_location (DwrSec *secp, DwrLocation *lp); 295 int read_data_attr (Dwarf_Half attr, int64_t *retVal); 296 int read_ref_attr (Dwarf_Half attr, int64_t *retVal); 297 char *get_linkage_name (); 298 char *Dwarf_string (Dwarf_Half attr); 299 int64_t Dwarf_data (Dwarf_Half attr); 300 int64_t Dwarf_ref (Dwarf_Half attr); 301 DwrSec *Dwarf_block (Dwarf_Half attr); 302 Dwarf_Addr Dwarf_addr (Dwarf_Half attr); 303 Dwarf_Addr Dwarf_location (Dwarf_Attribute attr); 304 Sp_lang_code Dwarf_lang (); 305 306 Dwarf *dwarf; 307 DwrSec *debug_infoSec; 308 uint64_t debug_abbrev_offset; 309 uint64_t stmt_list_offset; // offset in .debug_line section (DW_AT_stmt_list) 310 char *comp_dir; // compilation directory (DW_AT_comp_dir) 311 Module *module; 312 int unit_type; 313 Dwarf_Half version; 314 Dwarf_Small address_size; 315 Dwr_Tag dwrTag; 316 DwrLineRegs *dwrLineReg; 317 DbeArray<DwrAbbrevTable> *abbrevTable; 318 DbeArray<Dwr_Attr> *abbrevAtForm; 319}; 320 321#endif /* _DWARFLIB_H_ */ 322