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