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