1 /* Copyright (C) 2021-2023 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 ();
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
92 private:
93 bool isCopy;
94 unsigned char *data;
95 bool bounds_violation (uint64_t sz);
96 };
97
98 class DwrFileName
99 {
100 public:
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
111 class DwrLine
112 {
113 public:
114 DwrLine ();
115 ~DwrLine ();
116 uint64_t address;
117 uint32_t file;
118 uint32_t line;
119 uint32_t column;
120 };
121
122 class DwrInlinedSubr
123 {
124 public:
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
136 class DwrLineRegs
137 {
138 public:
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
147 private:
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
183 typedef 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
197 typedef struct Dwr_Tag
198 {
199 public:
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
214 enum
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
224 typedef struct DwrLocation
225 {
226 uint64_t offset;
227 uint64_t lc_number;
228 uint64_t lc_number2;
229 uint32_t op;
230 } DwrLocation;
231
232 typedef 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
242 class Dwarf_cnt
243 {
244 public:
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
263 class DwrCU
264 {
265 public:
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
288 private:
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_ */