Rizin
unix-like reverse engineering framework and cli tools
dwarf.c File Reference
#include <errno.h>
#include <rz_bin.h>
#include <rz_bin_dwarf.h>
#include <rz_core.h>

Go to the source code of this file.

Macros

#define D0   if (1)
 
#define D1   if (1)
 
#define DWARF_DUMP   0
 
#define DBGFD   NULL
 
#define STANDARD_OPERAND_COUNT_DWARF2   9
 
#define STANDARD_OPERAND_COUNT_DWARF3   12
 
#define RZ_BIN_DWARF_INFO   1
 
#define READ8(buf)
 
#define READ16(buf)
 
#define READ32(buf)
 
#define READ64(buf)
 

Functions

RZ_API const char * rz_bin_dwarf_get_tag_name (ut64 tag)
 
RZ_API const char * rz_bin_dwarf_get_attr_name (ut64 attr_code)
 
RZ_API const char * rz_bin_dwarf_get_attr_form_name (ut64 form_code)
 
RZ_API const char * rz_bin_dwarf_get_unit_type_name (ut64 unit_type)
 
RZ_API const char * rz_bin_dwarf_get_lang_name (ut64 lang)
 
static int abbrev_cmp (const void *a, const void *b)
 
static ut64 dwarf_read_initial_length (RZ_OUT bool *is_64bit, bool big_endian, const ut8 **buf, const ut8 *buf_end)
 Read an "initial length" value, as specified by dwarf. This also determines whether it is 64bit or 32bit and reads 4 or 12 bytes respectively. More...
 
static ut64 dwarf_read_offset (bool is_64bit, bool big_endian, const ut8 **buf, const ut8 *buf_end)
 Reads 64/32 bit unsigned based on format. More...
 
static ut64 dwarf_read_address (size_t size, bool big_endian, const ut8 **buf, const ut8 *buf_end)
 
static void line_header_fini (RzBinDwarfLineHeader *hdr)
 
static const ut8parse_line_header_source (RzBinFile *bf, const ut8 *buf, const ut8 *buf_end, RzBinDwarfLineHeader *hdr)
 
RZ_API char * rz_bin_dwarf_line_header_get_full_file_path (RZ_NULLABLE const RzBinDwarfDebugInfo *info, const RzBinDwarfLineHeader *header, ut64 file_index)
 
RZ_API RzBinDwarfLineFileCache rz_bin_dwarf_line_header_new_file_cache (const RzBinDwarfLineHeader *hdr)
 
RZ_API void rz_bin_dwarf_line_header_free_file_cache (const RzBinDwarfLineHeader *hdr, RzBinDwarfLineFileCache fnc)
 
static const char * get_full_file_path (const RzBinDwarfDebugInfo *info, const RzBinDwarfLineHeader *header, RZ_NULLABLE RzBinDwarfLineFileCache cache, ut64 file_index)
 
RZ_API ut64 rz_bin_dwarf_line_header_get_adj_opcode (const RzBinDwarfLineHeader *header, ut8 opcode)
 
RZ_API ut64 rz_bin_dwarf_line_header_get_spec_op_advance_pc (const RzBinDwarfLineHeader *header, ut8 opcode)
 
RZ_API st64 rz_bin_dwarf_line_header_get_spec_op_advance_line (const RzBinDwarfLineHeader *header, ut8 opcode)
 
static const ut8parse_line_header (RzBinFile *bf, const ut8 *buf, const ut8 *buf_end, RzBinDwarfLineHeader *hdr, ut64 offset_cur, bool big_endian)
 
RZ_API void rz_bin_dwarf_line_op_fini (RzBinDwarfLineOp *op)
 
static const ut8parse_ext_opcode (RzBinDwarfLineOp *op, const RzBinDwarfLineHeader *hdr, const ut8 *obuf, size_t len, bool big_endian, ut8 target_addr_size)
 
static size_t std_opcode_args_count (const RzBinDwarfLineHeader *hdr, ut8 opcode)
 
static const ut8parse_std_opcode (RzBinDwarfLineOp *op, const RzBinDwarfLineHeader *hdr, const ut8 *obuf, size_t len, ut8 opcode, bool big_endian)
 
RZ_API void rz_bin_dwarf_line_header_reset_regs (const RzBinDwarfLineHeader *hdr, RzBinDwarfSMRegisters *regs)
 
static void store_line_sample (RzBinSourceLineInfoBuilder *bob, const RzBinDwarfLineHeader *hdr, RzBinDwarfSMRegisters *regs, RZ_NULLABLE RzBinDwarfDebugInfo *info, RZ_NULLABLE RzBinDwarfLineFileCache fnc)
 
RZ_API bool rz_bin_dwarf_line_op_run (const RzBinDwarfLineHeader *hdr, RzBinDwarfSMRegisters *regs, RzBinDwarfLineOp *op, RZ_NULLABLE RzBinSourceLineInfoBuilder *bob, RZ_NULLABLE RzBinDwarfDebugInfo *info, RZ_NULLABLE RzBinDwarfLineFileCache fnc)
 Execute a single line op on regs and optionally store the resulting line info in bob. More...
 
static size_t parse_opcodes (const ut8 *obuf, size_t len, const RzBinDwarfLineHeader *hdr, RzVector *ops_out, RzBinDwarfSMRegisters *regs, RZ_NULLABLE RzBinSourceLineInfoBuilder *bob, RZ_NULLABLE RzBinDwarfDebugInfo *info, RZ_NULLABLE RzBinDwarfLineFileCache fnc, bool big_endian, ut8 target_addr_size)
 
static void line_unit_free (RzBinDwarfLineUnit *unit)
 
static RzBinDwarfLineInfoparse_line_raw (RzBinFile *binfile, const ut8 *obuf, ut64 len, RzBinDwarfLineInfoMask mask, bool big_endian, RZ_NULLABLE RzBinDwarfDebugInfo *info)
 
RZ_API void rz_bin_dwarf_arange_set_free (RzBinDwarfARangeSet *set)
 
static RzListparse_aranges_raw (const ut8 *obuf, size_t obuf_sz, bool big_endian)
 
static void free_ht_comp_dir (HtUPKv *kv)
 
static bool init_debug_info (RzBinDwarfDebugInfo *inf)
 
static int init_die (RzBinDwarfDie *die, ut64 abbr_code, ut64 attr_count)
 
static int init_comp_unit (RzBinDwarfCompUnit *cu)
 
static int expand_cu (RzBinDwarfCompUnit *cu)
 
static int init_abbrev_decl (RzBinDwarfAbbrevDecl *ad)
 
static int expand_abbrev_decl (RzBinDwarfAbbrevDecl *ad)
 
static int init_debug_abbrev (RzBinDwarfDebugAbbrev *da)
 
static int expand_debug_abbrev (RzBinDwarfDebugAbbrev *da)
 
RZ_API void rz_bin_dwarf_debug_abbrev_free (RzBinDwarfDebugAbbrev *da)
 
RZ_API void rz_bin_dwarf_line_info_free (RzBinDwarfLineInfo *li)
 
static void free_attr_value (RzBinDwarfAttrValue *val)
 
static void free_die (RzBinDwarfDie *die)
 
static void free_comp_unit (RzBinDwarfCompUnit *cu)
 
RZ_API void rz_bin_dwarf_debug_info_free (RzBinDwarfDebugInfo *inf)
 
static const ut8fill_block_data (const ut8 *buf, const ut8 *buf_end, RzBinDwarfBlock *block)
 
static const ut8parse_attr_value (const ut8 *obuf, int obuf_len, RzBinDwarfAttrDef *def, RzBinDwarfAttrValue *value, const RzBinDwarfCompUnitHdr *hdr, const ut8 *debug_str, size_t debug_str_len, bool big_endian)
 Parses attribute value based on its definition and stores it into value More...
 
static const ut8parse_die (const ut8 *buf, const ut8 *buf_end, RzBinDwarfDebugInfo *info, RzBinDwarfAbbrevDecl *abbrev, RzBinDwarfCompUnitHdr *hdr, RzBinDwarfDie *die, const ut8 *debug_str, size_t debug_str_len, bool big_endian)
 
static const ut8parse_comp_unit (RzBinDwarfDebugInfo *info, const ut8 *buf_start, RzBinDwarfCompUnit *unit, const RzBinDwarfDebugAbbrev *abbrevs, size_t first_abbr_idx, const ut8 *debug_str, size_t debug_str_len, bool big_endian)
 Reads throught comp_unit buffer and parses all its DIEntries. More...
 
static const ut8info_comp_unit_read_hdr (const ut8 *buf, const ut8 *buf_end, RzBinDwarfCompUnitHdr *hdr, bool big_endian)
 Reads all information about compilation unit header. More...
 
static int expand_info (RzBinDwarfDebugInfo *info)
 
static RzBinDwarfDebugInfoparse_info_raw (RzBinDwarfDebugAbbrev *da, const ut8 *obuf, size_t len, const ut8 *debug_str, size_t debug_str_len, bool big_endian)
 Parses whole .debug_info section. More...
 
static RzBinDwarfDebugAbbrevparse_abbrev_raw (const ut8 *obuf, size_t len)
 
static RzBinSectiongetsection (RzBinFile *binfile, const char *sn)
 
static ut8get_section_bytes (RzBinFile *binfile, const char *sect_name, size_t *len)
 
RZ_API RzBinDwarfDebugInforz_bin_dwarf_parse_info (RzBinFile *binfile, RzBinDwarfDebugAbbrev *da)
 Parses .debug_info section. More...
 
RZ_API RzBinDwarfLineInforz_bin_dwarf_parse_line (RzBinFile *binfile, RZ_NULLABLE RzBinDwarfDebugInfo *info, RzBinDwarfLineInfoMask mask)
 
RZ_API RzListrz_bin_dwarf_parse_aranges (RzBinFile *binfile)
 
RZ_API RzBinDwarfDebugAbbrevrz_bin_dwarf_parse_abbrev (RzBinFile *binfile)
 
static ut64 get_max_offset (size_t addr_size)
 
static RzBinDwarfLocListcreate_loc_list (ut64 offset)
 
static RzBinDwarfLocRangecreate_loc_range (ut64 start, ut64 end, RzBinDwarfBlock *block)
 
static void free_loc_table_list (RzBinDwarfLocList *loc_list)
 
static HtUP * parse_loc_raw (HtUP *loc_table, const ut8 *buf, size_t len, size_t addr_size, bool big_endian)
 
RZ_API HtUP * rz_bin_dwarf_parse_loc (RzBinFile *binfile, int addr_size)
 Parses out the .debug_loc section into a table that maps each list as offset of a list -> LocationList. More...
 
static void free_loc_table_entry (HtUPKv *kv)
 
RZ_API void rz_bin_dwarf_loc_free (HtUP *loc_table)
 

Variables

static const char * dwarf_tag_name_encodings []
 
static const char * dwarf_attr_encodings []
 
static const char * dwarf_attr_form_encodings []
 
static const char * dwarf_langs []
 
static const char * dwarf_unit_types []
 

Macro Definition Documentation

◆ D0

#define D0   if (1)

Definition at line 5 of file dwarf.c.

◆ D1

#define D1   if (1)

Definition at line 6 of file dwarf.c.

◆ DBGFD

#define DBGFD   NULL

Definition at line 15 of file dwarf.c.

◆ DWARF_DUMP

#define DWARF_DUMP   0

Definition at line 10 of file dwarf.c.

◆ READ16

#define READ16 (   buf)
Value:
(((buf) + sizeof(ut16) < buf_end) ? rz_read_ble16(buf, big_endian) : 0); \
(buf) += sizeof(ut16)
uint16_t ut16
voidpf void * buf
Definition: ioapi.h:138
static ut16 rz_read_ble16(const void *src, bool big_endian)
Definition: rz_endian.h:493

Definition at line 29 of file dwarf.c.

◆ READ32

#define READ32 (   buf)
Value:
(((buf) + sizeof(ut32) < buf_end) ? rz_read_ble32(buf, big_endian) : 0); \
(buf) += sizeof(ut32)
uint32_t ut32
static ut32 rz_read_ble32(const void *src, bool big_endian)
Definition: rz_endian.h:497

Definition at line 32 of file dwarf.c.

◆ READ64

#define READ64 (   buf)
Value:
(((buf) + sizeof(ut64) < buf_end) ? rz_read_ble64(buf, big_endian) : 0); \
(buf) += sizeof(ut64)
static ut64 rz_read_ble64(const void *src, bool big_endian)
Definition: rz_endian.h:501
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

Definition at line 35 of file dwarf.c.

◆ READ8

#define READ8 (   buf)
Value:
(((buf) + 1 < buf_end) ? *((ut8 *)(buf)) : 0); \
(buf)++
uint8_t ut8
Definition: lh5801.h:11

Definition at line 26 of file dwarf.c.

◆ RZ_BIN_DWARF_INFO

#define RZ_BIN_DWARF_INFO   1

Definition at line 24 of file dwarf.c.

◆ STANDARD_OPERAND_COUNT_DWARF2

#define STANDARD_OPERAND_COUNT_DWARF2   9

Definition at line 22 of file dwarf.c.

◆ STANDARD_OPERAND_COUNT_DWARF3

#define STANDARD_OPERAND_COUNT_DWARF3   12

Definition at line 23 of file dwarf.c.

Function Documentation

◆ abbrev_cmp()

static int abbrev_cmp ( const void *  a,
const void *  b 
)
static

Definition at line 394 of file dwarf.c.

394  {
395  const RzBinDwarfAbbrevDecl *first = a;
396  const RzBinDwarfAbbrevDecl *second = b;
397 
398  if (first->offset > second->offset) {
399  return 1;
400  } else if (first->offset < second->offset) {
401  return -1;
402  } else {
403  return 0;
404  }
405 }
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41

References a, b, and RzBinDwarfAbbrevDecl::offset.

Referenced by parse_info_raw().

◆ create_loc_list()

static RzBinDwarfLocList* create_loc_list ( ut64  offset)
inlinestatic

Definition at line 2168 of file dwarf.c.

2168  {
2170  if (list) {
2171  list->list = rz_list_new();
2172  list->offset = offset;
2173  }
2174  return list;
2175 }
voidpf uLong offset
Definition: ioapi.h:144
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
#define RZ_NEW0(x)
Definition: rz_types.h:284

References list(), rz_list_new(), and RZ_NEW0.

Referenced by parse_loc_raw().

◆ create_loc_range()

static RzBinDwarfLocRange* create_loc_range ( ut64  start,
ut64  end,
RzBinDwarfBlock block 
)
inlinestatic

Definition at line 2177 of file dwarf.c.

2177  {
2179  if (range) {
2180  range->start = start;
2181  range->end = end;
2182  range->expression = block;
2183  }
2184  return range;
2185 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
Definition: rz_bin_dwarf.h:912

References test_evm::end, capstone::range, RZ_NEW0, and start.

Referenced by parse_loc_raw().

◆ dwarf_read_address()

static ut64 dwarf_read_address ( size_t  size,
bool  big_endian,
const ut8 **  buf,
const ut8 buf_end 
)
inlinestatic

Definition at line 440 of file dwarf.c.

440  {
441  ut64 result;
442  switch (size) {
443  case 2:
444  result = READ16(*buf);
445  break;
446  case 4:
447  result = READ32(*buf);
448  break;
449  case 8:
450  result = READ64(*buf);
451  break;
452  default:
453  result = 0;
454  *buf += size;
455  RZ_LOG_WARN("Weird dwarf address size: %zu.", size);
456  }
457  return result;
458 }
#define READ16(buf)
Definition: dwarf.c:29
#define READ64(buf)
Definition: dwarf.c:35
#define READ32(buf)
Definition: dwarf.c:32
voidpf void uLong size
Definition: ioapi.h:138
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56

References READ16, READ32, READ64, RZ_LOG_WARN, and ut64().

Referenced by parse_aranges_raw(), parse_ext_opcode(), and parse_loc_raw().

◆ dwarf_read_initial_length()

static ut64 dwarf_read_initial_length ( RZ_OUT bool is_64bit,
bool  big_endian,
const ut8 **  buf,
const ut8 buf_end 
)
inlinestatic

Read an "initial length" value, as specified by dwarf. This also determines whether it is 64bit or 32bit and reads 4 or 12 bytes respectively.

Definition at line 411 of file dwarf.c.

411  {
412  ut64 r = READ32(*buf);
413  if (r == DWARF_INIT_LEN_64) {
414  r = READ64(*buf);
415  *is_64bit = true;
416  } else {
417  *is_64bit = false;
418  }
419  return r;
420 }
#define r
Definition: crypto_rc6.c:12
#define DWARF_INIT_LEN_64
Definition: rz_bin_dwarf.h:652

References DWARF_INIT_LEN_64, r, READ32, READ64, and ut64().

Referenced by parse_aranges_raw(), and parse_line_header().

◆ dwarf_read_offset()

static ut64 dwarf_read_offset ( bool  is_64bit,
bool  big_endian,
const ut8 **  buf,
const ut8 buf_end 
)
inlinestatic

Reads 64/32 bit unsigned based on format.

Parameters
is_64bitFormat of the comp unit
bufPointer to the buffer to read from, to update after read
buf_endTo check the boundary /for READ macro/
Returns
ut64 Read value

Definition at line 430 of file dwarf.c.

430  {
431  ut64 result;
432  if (is_64bit) {
433  result = READ64(*buf);
434  } else {
435  result = READ32(*buf);
436  }
437  return result;
438 }

References READ32, READ64, and ut64().

Referenced by info_comp_unit_read_hdr(), parse_aranges_raw(), parse_attr_value(), and parse_line_header().

◆ expand_abbrev_decl()

static int expand_abbrev_decl ( RzBinDwarfAbbrevDecl ad)
static

Definition at line 1281 of file dwarf.c.

1281  {
1283 
1284  if (!ad || !ad->capacity || ad->capacity != ad->count) {
1285  return -EINVAL;
1286  }
1287 
1288  tmp = (RzBinDwarfAttrDef *)realloc(ad->defs,
1289  ad->capacity * 2 * sizeof(RzBinDwarfAttrDef));
1290 
1291  if (!tmp) {
1292  return -ENOMEM;
1293  }
1294 
1295  // Set the area in the buffer past the length to 0
1296  memset((ut8 *)tmp + ad->capacity * sizeof(RzBinDwarfAttrDef),
1297  0, ad->capacity * sizeof(RzBinDwarfAttrDef));
1298  ad->defs = tmp;
1299  ad->capacity *= 2;
1300 
1301  return 0;
1302 }
return memset(p, 0, total)
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
#define EINVAL
Definition: sftypes.h:132
#define ENOMEM
Definition: sftypes.h:122
RzBinDwarfAttrDef * defs
Definition: rz_bin_dwarf.h:793

References RzBinDwarfAbbrevDecl::capacity, RzBinDwarfAbbrevDecl::count, RzBinDwarfAbbrevDecl::defs, EINVAL, ENOMEM, memset(), realloc(), and autogen_x86imm::tmp.

Referenced by parse_abbrev_raw().

◆ expand_cu()

static int expand_cu ( RzBinDwarfCompUnit cu)
static

Definition at line 1244 of file dwarf.c.

1244  {
1245  RzBinDwarfDie *tmp;
1246 
1247  if (!cu || cu->capacity == 0 || cu->capacity != cu->count) {
1248  return -EINVAL;
1249  }
1250 
1251  tmp = (RzBinDwarfDie *)realloc(cu->dies,
1252  cu->capacity * 2 * sizeof(RzBinDwarfDie));
1253  if (!tmp) {
1254  return -ENOMEM;
1255  }
1256 
1257  memset((ut8 *)tmp + cu->capacity * sizeof(RzBinDwarfDie),
1258  0, cu->capacity * sizeof(RzBinDwarfDie));
1259  cu->dies = tmp;
1260  cu->capacity *= 2;
1261 
1262  return 0;
1263 }
RzBinDwarfDie * dies
Definition: rz_bin_dwarf.h:764

References RzBinDwarfCompUnit::capacity, RzBinDwarfCompUnit::count, RzBinDwarfCompUnit::dies, EINVAL, ENOMEM, memset(), realloc(), and autogen_x86imm::tmp.

Referenced by parse_comp_unit().

◆ expand_debug_abbrev()

static int expand_debug_abbrev ( RzBinDwarfDebugAbbrev da)
static

Definition at line 1318 of file dwarf.c.

1318  {
1320 
1321  if (!da || da->capacity == 0 || da->capacity != da->count) {
1322  return -EINVAL;
1323  }
1324 
1326  da->capacity * 2 * sizeof(RzBinDwarfAbbrevDecl));
1327 
1328  if (!tmp) {
1329  return -ENOMEM;
1330  }
1331  memset((ut8 *)tmp + da->capacity * sizeof(RzBinDwarfAbbrevDecl),
1332  0, da->capacity * sizeof(RzBinDwarfAbbrevDecl));
1333 
1334  da->decls = tmp;
1335  da->capacity *= 2;
1336 
1337  return 0;
1338 }
RzBinDwarfAbbrevDecl * decls
Definition: rz_bin_dwarf.h:801

References RzBinDwarfDebugAbbrev::capacity, RzBinDwarfDebugAbbrev::count, RzBinDwarfDebugAbbrev::decls, EINVAL, ENOMEM, memset(), realloc(), and autogen_x86imm::tmp.

Referenced by parse_abbrev_raw().

◆ expand_info()

static int expand_info ( RzBinDwarfDebugInfo info)
static

Definition at line 1868 of file dwarf.c.

1868  {
1869  rz_return_val_if_fail(info && info->capacity == info->count, -1);
1870 
1871  RzBinDwarfCompUnit *tmp = realloc(info->comp_units,
1872  info->capacity * 2 * sizeof(RzBinDwarfCompUnit));
1873  if (!tmp) {
1874  return -1;
1875  }
1876 
1877  memset((ut8 *)tmp + info->capacity * sizeof(RzBinDwarfCompUnit),
1878  0, info->capacity * sizeof(RzBinDwarfCompUnit));
1879 
1880  info->comp_units = tmp;
1881  info->capacity *= 2;
1882 
1883  return 0;
1884 }
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108

References info(), memset(), realloc(), rz_return_val_if_fail, and autogen_x86imm::tmp.

Referenced by parse_info_raw().

◆ fill_block_data()

static const ut8* fill_block_data ( const ut8 buf,
const ut8 buf_end,
RzBinDwarfBlock block 
)
static

Definition at line 1420 of file dwarf.c.

1420  {
1421  block->data = calloc(sizeof(ut8), block->length);
1422  if (!block->data) {
1423  return NULL;
1424  }
1425  /* Maybe unroll this as an optimization in future? */
1426  if (block->data) {
1427  size_t j = 0;
1428  for (j = 0; j < block->length; j++) {
1429  block->data[j] = READ8(buf);
1430  }
1431  }
1432  return buf;
1433 }
#define NULL
Definition: cris-opc.c:27
#define READ8(buf)
Definition: dwarf.c:26
void * calloc(size_t number, size_t size)
Definition: malloc.c:102

References calloc(), RzBinDwarfBlock::data, RzBinDwarfBlock::length, NULL, and READ8.

Referenced by parse_attr_value(), and parse_loc_raw().

◆ free_attr_value()

static void free_attr_value ( RzBinDwarfAttrValue val)
static

Definition at line 1361 of file dwarf.c.

1361  {
1362  // TODO adjust to new forms, now we're leaking
1363  if (!val) {
1364  return;
1365  }
1366  switch (val->attr_form) {
1367  case DW_FORM_strp:
1368  case DW_FORM_string:
1369  RZ_FREE(val->string.content);
1370  break;
1371  case DW_FORM_exprloc:
1372  case DW_FORM_block:
1373  case DW_FORM_block1:
1374  case DW_FORM_block2:
1375  case DW_FORM_block4:
1376  RZ_FREE(val->block.data);
1377  break;
1378  default:
1379  break;
1380  };
1381 }
ut16 val
Definition: armass64_const.h:6
#define DW_FORM_exprloc
Definition: rz_bin_dwarf.h:301
#define DW_FORM_block2
Definition: rz_bin_dwarf.h:280
#define DW_FORM_block1
Definition: rz_bin_dwarf.h:287
#define DW_FORM_block
Definition: rz_bin_dwarf.h:286
#define DW_FORM_string
Definition: rz_bin_dwarf.h:285
#define DW_FORM_block4
Definition: rz_bin_dwarf.h:281
#define DW_FORM_strp
Definition: rz_bin_dwarf.h:291
#define RZ_FREE(x)
Definition: rz_types.h:369

References DW_FORM_block, DW_FORM_block1, DW_FORM_block2, DW_FORM_block4, DW_FORM_exprloc, DW_FORM_string, DW_FORM_strp, RZ_FREE, and val.

Referenced by free_die().

◆ free_comp_unit()

static void free_comp_unit ( RzBinDwarfCompUnit cu)
static

Definition at line 1394 of file dwarf.c.

1394  {
1395  size_t i;
1396  if (!cu) {
1397  return;
1398  }
1399  for (i = 0; i < cu->count; i++) {
1400  if (cu->dies) {
1401  free_die(&cu->dies[i]);
1402  }
1403  }
1404  RZ_FREE(cu->dies);
1405 }
lzma_index ** i
Definition: index.h:629
static void free_die(RzBinDwarfDie *die)
Definition: dwarf.c:1383

References RzBinDwarfCompUnit::count, RzBinDwarfCompUnit::dies, free_die(), i, and RZ_FREE.

Referenced by rz_bin_dwarf_debug_info_free().

◆ free_die()

static void free_die ( RzBinDwarfDie die)
static

Definition at line 1383 of file dwarf.c.

1383  {
1384  size_t i;
1385  if (!die) {
1386  return;
1387  }
1388  for (i = 0; i < die->count; i++) {
1389  free_attr_value(&die->attr_values[i]);
1390  }
1391  RZ_FREE(die->attr_values);
1392 }
static void free_attr_value(RzBinDwarfAttrValue *val)
Definition: dwarf.c:1361
RzBinDwarfAttrValue * attr_values
Definition: rz_bin_dwarf.h:756

References RzBinDwarfDie::attr_values, RzBinDwarfDie::count, free_attr_value(), i, and RZ_FREE.

Referenced by free_comp_unit().

◆ free_ht_comp_dir()

static void free_ht_comp_dir ( HtUPKv *  kv)
static

Definition at line 1192 of file dwarf.c.

1192  {
1193  free(kv->value);
1194 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130

References free().

Referenced by init_debug_info().

◆ free_loc_table_entry()

static void free_loc_table_entry ( HtUPKv *  kv)
static

Definition at line 2277 of file dwarf.c.

2277  {
2278  if (kv) {
2279  free_loc_table_list(kv->value);
2280  }
2281 }
static void free_loc_table_list(RzBinDwarfLocList *loc_list)
Definition: dwarf.c:2187

References free_loc_table_list().

Referenced by rz_bin_dwarf_loc_free().

◆ free_loc_table_list()

static void free_loc_table_list ( RzBinDwarfLocList loc_list)
static

Definition at line 2187 of file dwarf.c.

2187  {
2188  RzListIter *iter;
2190  rz_list_foreach (loc_list->list, iter, range) {
2191  free(range->expression->data);
2192  free(range->expression);
2193  free(range);
2194  }
2195  rz_list_free(loc_list->list);
2196  free(loc_list);
2197 }
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137

References free(), rz_bin_dwarf_loc_list_t::list, capstone::range, and rz_list_free().

Referenced by free_loc_table_entry(), and parse_loc_raw().

◆ get_full_file_path()

static const char* get_full_file_path ( const RzBinDwarfDebugInfo info,
const RzBinDwarfLineHeader header,
RZ_NULLABLE RzBinDwarfLineFileCache  cache,
ut64  file_index 
)
static

Definition at line 599 of file dwarf.c.

600  {
601  if (file_index >= header->file_names_count) {
602  return NULL;
603  }
604  if (!cache) {
605  return header->file_names[file_index].name;
606  }
607  if (!cache[file_index]) {
608  cache[file_index] = rz_bin_dwarf_line_header_get_full_file_path(info, header, file_index);
609  }
610  return cache[file_index];
611 }
RZ_API char * rz_bin_dwarf_line_header_get_full_file_path(RZ_NULLABLE const RzBinDwarfDebugInfo *info, const RzBinDwarfLineHeader *header, ut64 file_index)
Definition: dwarf.c:547
#define header(is_bt, len_min, ret_op)

References header, info(), NULL, and rz_bin_dwarf_line_header_get_full_file_path().

Referenced by store_line_sample().

◆ get_max_offset()

static ut64 get_max_offset ( size_t  addr_size)
inlinestatic

Definition at line 2156 of file dwarf.c.

2156  {
2157  switch (addr_size) {
2158  case 2:
2159  return UT16_MAX;
2160  case 4:
2161  return UT32_MAX;
2162  case 8:
2163  return UT64_MAX;
2164  }
2165  return 0;
2166 }
#define UT32_MAX
Definition: rz_types_base.h:99
#define UT64_MAX
Definition: rz_types_base.h:86
#define UT16_MAX

References UT16_MAX, UT32_MAX, and UT64_MAX.

Referenced by parse_loc_raw().

◆ get_section_bytes()

static ut8* get_section_bytes ( RzBinFile binfile,
const char *  sect_name,
size_t len 
)
static

Definition at line 2053 of file dwarf.c.

2053  {
2054  rz_return_val_if_fail(binfile && sect_name && len, NULL);
2055  RzBinSection *section = getsection(binfile, sect_name);
2056  if (!section) {
2057  return NULL;
2058  }
2059  if (section->paddr >= binfile->size) {
2060  return NULL;
2061  }
2062  *len = RZ_MIN(section->size, binfile->size - section->paddr);
2063  ut8 *buf = calloc(1, *len);
2064  rz_buf_read_at(binfile->buf, section->paddr, buf, *len);
2065  return buf;
2066 }
size_t len
Definition: 6502dis.c:15
static RzBinSection * getsection(RzBinFile *binfile, const char *sn)
Definition: dwarf.c:2034
RZ_API st64 rz_buf_read_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
Read len bytes of the buffer at the specified address.
Definition: buf.c:1136
#define RZ_MIN(x, y)
RzBuffer * buf
Definition: rz_bin.h:303
uint32_t size

References rz_bin_file_t::buf, calloc(), getsection(), len, NULL, rz_buf_read_at(), RZ_MIN, rz_return_val_if_fail, section::size, and rz_bin_file_t::size.

Referenced by rz_bin_dwarf_parse_abbrev(), rz_bin_dwarf_parse_aranges(), rz_bin_dwarf_parse_info(), rz_bin_dwarf_parse_line(), and rz_bin_dwarf_parse_loc().

◆ getsection()

static RzBinSection* getsection ( RzBinFile binfile,
const char *  sn 
)
static

Definition at line 2034 of file dwarf.c.

2034  {
2035  rz_return_val_if_fail(binfile && sn, NULL);
2036  RzListIter *iter;
2038  RzBinObject *o = binfile->o;
2039  if (!o || !o->sections) {
2040  return NULL;
2041  }
2042  rz_list_foreach (o->sections, iter, section) {
2043  if (!section->name) {
2044  continue;
2045  }
2046  if (strstr(section->name, sn)) {
2047  return section;
2048  }
2049  }
2050  return NULL;
2051 }
RzBinObject * o
Definition: rz_bin.h:305
RzList * sections
Definition: rz_bin.h:267

References NULL, rz_bin_file_t::o, rz_return_val_if_fail, and rz_bin_object_t::sections.

Referenced by get_section_bytes().

◆ info_comp_unit_read_hdr()

static const ut8* info_comp_unit_read_hdr ( const ut8 buf,
const ut8 buf_end,
RzBinDwarfCompUnitHdr hdr,
bool  big_endian 
)
static

Reads all information about compilation unit header.

Parameters
bufStart of the buffer
buf_endUpper bound of the buffer
unitUnit to read information into
Returns
ut8* Advanced position in a buffer

Definition at line 1840 of file dwarf.c.

1840  {
1841  // 32-bit vs 64-bit dwarf formats
1842  // http://www.dwarfstd.org/doc/Dwarf3.pdf section 7.4
1843  hdr->length = READ32(buf);
1844  if (hdr->length == (ut32)DWARF_INIT_LEN_64) { // then its 64bit
1845  hdr->length = READ64(buf);
1846  hdr->is_64bit = true;
1847  }
1848  const ut8 *tmp = buf; // to calculate header size
1849  hdr->version = READ16(buf);
1850  if (hdr->version == 5) {
1851  hdr->unit_type = READ8(buf);
1852  hdr->address_size = READ8(buf);
1853  hdr->abbrev_offset = dwarf_read_offset(hdr->is_64bit, big_endian, &buf, buf_end);
1854 
1855  if (hdr->unit_type == DW_UT_skeleton || hdr->unit_type == DW_UT_split_compile) {
1856  hdr->dwo_id = READ8(buf);
1857  } else if (hdr->unit_type == DW_UT_type || hdr->unit_type == DW_UT_split_type) {
1858  hdr->type_sig = READ64(buf);
1859  hdr->type_offset = dwarf_read_offset(hdr->is_64bit, big_endian, &buf, buf_end);
1860  }
1861  } else {
1862  hdr->abbrev_offset = dwarf_read_offset(hdr->is_64bit, big_endian, &buf, buf_end);
1863  hdr->address_size = READ8(buf);
1864  }
1865  hdr->header_size = buf - tmp; // header size excluding length field
1866  return buf;
1867 }
static ut64 dwarf_read_offset(bool is_64bit, bool big_endian, const ut8 **buf, const ut8 *buf_end)
Reads 64/32 bit unsigned based on format.
Definition: dwarf.c:430
#define DW_UT_split_type
Definition: rz_bin_dwarf.h:623
#define DW_UT_split_compile
Definition: rz_bin_dwarf.h:622
#define DW_UT_type
Definition: rz_bin_dwarf.h:619
#define DW_UT_skeleton
Definition: rz_bin_dwarf.h:621

References RzBinDwarfCompUnitHdr::abbrev_offset, RzBinDwarfCompUnitHdr::address_size, DW_UT_skeleton, DW_UT_split_compile, DW_UT_split_type, DW_UT_type, DWARF_INIT_LEN_64, dwarf_read_offset(), RzBinDwarfCompUnitHdr::dwo_id, RzBinDwarfCompUnitHdr::header_size, RzBinDwarfCompUnitHdr::is_64bit, RzBinDwarfCompUnitHdr::length, READ16, READ32, READ64, READ8, autogen_x86imm::tmp, RzBinDwarfCompUnitHdr::type_offset, RzBinDwarfCompUnitHdr::type_sig, RzBinDwarfCompUnitHdr::unit_type, and RzBinDwarfCompUnitHdr::version.

Referenced by parse_info_raw().

◆ init_abbrev_decl()

static int init_abbrev_decl ( RzBinDwarfAbbrevDecl ad)
static

Definition at line 1265 of file dwarf.c.

1265  {
1266  if (!ad) {
1267  return -EINVAL;
1268  }
1269  ad->defs = calloc(sizeof(RzBinDwarfAttrDef), ABBREV_DECL_CAP);
1270 
1271  if (!ad->defs) {
1272  return -ENOMEM;
1273  }
1274 
1275  ad->capacity = ABBREV_DECL_CAP;
1276  ad->count = 0;
1277 
1278  return 0;
1279 }
#define ABBREV_DECL_CAP
Definition: rz_bin_dwarf.h:784

References ABBREV_DECL_CAP, calloc(), RzBinDwarfAbbrevDecl::capacity, RzBinDwarfAbbrevDecl::count, RzBinDwarfAbbrevDecl::defs, EINVAL, and ENOMEM.

Referenced by parse_abbrev_raw().

◆ init_comp_unit()

static int init_comp_unit ( RzBinDwarfCompUnit cu)
static

Definition at line 1231 of file dwarf.c.

1231  {
1232  if (!cu) {
1233  return -EINVAL;
1234  }
1235  cu->dies = calloc(sizeof(RzBinDwarfDie), COMP_UNIT_CAPACITY);
1236  if (!cu->dies) {
1237  return -ENOMEM;
1238  }
1240  cu->count = 0;
1241  return 0;
1242 }
#define COMP_UNIT_CAPACITY
Definition: rz_bin_dwarf.h:767

References calloc(), RzBinDwarfCompUnit::capacity, COMP_UNIT_CAPACITY, RzBinDwarfCompUnit::count, RzBinDwarfCompUnit::dies, EINVAL, and ENOMEM.

Referenced by parse_info_raw().

◆ init_debug_abbrev()

static int init_debug_abbrev ( RzBinDwarfDebugAbbrev da)
static

Definition at line 1304 of file dwarf.c.

1304  {
1305  if (!da) {
1306  return -EINVAL;
1307  }
1309  if (!da->decls) {
1310  return -ENOMEM;
1311  }
1312  da->capacity = DEBUG_ABBREV_CAP;
1313  da->count = 0;
1314 
1315  return 0;
1316 }
#define DEBUG_ABBREV_CAP
Definition: rz_bin_dwarf.h:796

References calloc(), RzBinDwarfDebugAbbrev::capacity, RzBinDwarfDebugAbbrev::count, DEBUG_ABBREV_CAP, RzBinDwarfDebugAbbrev::decls, EINVAL, and ENOMEM.

Referenced by parse_abbrev_raw().

◆ init_debug_info()

static bool init_debug_info ( RzBinDwarfDebugInfo inf)
static

Definition at line 1196 of file dwarf.c.

1196  {
1198  if (!inf->comp_units) {
1199  return false;
1200  }
1201  inf->line_info_offset_comp_dir = ht_up_new(NULL, free_ht_comp_dir, NULL);
1202  if (!inf->line_info_offset_comp_dir) {
1203  goto wurzelbert_comp_units;
1204  }
1205  inf->capacity = DEBUG_INFO_CAPACITY;
1206  inf->count = 0;
1207  return true;
1208 wurzelbert_comp_units:
1209  RZ_FREE(inf->comp_units);
1210  return false;
1211 }
static void free_ht_comp_dir(HtUPKv *kv)
Definition: dwarf.c:1192
#define DEBUG_INFO_CAPACITY
Definition: rz_bin_dwarf.h:768
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
int inf(FILE *source, FILE *dest)
Definition: zpipe.c:92

References DEBUG_INFO_CAPACITY, free_ht_comp_dir(), inf(), NULL, RZ_FREE, and RZ_NEWS0.

Referenced by parse_info_raw().

◆ init_die()

static int init_die ( RzBinDwarfDie die,
ut64  abbr_code,
ut64  attr_count 
)
static

Definition at line 1213 of file dwarf.c.

1213  {
1214  if (!die) {
1215  return -1;
1216  }
1217  if (attr_count) {
1218  die->attr_values = calloc(sizeof(RzBinDwarfAttrValue), attr_count);
1219  if (!die->attr_values) {
1220  return -1;
1221  }
1222  } else {
1223  die->attr_values = NULL;
1224  }
1225  die->abbrev_code = abbr_code;
1226  die->capacity = attr_count;
1227  die->count = 0;
1228  return 0;
1229 }

References RzBinDwarfDie::abbrev_code, RzBinDwarfDie::attr_values, calloc(), RzBinDwarfDie::capacity, RzBinDwarfDie::count, and NULL.

Referenced by parse_comp_unit().

◆ line_header_fini()

static void line_header_fini ( RzBinDwarfLineHeader hdr)
static

Definition at line 460 of file dwarf.c.

460  {
461  if (hdr) {
462  for (size_t i = 0; i < hdr->file_names_count; i++) {
463  free(hdr->file_names[i].name);
464  }
465 
466  free(hdr->std_opcode_lengths);
467  free(hdr->file_names);
468 
469  if (hdr->include_dirs) {
470  for (size_t i = 0; i < hdr->include_dirs_count; i++) {
471  free(hdr->include_dirs[i]);
472  }
473  free(hdr->include_dirs);
474  }
475  }
476 }
ut8 * std_opcode_lengths
The number of LEB128 operands for each of the standard opcodes From standard_opcode_lengths in DWARF ...
Definition: rz_bin_dwarf.h:850
RzBinDwarfLineFileEntry * file_names
Definition: rz_bin_dwarf.h:854
char * name
Definition: rz_bin_dwarf.h:824

References RzBinDwarfLineHeader::file_names, RzBinDwarfLineHeader::file_names_count, free(), i, RzBinDwarfLineHeader::include_dirs, RzBinDwarfLineHeader::include_dirs_count, rz_bin_dwarf_line_file_entry_t::name, and RzBinDwarfLineHeader::std_opcode_lengths.

Referenced by line_unit_free().

◆ line_unit_free()

static void line_unit_free ( RzBinDwarfLineUnit unit)
static

Definition at line 982 of file dwarf.c.

982  {
983  if (!unit) {
984  return;
985  }
986  line_header_fini(&unit->header);
987  if (unit->ops) {
988  for (size_t i = 0; i < unit->ops_count; i++) {
990  }
991  free(unit->ops);
992  }
993  free(unit);
994 }
RZ_API void rz_bin_dwarf_line_op_fini(RzBinDwarfLineOp *op)
Definition: dwarf.c:699
static void line_header_fini(RzBinDwarfLineHeader *hdr)
Definition: dwarf.c:460
RzBinDwarfLineHeader header
Definition: rz_bin_dwarf.h:892
RzBinDwarfLineOp * ops
Definition: rz_bin_dwarf.h:895

References free(), RzBinDwarfLineUnit::header, i, line_header_fini(), RzBinDwarfLineUnit::ops, RzBinDwarfLineUnit::ops_count, and rz_bin_dwarf_line_op_fini().

Referenced by parse_line_raw().

◆ parse_abbrev_raw()

static RzBinDwarfDebugAbbrev* parse_abbrev_raw ( const ut8 obuf,
size_t  len 
)
static

Definition at line 1973 of file dwarf.c.

1973  {
1974  const ut8 *buf = obuf, *buf_end = obuf + len;
1975  ut64 tmp, attr_code, attr_form, offset;
1976  st64 special;
1977  ut8 has_children;
1978  RzBinDwarfAbbrevDecl *tmpdecl;
1979 
1980  // XXX - Set a suitable value here.
1981  if (!obuf || len < 3) {
1982  return NULL;
1983  }
1985 
1986  init_debug_abbrev(da);
1987 
1988  while (buf && buf + 1 < buf_end) {
1989  offset = buf - obuf;
1990  buf = rz_uleb128(buf, (size_t)(buf_end - buf), &tmp, NULL);
1991  if (!buf || !tmp || buf >= buf_end) {
1992  continue;
1993  }
1994  if (da->count == da->capacity) {
1995  expand_debug_abbrev(da);
1996  }
1997  tmpdecl = &da->decls[da->count];
1998  init_abbrev_decl(tmpdecl);
1999 
2000  tmpdecl->code = tmp;
2001  buf = rz_uleb128(buf, (size_t)(buf_end - buf), &tmp, NULL);
2002  tmpdecl->tag = tmp;
2003 
2004  tmpdecl->offset = offset;
2005  if (buf >= buf_end) {
2006  break;
2007  }
2008  has_children = READ8(buf);
2009  tmpdecl->has_children = has_children;
2010  do {
2011  if (tmpdecl->count == tmpdecl->capacity) {
2012  expand_abbrev_decl(tmpdecl);
2013  }
2014  buf = rz_uleb128(buf, (size_t)(buf_end - buf), &attr_code, NULL);
2015  if (buf >= buf_end) {
2016  break;
2017  }
2018  buf = rz_uleb128(buf, (size_t)(buf_end - buf), &attr_form, NULL);
2019  // http://www.dwarfstd.org/doc/DWARF5.pdf#page=225
2020  if (attr_form == DW_FORM_implicit_const) {
2021  buf = rz_leb128(buf, (size_t)(buf_end - buf), &special);
2022  tmpdecl->defs[tmpdecl->count].special = special;
2023  }
2024  tmpdecl->defs[tmpdecl->count].attr_name = attr_code;
2025  tmpdecl->defs[tmpdecl->count].attr_form = attr_form;
2026  tmpdecl->count++;
2027  } while (attr_code && attr_form);
2028 
2029  da->count++;
2030  }
2031  return da;
2032 }
static int init_debug_abbrev(RzBinDwarfDebugAbbrev *da)
Definition: dwarf.c:1304
static int init_abbrev_decl(RzBinDwarfAbbrevDecl *ad)
Definition: dwarf.c:1265
static int expand_debug_abbrev(RzBinDwarfDebugAbbrev *da)
Definition: dwarf.c:1318
static int expand_abbrev_decl(RzBinDwarfAbbrevDecl *ad)
Definition: dwarf.c:1281
static void special(struct parse *, int)
Definition: regcomp.c:1076
#define DW_FORM_implicit_const
Definition: rz_bin_dwarf.h:310
#define st64
Definition: rz_types_base.h:10
RZ_API const ut8 * rz_uleb128(const ut8 *data, int datalen, RZ_NULLABLE ut64 *v, const char **error)
Definition: uleb128.c:9
RZ_API const ut8 * rz_leb128(const ut8 *data, int datalen, st64 *v)
Definition: uleb128.c:117
static unsigned char * obuf
Definition: z80asm.c:36

References RzBinDwarfAttrDef::attr_form, RzBinDwarfAttrDef::attr_name, RzBinDwarfAbbrevDecl::capacity, RzBinDwarfDebugAbbrev::capacity, RzBinDwarfAbbrevDecl::code, RzBinDwarfAbbrevDecl::count, RzBinDwarfDebugAbbrev::count, RzBinDwarfDebugAbbrev::decls, RzBinDwarfAbbrevDecl::defs, DW_FORM_implicit_const, expand_abbrev_decl(), expand_debug_abbrev(), RzBinDwarfAbbrevDecl::has_children, init_abbrev_decl(), init_debug_abbrev(), len, NULL, obuf, RzBinDwarfAbbrevDecl::offset, READ8, rz_leb128(), RZ_NEW0, rz_uleb128(), RzBinDwarfAttrDef::special, special(), st64, RzBinDwarfAbbrevDecl::tag, autogen_x86imm::tmp, and ut64().

Referenced by rz_bin_dwarf_parse_abbrev().

◆ parse_aranges_raw()

static RzList* parse_aranges_raw ( const ut8 obuf,
size_t  obuf_sz,
bool  big_endian 
)
static

Definition at line 1114 of file dwarf.c.

1114  {
1116  const ut8 *buf = obuf;
1117  const ut8 *buf_end = buf + obuf_sz;
1118 
1120  if (!r) {
1121  return NULL;
1122  }
1123 
1124  // DWARF 3 Standard Section 6.1.2 Lookup by Address
1125  // also useful to grep for display_debug_aranges in binutils
1126  while (buf < buf_end) {
1127  const ut8 *start = buf;
1128  bool is_64bit;
1129  ut64 unit_length = dwarf_read_initial_length(&is_64bit, big_endian, &buf, buf_end);
1130  // Sanity check: length must be at least the minimal size of the remaining header fields
1131  // and at maximum the remaining buffer size.
1132  size_t header_rest_size = 2 + (is_64bit ? 8 : 4) + 1 + 1;
1133  if (unit_length < header_rest_size || unit_length > buf_end - buf) {
1134  break;
1135  }
1136  const ut8 *next_set_buf = buf + unit_length;
1138  if (!set) {
1139  break;
1140  }
1141  set->unit_length = unit_length;
1142  set->is_64bit = is_64bit;
1143  set->version = READ16(buf);
1144  set->debug_info_offset = dwarf_read_offset(set->is_64bit, big_endian, &buf, buf_end);
1145  set->address_size = READ8(buf);
1146  set->segment_size = READ8(buf);
1147  unit_length -= header_rest_size;
1148  if (!set->address_size) {
1149  free(set);
1150  break;
1151  }
1152 
1153  // align to 2*addr_size
1154  size_t off = buf - start;
1155  size_t pad = rz_num_align_delta(off, 2 * set->address_size);
1156  if (pad > unit_length || pad > buf_end - buf) {
1157  free(set);
1158  break;
1159  }
1160  buf += pad;
1161  unit_length -= pad;
1162 
1163  size_t arange_size = 2 * set->address_size;
1164  set->aranges_count = unit_length / arange_size;
1165  if (!set->aranges_count) {
1166  free(set);
1167  break;
1168  }
1170  if (!set->aranges) {
1171  free(set);
1172  break;
1173  }
1174  size_t i;
1175  for (i = 0; i < set->aranges_count; i++) {
1176  set->aranges[i].addr = dwarf_read_address(set->address_size, big_endian, &buf, buf_end);
1177  set->aranges[i].length = dwarf_read_address(set->address_size, big_endian, &buf, buf_end);
1178  if (!set->aranges[i].addr && !set->aranges[i].length) {
1179  // last entry has two 0s
1180  i++; // so i will be the total count of read entries
1181  break;
1182  }
1183  }
1184  set->aranges_count = i;
1185  buf = next_set_buf;
1186  rz_list_push(r, set);
1187  }
1188 
1189  return r;
1190 }
static ut64 dwarf_read_address(size_t size, bool big_endian, const ut8 **buf, const ut8 *buf_end)
Definition: dwarf.c:440
RZ_API void rz_bin_dwarf_arange_set_free(RzBinDwarfARangeSet *set)
Definition: dwarf.c:1106
static ut64 dwarf_read_initial_length(RZ_OUT bool *is_64bit, bool big_endian, const ut8 **buf, const ut8 *buf_end)
Read an "initial length" value, as specified by dwarf. This also determines whether it is 64bit or 32...
Definition: dwarf.c:411
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_BORROW RzListIter * rz_list_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
Definition: list.c:60
int off
Definition: pal.c:13
static void pad(RzStrBuf *sb, ut32 count)
Definition: protobuf.c:36
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
static ut64 rz_num_align_delta(ut64 v, ut64 alignment)
Padding to align v to the next alignment-boundary.
Definition: rz_num.h:116
#define RZ_NEW(x)
Definition: rz_types.h:285
DWARF 3 Standard Section 6.1.2 Lookup by Address.
Definition: rz_bin_dwarf.h:931
RzBinDwarfARange * aranges
Definition: rz_bin_dwarf.h:939

References rz_bin_dwarf_arange_t::addr, rz_bin_dwarf_arange_set_t::address_size, rz_bin_dwarf_arange_set_t::aranges, rz_bin_dwarf_arange_set_t::aranges_count, rz_bin_dwarf_arange_set_t::debug_info_offset, dwarf_read_address(), dwarf_read_initial_length(), dwarf_read_offset(), free(), i, rz_bin_dwarf_arange_set_t::is_64bit, rz_bin_dwarf_arange_t::length, NULL, obuf, off, pad(), r, READ16, READ8, rz_bin_dwarf_arange_set_free(), rz_list_newf(), rz_list_push(), RZ_NEW, RZ_NEWS0, rz_num_align_delta(), rz_return_val_if_fail, rz_bin_dwarf_arange_set_t::segment_size, start, rz_bin_dwarf_arange_set_t::unit_length, ut64(), and rz_bin_dwarf_arange_set_t::version.

Referenced by rz_bin_dwarf_parse_aranges().

◆ parse_attr_value()

static const ut8* parse_attr_value ( const ut8 obuf,
int  obuf_len,
RzBinDwarfAttrDef def,
RzBinDwarfAttrValue value,
const RzBinDwarfCompUnitHdr hdr,
const ut8 debug_str,
size_t  debug_str_len,
bool  big_endian 
)
static

Parses attribute value based on its definition and stores it into value

This function is quite incomplete and requires lot of work With parsing various new FORM values

Parameters
obuf
obuf_lenBuffer max capacity
defAttribute definition
valueParsed value storage
hdrCurrent unit header
debug_strPtr to string section start
debug_str_lenLength of the string section
Returns
const ut8* Updated buffer

Definition at line 1450 of file dwarf.c.

1454  {
1455 
1456  const ut8 *buf = obuf;
1457  const ut8 *buf_end = obuf + obuf_len;
1458  size_t j;
1459 
1460  rz_return_val_if_fail(def && value && hdr && obuf && obuf_len >= 1, NULL);
1461 
1462  value->attr_form = def->attr_form;
1463  value->attr_name = def->attr_name;
1464  value->block.data = NULL;
1465  value->string.content = NULL;
1466  value->string.offset = 0;
1467 
1468  // http://www.dwarfstd.org/doc/DWARF4.pdf#page=161&zoom=100,0,560
1469  switch (def->attr_form) {
1470  case DW_FORM_addr:
1471  value->kind = DW_AT_KIND_ADDRESS;
1472  switch (hdr->address_size) {
1473  case 1:
1474  value->address = READ8(buf);
1475  break;
1476  case 2:
1477  value->address = READ16(buf);
1478  break;
1479  case 4:
1480  value->address = READ32(buf);
1481  break;
1482  case 8:
1483  value->address = READ64(buf);
1484  break;
1485  default:
1486  RZ_LOG_ERROR("DWARF: Unexpected pointer size: %u\n", (unsigned)hdr->address_size);
1487  return NULL;
1488  }
1489  break;
1490  case DW_FORM_data1:
1491  value->kind = DW_AT_KIND_CONSTANT;
1492  value->uconstant = READ8(buf);
1493  break;
1494  case DW_FORM_data2:
1495  value->kind = DW_AT_KIND_CONSTANT;
1496  value->uconstant = READ16(buf);
1497  break;
1498  case DW_FORM_data4:
1499  value->kind = DW_AT_KIND_CONSTANT;
1500  value->uconstant = READ32(buf);
1501  break;
1502  case DW_FORM_data8:
1503  value->kind = DW_AT_KIND_CONSTANT;
1504  value->uconstant = READ64(buf);
1505  break;
1506  case DW_FORM_data16: // TODO Fix this, right now I just read the data, but I need to make storage for it
1507  value->kind = DW_AT_KIND_CONSTANT;
1508  value->uconstant = READ64(buf);
1509  value->uconstant = READ64(buf);
1510  break;
1511  case DW_FORM_sdata:
1512  value->kind = DW_AT_KIND_CONSTANT;
1513  buf = rz_leb128(buf, buf_end - buf, &value->sconstant);
1514  break;
1515  case DW_FORM_udata:
1516  value->kind = DW_AT_KIND_CONSTANT;
1517  buf = rz_uleb128(buf, buf_end - buf, &value->uconstant, NULL);
1518  break;
1519  case DW_FORM_string:
1520  value->kind = DW_AT_KIND_STRING;
1521  value->string.content = *buf ? rz_str_ndup((char *)buf, buf_end - buf) : NULL;
1522  buf += value->string.content ? strlen(value->string.content) + 1 : 1;
1523  break;
1524  case DW_FORM_block1:
1525  value->kind = DW_AT_KIND_BLOCK;
1526  value->block.length = READ8(buf);
1527  buf = fill_block_data(buf, buf_end, &value->block);
1528  break;
1529  case DW_FORM_block2:
1530  value->kind = DW_AT_KIND_BLOCK;
1531  value->block.length = READ16(buf);
1532  if (value->block.length > 0) {
1533  value->block.data = calloc(sizeof(ut8), value->block.length);
1534  if (!value->block.data) {
1535  return NULL;
1536  }
1537  for (j = 0; j < value->block.length; j++) {
1538  value->block.data[j] = READ8(buf);
1539  }
1540  }
1541  break;
1542  case DW_FORM_block4:
1543  value->kind = DW_AT_KIND_BLOCK;
1544  value->block.length = READ32(buf);
1545  buf = fill_block_data(buf, buf_end, &value->block);
1546  break;
1547  case DW_FORM_block: // variable length ULEB128
1548  value->kind = DW_AT_KIND_BLOCK;
1549  buf = rz_uleb128(buf, buf_end - buf, &value->block.length, NULL);
1550  if (!buf || buf >= buf_end) {
1551  return NULL;
1552  }
1553  buf = fill_block_data(buf, buf_end, &value->block);
1554  break;
1555  case DW_FORM_flag:
1556  value->kind = DW_AT_KIND_FLAG;
1557  value->flag = READ8(buf);
1558  break;
1559  // offset in .debug_str
1560  case DW_FORM_strp:
1561  value->kind = DW_AT_KIND_STRING;
1562  value->string.offset = dwarf_read_offset(hdr->is_64bit, big_endian, &buf, buf_end);
1563  if (debug_str && value->string.offset < debug_str_len) {
1564  value->string.content =
1565  rz_str_ndup((char *)debug_str + value->string.offset, debug_str_len - value->string.offset);
1566  } else {
1567  value->string.content = NULL; // Means malformed DWARF, should we print error message?
1568  }
1569  break;
1570  // offset in .debug_info
1571  case DW_FORM_ref_addr:
1572  value->kind = DW_AT_KIND_REFERENCE;
1573  value->reference = dwarf_read_offset(hdr->is_64bit, big_endian, &buf, buf_end);
1574  break;
1575  // This type of reference is an offset from the first byte of the compilation
1576  // header for the compilation unit containing the reference
1577  case DW_FORM_ref1:
1578  value->kind = DW_AT_KIND_REFERENCE;
1579  value->reference = hdr->unit_offset + READ8(buf);
1580  break;
1581  case DW_FORM_ref2:
1582  value->kind = DW_AT_KIND_REFERENCE;
1583  value->reference = hdr->unit_offset + READ16(buf);
1584  break;
1585  case DW_FORM_ref4:
1586  value->kind = DW_AT_KIND_REFERENCE;
1587  value->reference = hdr->unit_offset + READ32(buf);
1588  break;
1589  case DW_FORM_ref8:
1590  value->kind = DW_AT_KIND_REFERENCE;
1591  value->reference = hdr->unit_offset + READ64(buf);
1592  break;
1593  case DW_FORM_ref_udata:
1594  value->kind = DW_AT_KIND_REFERENCE;
1595  // uleb128 is enough to fit into ut64?
1596  buf = rz_uleb128(buf, buf_end - buf, &value->reference, NULL);
1597  value->reference += hdr->unit_offset;
1598  break;
1599  // offset in a section other than .debug_info or .debug_str
1600  case DW_FORM_sec_offset:
1601  value->kind = DW_AT_KIND_REFERENCE;
1602  value->reference = dwarf_read_offset(hdr->is_64bit, big_endian, &buf, buf_end);
1603  break;
1604  case DW_FORM_exprloc:
1605  value->kind = DW_AT_KIND_BLOCK;
1606  buf = rz_uleb128(buf, buf_end - buf, &value->block.length, NULL);
1607  if (!buf || buf >= buf_end) {
1608  return NULL;
1609  }
1610  buf = fill_block_data(buf, buf_end, &value->block);
1611  break;
1612  // this means that the flag is present, nothing is read
1613  case DW_FORM_flag_present:
1614  value->kind = DW_AT_KIND_FLAG;
1615  value->flag = true;
1616  break;
1617  case DW_FORM_ref_sig8:
1618  value->kind = DW_AT_KIND_REFERENCE;
1619  value->reference = READ64(buf);
1620  break;
1621  // offset into .debug_line_str section, can't parse the section now, so we just skip
1622  case DW_FORM_strx:
1623  value->kind = DW_AT_KIND_STRING;
1624  // value->string.offset = dwarf_read_offset (hdr->is_64bit, big_endian, &buf, buf_end);
1625  // if (debug_str && value->string.offset < debug_str_len) {
1626  // value->string.content =
1627  // rz_str_ndup ((const char *)(debug_str + value->string.offset), debug_str_len - value->string.offset);
1628  // } else {
1629  // value->string.content = NULL; // Means malformed DWARF, should we print error message?
1630  // }
1631  break;
1632  case DW_FORM_strx1:
1633  value->kind = DW_AT_KIND_STRING;
1634  value->string.offset = READ8(buf);
1635  break;
1636  case DW_FORM_strx2:
1637  value->kind = DW_AT_KIND_STRING;
1638  value->string.offset = READ16(buf);
1639  break;
1640  case DW_FORM_strx3: // TODO Add 3 byte int read
1641  value->kind = DW_AT_KIND_STRING;
1642  buf += 3;
1643  break;
1644  case DW_FORM_strx4:
1645  value->kind = DW_AT_KIND_STRING;
1646  value->string.offset = READ32(buf);
1647  break;
1649  value->kind = DW_AT_KIND_CONSTANT;
1650  value->uconstant = def->special;
1651  break;
1652  /* addrx* forms : The index is relative to the value of the
1653  DW_AT_addr_base attribute of the associated compilation unit.
1654  index into an array of addresses in the .debug_addr section.*/
1655  case DW_FORM_addrx:
1656  value->kind = DW_AT_KIND_ADDRESS;
1657  buf = rz_uleb128(buf, buf_end - buf, &value->address, NULL);
1658  break;
1659  case DW_FORM_addrx1:
1660  value->kind = DW_AT_KIND_ADDRESS;
1661  value->address = READ8(buf);
1662  break;
1663  case DW_FORM_addrx2:
1664  value->kind = DW_AT_KIND_ADDRESS;
1665  value->address = READ16(buf);
1666  break;
1667  case DW_FORM_addrx3:
1668  // I need to add 3byte endianess free read here TODO
1669  value->kind = DW_AT_KIND_ADDRESS;
1670  buf += 3;
1671  break;
1672  case DW_FORM_addrx4:
1673  value->kind = DW_AT_KIND_ADDRESS;
1674  value->address = READ32(buf);
1675  break;
1676  case DW_FORM_line_ptr: // offset in a section .debug_line_str
1677  case DW_FORM_strp_sup: // offset in a section .debug_line_str
1678  value->kind = DW_AT_KIND_STRING;
1679  value->string.offset = dwarf_read_offset(hdr->is_64bit, big_endian, &buf, buf_end);
1680  // if (debug_str && value->string.offset < debug_line_str_len) {
1681  // value->string.content =
1682  // rz_str_ndup
1683  break;
1684  // offset in the supplementary object file
1685  case DW_FORM_ref_sup4:
1686  value->kind = DW_AT_KIND_REFERENCE;
1687  value->reference = READ32(buf);
1688  break;
1689  case DW_FORM_ref_sup8:
1690  value->kind = DW_AT_KIND_REFERENCE;
1691  value->reference = READ64(buf);
1692  break;
1693  // An index into the .debug_loc
1694  case DW_FORM_loclistx:
1695  value->kind = DW_AT_KIND_LOCLISTPTR;
1696  value->reference = dwarf_read_offset(hdr->is_64bit, big_endian, &buf, buf_end);
1697  break;
1698  // An index into the .debug_rnglists
1699  case DW_FORM_rnglistx:
1700  value->kind = DW_AT_KIND_ADDRESS;
1701  buf = rz_uleb128(buf, buf_end - buf, &value->address, NULL);
1702  break;
1703  default:
1704  RZ_LOG_ERROR("Unknown DW_FORM 0x%02" PFMT64x "\n", def->attr_form);
1705  value->uconstant = 0;
1706  return NULL;
1707  }
1708  return buf;
1709 }
static int value
Definition: cmd_api.c:93
static const ut8 * fill_block_data(const ut8 *buf, const ut8 *buf_end, RzBinDwarfBlock *block)
Definition: dwarf.c:1420
#define DW_FORM_strx4
Definition: rz_bin_dwarf.h:317
#define DW_FORM_strx3
Definition: rz_bin_dwarf.h:316
#define DW_FORM_sdata
Definition: rz_bin_dwarf.h:290
#define DW_FORM_addrx4
Definition: rz_bin_dwarf.h:321
#define DW_FORM_udata
Definition: rz_bin_dwarf.h:292
#define DW_FORM_ref_sup8
Definition: rz_bin_dwarf.h:313
#define DW_FORM_strx
Definition: rz_bin_dwarf.h:303
#define DW_FORM_addrx3
Definition: rz_bin_dwarf.h:320
#define DW_FORM_ref_udata
Definition: rz_bin_dwarf.h:298
@ DW_AT_KIND_STRING
Definition: rz_bin_dwarf.h:698
@ DW_AT_KIND_REFERENCE
Definition: rz_bin_dwarf.h:697
@ DW_AT_KIND_BLOCK
Definition: rz_bin_dwarf.h:689
@ DW_AT_KIND_CONSTANT
Definition: rz_bin_dwarf.h:690
@ DW_AT_KIND_ADDRESS
Definition: rz_bin_dwarf.h:688
@ DW_AT_KIND_FLAG
Definition: rz_bin_dwarf.h:692
@ DW_AT_KIND_LOCLISTPTR
Definition: rz_bin_dwarf.h:694
#define DW_FORM_addr
Definition: rz_bin_dwarf.h:279
#define DW_FORM_data16
Definition: rz_bin_dwarf.h:307
#define DW_FORM_line_ptr
Definition: rz_bin_dwarf.h:308
#define DW_FORM_ref_sup4
Definition: rz_bin_dwarf.h:305
#define DW_FORM_ref_sig8
Definition: rz_bin_dwarf.h:309
#define DW_FORM_strx1
Definition: rz_bin_dwarf.h:314
#define DW_FORM_ref_addr
Definition: rz_bin_dwarf.h:293
#define DW_FORM_strx2
Definition: rz_bin_dwarf.h:315
#define DW_FORM_addrx2
Definition: rz_bin_dwarf.h:319
#define DW_FORM_addrx1
Definition: rz_bin_dwarf.h:318
#define DW_FORM_data2
Definition: rz_bin_dwarf.h:282
#define DW_FORM_flag_present
Definition: rz_bin_dwarf.h:302
#define DW_FORM_flag
Definition: rz_bin_dwarf.h:289
#define DW_FORM_data4
Definition: rz_bin_dwarf.h:283
#define DW_FORM_data1
Definition: rz_bin_dwarf.h:288
#define DW_FORM_strp_sup
Definition: rz_bin_dwarf.h:306
#define DW_FORM_data8
Definition: rz_bin_dwarf.h:284
#define DW_FORM_ref2
Definition: rz_bin_dwarf.h:295
#define DW_FORM_ref8
Definition: rz_bin_dwarf.h:297
#define DW_FORM_addrx
Definition: rz_bin_dwarf.h:304
#define DW_FORM_rnglistx
Definition: rz_bin_dwarf.h:312
#define DW_FORM_ref1
Definition: rz_bin_dwarf.h:294
#define DW_FORM_loclistx
Definition: rz_bin_dwarf.h:311
#define DW_FORM_ref4
Definition: rz_bin_dwarf.h:296
#define DW_FORM_sec_offset
Definition: rz_bin_dwarf.h:300
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
#define PFMT64x
Definition: rz_types.h:393
int def(FILE *source, FILE *dest, int level)
Definition: zpipe.c:36

References RzBinDwarfCompUnitHdr::address_size, calloc(), def(), DW_AT_KIND_ADDRESS, DW_AT_KIND_BLOCK, DW_AT_KIND_CONSTANT, DW_AT_KIND_FLAG, DW_AT_KIND_LOCLISTPTR, DW_AT_KIND_REFERENCE, DW_AT_KIND_STRING, DW_FORM_addr, DW_FORM_addrx, DW_FORM_addrx1, DW_FORM_addrx2, DW_FORM_addrx3, DW_FORM_addrx4, DW_FORM_block, DW_FORM_block1, DW_FORM_block2, DW_FORM_block4, DW_FORM_data1, DW_FORM_data16, DW_FORM_data2, DW_FORM_data4, DW_FORM_data8, DW_FORM_exprloc, DW_FORM_flag, DW_FORM_flag_present, DW_FORM_implicit_const, DW_FORM_line_ptr, DW_FORM_loclistx, DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4, DW_FORM_ref8, DW_FORM_ref_addr, DW_FORM_ref_sig8, DW_FORM_ref_sup4, DW_FORM_ref_sup8, DW_FORM_ref_udata, DW_FORM_rnglistx, DW_FORM_sdata, DW_FORM_sec_offset, DW_FORM_string, DW_FORM_strp, DW_FORM_strp_sup, DW_FORM_strx, DW_FORM_strx1, DW_FORM_strx2, DW_FORM_strx3, DW_FORM_strx4, DW_FORM_udata, dwarf_read_offset(), fill_block_data(), RzBinDwarfCompUnitHdr::is_64bit, NULL, obuf, PFMT64x, READ16, READ32, READ64, READ8, rz_leb128(), RZ_LOG_ERROR, rz_return_val_if_fail, rz_str_ndup(), rz_uleb128(), RzBinDwarfCompUnitHdr::unit_offset, and value.

Referenced by parse_die().

◆ parse_comp_unit()

static const ut8* parse_comp_unit ( RzBinDwarfDebugInfo info,
const ut8 buf_start,
RzBinDwarfCompUnit unit,
const RzBinDwarfDebugAbbrev abbrevs,
size_t  first_abbr_idx,
const ut8 debug_str,
size_t  debug_str_len,
bool  big_endian 
)
static

Reads throught comp_unit buffer and parses all its DIEntries.

Parameters
buf_startStart of the compilation unit data
unitUnit to store the newly parsed information
abbrevsParsed abbrev section info of all abbreviations
first_abbr_idxindex for first abbrev of the current comp unit in abbrev array
debug_strPtr to string section start
debug_str_lenLength of the string section
Returns
const ut8* Update buffer

Definition at line 1776 of file dwarf.c.

1778  {
1779 
1780  const ut8 *buf = buf_start;
1781  const ut8 *buf_end = buf_start + unit->hdr.length - unit->hdr.header_size;
1782 
1783  while (buf && buf < buf_end && buf >= buf_start) {
1784  if (unit->count && unit->capacity == unit->count) {
1785  expand_cu(unit);
1786  }
1787  RzBinDwarfDie *die = &unit->dies[unit->count];
1788  // add header size to the offset;
1789  die->offset = buf - buf_start + unit->hdr.header_size + unit->offset;
1790  die->offset += unit->hdr.is_64bit ? 12 : 4;
1791 
1792  // DIE starts with ULEB128 with the abbreviation code
1793  ut64 abbr_code;
1794  buf = rz_uleb128(buf, buf_end - buf, &abbr_code, NULL);
1795 
1796  if (abbr_code > abbrevs->count || !buf) { // something invalid
1797  return NULL;
1798  }
1799 
1800  if (buf >= buf_end) {
1801  unit->count++; // we wanna store this entry too, usually the last one is null_entry
1802  return buf; // return the buffer to parse next compilation units
1803  }
1804  // there can be "null" entries that have abbr_code == 0
1805  if (!abbr_code) {
1806  unit->count++;
1807  continue;
1808  }
1809  ut64 abbr_idx = first_abbr_idx + abbr_code;
1810 
1811  if (abbrevs->count < abbr_idx) {
1812  return NULL;
1813  }
1814  RzBinDwarfAbbrevDecl *abbrev = &abbrevs->decls[abbr_idx - 1];
1815 
1816  if (init_die(die, abbr_code, abbrev->count)) {
1817  return NULL; // error
1818  }
1819  die->tag = abbrev->tag;
1820  die->has_children = abbrev->has_children;
1821 
1822  buf = parse_die(buf, buf_end, info, abbrev, &unit->hdr, die, debug_str, debug_str_len, big_endian);
1823  if (!buf) {
1824  return NULL;
1825  }
1826 
1827  unit->count++;
1828  }
1829  return buf;
1830 }
static const ut8 * parse_die(const ut8 *buf, const ut8 *buf_end, RzBinDwarfDebugInfo *info, RzBinDwarfAbbrevDecl *abbrev, RzBinDwarfCompUnitHdr *hdr, RzBinDwarfDie *die, const ut8 *debug_str, size_t debug_str_len, bool big_endian)
Definition: dwarf.c:1722
static int expand_cu(RzBinDwarfCompUnit *cu)
Definition: dwarf.c:1244
static int init_die(RzBinDwarfDie *die, ut64 abbr_code, ut64 attr_count)
Definition: dwarf.c:1213
RzBinDwarfCompUnitHdr hdr
Definition: rz_bin_dwarf.h:760

References RzBinDwarfCompUnit::capacity, RzBinDwarfCompUnit::count, RzBinDwarfAbbrevDecl::count, RzBinDwarfDebugAbbrev::count, RzBinDwarfDebugAbbrev::decls, RzBinDwarfCompUnit::dies, expand_cu(), RzBinDwarfDie::has_children, RzBinDwarfAbbrevDecl::has_children, RzBinDwarfCompUnit::hdr, RzBinDwarfCompUnitHdr::header_size, info(), init_die(), RzBinDwarfCompUnitHdr::is_64bit, RzBinDwarfCompUnitHdr::length, NULL, RzBinDwarfDie::offset, RzBinDwarfCompUnit::offset, parse_die(), rz_uleb128(), RzBinDwarfDie::tag, RzBinDwarfAbbrevDecl::tag, and ut64().

Referenced by parse_info_raw().

◆ parse_die()

static const ut8* parse_die ( const ut8 buf,
const ut8 buf_end,
RzBinDwarfDebugInfo info,
RzBinDwarfAbbrevDecl abbrev,
RzBinDwarfCompUnitHdr hdr,
RzBinDwarfDie die,
const ut8 debug_str,
size_t  debug_str_len,
bool  big_endian 
)
static
Parameters
bufStart of the DIE data
buf_end
infodebug info where the line_info_offset_comp_dir will be populated if such an entry is found
abbrevAbbreviation of the DIE
hdrUnit header
dieDIE to store the parsed info into
debug_strPtr to string section start
debug_str_lenLength of the string section
Returns
const ut8* Updated buffer

Definition at line 1722 of file dwarf.c.

1723  {
1724  size_t i;
1725  const char *comp_dir = NULL;
1726  ut64 line_info_offset = UT64_MAX;
1727  if (abbrev->count) {
1728  for (i = 0; i < abbrev->count - 1; i++) {
1729  memset(&die->attr_values[i], 0, sizeof(die->attr_values[i]));
1730 
1731  buf = parse_attr_value(buf, buf_end - buf, &abbrev->defs[i],
1732  &die->attr_values[i], hdr, debug_str, debug_str_len, big_endian);
1733 
1734  RzBinDwarfAttrValue *attribute = &die->attr_values[i];
1735 
1736  if (attribute->attr_name == DW_AT_comp_dir && (attribute->attr_form == DW_FORM_strp || attribute->attr_form == DW_FORM_string) && attribute->string.content) {
1737  comp_dir = attribute->string.content;
1738  }
1739  if (attribute->attr_name == DW_AT_stmt_list) {
1740  if (attribute->kind == DW_AT_KIND_CONSTANT) {
1741  line_info_offset = attribute->uconstant;
1742  } else if (attribute->kind == DW_AT_KIND_REFERENCE) {
1743  line_info_offset = attribute->reference;
1744  }
1745  }
1746  die->count++;
1747  }
1748  }
1749 
1750  // If this is a compilation unit dir attribute, we want to cache it so the line info parsing
1751  // which will need this info can quickly look it up.
1752  if (comp_dir && line_info_offset != UT64_MAX) {
1753  char *name = strdup(comp_dir);
1754  if (name) {
1755  if (!ht_up_insert(info->line_info_offset_comp_dir, line_info_offset, name)) {
1756  free(name);
1757  }
1758  }
1759  }
1760 
1761  return buf;
1762 }
static const ut8 * parse_attr_value(const ut8 *obuf, int obuf_len, RzBinDwarfAttrDef *def, RzBinDwarfAttrValue *value, const RzBinDwarfCompUnitHdr *hdr, const ut8 *debug_str, size_t debug_str_len, bool big_endian)
Parses attribute value based on its definition and stores it into value
Definition: dwarf.c:1450
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define DW_AT_comp_dir
Definition: rz_bin_dwarf.h:150
#define DW_AT_stmt_list
Definition: rz_bin_dwarf.h:140
RzBinDwarfAttrKind kind
Definition: rz_bin_dwarf.h:704
struct dwarf_attr_kind::@251::@253 string
Definition: z80asm.h:102

References dwarf_attr_kind::attr_form, dwarf_attr_kind::attr_name, RzBinDwarfDie::attr_values, RzBinDwarfDie::count, RzBinDwarfAbbrevDecl::count, RzBinDwarfAbbrevDecl::defs, DW_AT_comp_dir, DW_AT_KIND_CONSTANT, DW_AT_KIND_REFERENCE, DW_AT_stmt_list, DW_FORM_string, DW_FORM_strp, free(), i, info(), dwarf_attr_kind::kind, memset(), NULL, parse_attr_value(), dwarf_attr_kind::reference, strdup(), dwarf_attr_kind::string, dwarf_attr_kind::uconstant, ut64(), and UT64_MAX.

Referenced by parse_comp_unit().

◆ parse_ext_opcode()

static const ut8* parse_ext_opcode ( RzBinDwarfLineOp op,
const RzBinDwarfLineHeader hdr,
const ut8 obuf,
size_t  len,
bool  big_endian,
ut8  target_addr_size 
)
static

Definition at line 706 of file dwarf.c.

707  {
708  rz_return_val_if_fail(op && hdr && obuf, NULL);
709  const ut8 *buf = obuf;
710  const ut8 *buf_end = obuf + len;
711 
712  ut64 op_len;
713  buf = rz_uleb128(buf, len, &op_len, NULL);
714  // op_len must fit and be at least 1 (for the opcode byte)
715  if (!buf || buf >= buf_end || !op_len || buf_end - buf < op_len) {
716  return NULL;
717  }
718 
719  ut8 opcode = *buf++;
721  op->opcode = opcode;
722 
723  switch (opcode) {
724  case DW_LNE_set_address: {
725  ut8 addr_size = hdr->address_size;
726  if (hdr->version < 5) { // address_size in header only starting with Dwarf 5
727  addr_size = target_addr_size;
728  }
729  op->args.set_address = dwarf_read_address(addr_size, big_endian, &buf, buf_end);
730  break;
731  }
732  case DW_LNE_define_file: {
733  size_t fn_len = rz_str_nlen((const char *)buf, buf_end - buf);
734  char *fn = malloc(fn_len + 1);
735  if (!fn) {
736  return NULL;
737  }
738  memcpy(fn, buf, fn_len);
739  fn[fn_len] = 0;
740  op->args.define_file.filename = fn;
741  buf += fn_len + 1;
742  if (buf + 1 < buf_end) {
743  buf = rz_uleb128(buf, buf_end - buf, &op->args.define_file.dir_index, NULL);
744  }
745  if (buf && buf + 1 < buf_end) {
746  buf = rz_uleb128(buf, buf_end - buf, NULL, NULL);
747  }
748  if (buf && buf + 1 < buf_end) {
749  buf = rz_uleb128(buf, buf_end - buf, NULL, NULL);
750  }
751  break;
752  }
754  buf = rz_uleb128(buf, buf_end - buf, &op->args.set_discriminator, NULL);
755  break;
756  case DW_LNE_end_sequence:
757  default:
758  buf += op_len - 1;
759  break;
760  }
761  return buf;
762 }
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * malloc(size_t size)
Definition: malloc.c:123
static const char struct stat static buf struct stat static buf static idle const char static path static fd const char static len const void static prot const char struct module static image struct kernel_sym static table unsigned char static buf static fsuid unsigned struct dirent unsigned static count const struct iovec static count static pid const void static len static flags const struct sched_param static p static pid static policy struct timespec static tp static suid unsigned fn
Definition: sflib.h:186
#define DW_LNE_set_address
Definition: rz_bin_dwarf.h:33
#define DW_LNE_set_discriminator
Definition: rz_bin_dwarf.h:35
@ RZ_BIN_DWARF_LINE_OP_TYPE_EXT
Definition: rz_bin_dwarf.h:861
#define DW_LNE_define_file
Definition: rz_bin_dwarf.h:34
#define DW_LNE_end_sequence
Definition: rz_bin_dwarf.h:32
RZ_API size_t rz_str_nlen(const char *s, size_t n)
Definition: str.c:1949
Definition: dis.c:32

References RzBinDwarfLineHeader::address_size, DW_LNE_define_file, DW_LNE_end_sequence, DW_LNE_set_address, DW_LNE_set_discriminator, dwarf_read_address(), fn, len, malloc(), memcpy(), NULL, obuf, RZ_BIN_DWARF_LINE_OP_TYPE_EXT, rz_return_val_if_fail, rz_str_nlen(), rz_uleb128(), ut64(), and RzBinDwarfLineHeader::version.

Referenced by parse_opcodes().

◆ parse_info_raw()

static RzBinDwarfDebugInfo* parse_info_raw ( RzBinDwarfDebugAbbrev da,
const ut8 obuf,
size_t  len,
const ut8 debug_str,
size_t  debug_str_len,
bool  big_endian 
)
static

Parses whole .debug_info section.

Parameters
daParsed Abbreviations
obuf.debug_info section buffer start
lenlength of the section buffer
debug_strstart of the .debug_str section
debug_str_lenlength of the debug_str section
big_endian
Returns
RZ_API* parse_info_raw Parsed information

Definition at line 1897 of file dwarf.c.

1899  {
1900 
1901  rz_return_val_if_fail(da && obuf, false);
1902 
1903  const ut8 *buf = obuf;
1904  const ut8 *buf_end = obuf + len;
1905 
1907  if (!info) {
1908  return NULL;
1909  }
1910  if (!init_debug_info(info)) {
1911  goto cleanup;
1912  }
1913  int unit_idx = 0;
1914 
1915  while (buf < buf_end) {
1916  if (info->count >= info->capacity) {
1917  if (expand_info(info)) {
1918  break;
1919  }
1920  }
1921 
1922  RzBinDwarfCompUnit *unit = &info->comp_units[unit_idx];
1923  if (init_comp_unit(unit) < 0) {
1924  unit_idx--;
1925  goto cleanup;
1926  }
1927  info->count++;
1928 
1929  unit->offset = buf - obuf;
1930  // small redundancy, because it was easiest solution at a time
1931  unit->hdr.unit_offset = buf - obuf;
1932 
1933  buf = info_comp_unit_read_hdr(buf, buf_end, &unit->hdr, big_endian);
1934 
1935  if (unit->hdr.length > len) {
1936  goto cleanup;
1937  }
1938 
1939  if (da->decls->count >= da->capacity) {
1940  RZ_LOG_WARN("malformed dwarf have not enough buckets for decls.\n");
1941  }
1942  rz_warn_if_fail(da->count <= da->capacity);
1943 
1944  // find abbrev start for current comp unit
1945  // we could also do naive, ((char *)da->decls) + abbrev_offset,
1946  // but this is more bulletproof to invalid DWARF
1947  RzBinDwarfAbbrevDecl key = { .offset = unit->hdr.abbrev_offset };
1948  RzBinDwarfAbbrevDecl *abbrev_start = bsearch(&key, da->decls, da->count, sizeof(key), abbrev_cmp);
1949  if (!abbrev_start) {
1950  goto cleanup;
1951  }
1952  // They point to the same array object, so should be def. behaviour
1953  size_t first_abbr_idx = abbrev_start - da->decls;
1954 
1955  buf = parse_comp_unit(info, buf, unit, da, first_abbr_idx, debug_str, debug_str_len, big_endian);
1956 
1957  if (!buf) {
1958  goto cleanup;
1959  }
1960 
1961  info->n_dwarf_dies += unit->count;
1962 
1963  unit_idx++;
1964  }
1965 
1966  return info;
1967 
1968 cleanup:
1970  return NULL;
1971 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
static int expand_info(RzBinDwarfDebugInfo *info)
Definition: dwarf.c:1868
static int abbrev_cmp(const void *a, const void *b)
Definition: dwarf.c:394
static bool init_debug_info(RzBinDwarfDebugInfo *inf)
Definition: dwarf.c:1196
static const ut8 * info_comp_unit_read_hdr(const ut8 *buf, const ut8 *buf_end, RzBinDwarfCompUnitHdr *hdr, bool big_endian)
Reads all information about compilation unit header.
Definition: dwarf.c:1840
static int init_comp_unit(RzBinDwarfCompUnit *cu)
Definition: dwarf.c:1231
RZ_API void rz_bin_dwarf_debug_info_free(RzBinDwarfDebugInfo *inf)
Definition: dwarf.c:1407
static const ut8 * parse_comp_unit(RzBinDwarfDebugInfo *info, const ut8 *buf_start, RzBinDwarfCompUnit *unit, const RzBinDwarfDebugAbbrev *abbrevs, size_t first_abbr_idx, const ut8 *debug_str, size_t debug_str_len, bool big_endian)
Reads throught comp_unit buffer and parses all its DIEntries.
Definition: dwarf.c:1776
void cleanup(void)
Definition: enough.c:244
#define rz_warn_if_fail(expr)
Definition: rz_assert.h:35

References abbrev_cmp(), RzBinDwarfCompUnitHdr::abbrev_offset, RzBinDwarfDebugAbbrev::capacity, cleanup(), RzBinDwarfCompUnit::count, RzBinDwarfAbbrevDecl::count, RzBinDwarfDebugAbbrev::count, RzBinDwarfDebugAbbrev::decls, expand_info(), RzBinDwarfCompUnit::hdr, info(), info_comp_unit_read_hdr(), init_comp_unit(), init_debug_info(), key, len, RzBinDwarfCompUnitHdr::length, NULL, obuf, RzBinDwarfCompUnit::offset, parse_comp_unit(), rz_bin_dwarf_debug_info_free(), RZ_LOG_WARN, RZ_NEW0, rz_return_val_if_fail, rz_warn_if_fail, and RzBinDwarfCompUnitHdr::unit_offset.

Referenced by rz_bin_dwarf_parse_info().

◆ parse_line_header()

static const ut8* parse_line_header ( RzBinFile bf,
const ut8 buf,
const ut8 buf_end,
RzBinDwarfLineHeader hdr,
ut64  offset_cur,
bool  big_endian 
)
static

Definition at line 638 of file dwarf.c.

640  {
641  rz_return_val_if_fail(hdr && bf && buf && buf_end, NULL);
642 
643  hdr->offset = offset_cur;
644  hdr->is_64bit = false;
645  hdr->unit_length = dwarf_read_initial_length(&hdr->is_64bit, big_endian, &buf, buf_end);
646  hdr->version = READ16(buf);
647 
648  if (hdr->version == 5) {
649  hdr->address_size = READ8(buf);
651  }
652 
653  hdr->header_length = dwarf_read_offset(hdr->is_64bit, big_endian, &buf, buf_end);
654 
655  const ut8 *tmp_buf = buf; // So I can skip parsing DWARF 5 headers for now
656 
657  if (buf_end - buf < 8) {
658  return NULL;
659  }
660  hdr->min_inst_len = READ8(buf);
661  if (hdr->version >= 4) {
662  hdr->max_ops_per_inst = READ8(buf);
663  }
664  hdr->default_is_stmt = READ8(buf);
665  hdr->line_base = (st8)READ8(buf);
666  hdr->line_range = READ8(buf);
667  hdr->opcode_base = READ8(buf);
668 
669  hdr->file_names = NULL;
670 
671  if (hdr->opcode_base > 1) {
672  hdr->std_opcode_lengths = calloc(sizeof(ut8), hdr->opcode_base - 1);
673  for (size_t i = 1; i < hdr->opcode_base; i++) {
674  if (buf + 2 > buf_end) {
675  hdr->opcode_base = i;
676  break;
677  }
678  hdr->std_opcode_lengths[i - 1] = READ8(buf);
679  }
680  } else {
681  hdr->std_opcode_lengths = NULL;
682  }
683  // TODO finish parsing of source files out of DWARF 5 header
684  // for now we skip
685  if (hdr->version == 5) {
686  tmp_buf += hdr->header_length;
687  return tmp_buf;
688  }
689 
690  if (hdr->version <= 4) {
691  buf = parse_line_header_source(bf, buf, buf_end, hdr);
692  } else {
693  buf = NULL;
694  }
695 
696  return buf;
697 }
static const ut8 * parse_line_header_source(RzBinFile *bf, const ut8 *buf, const ut8 *buf_end, RzBinDwarfLineHeader *hdr)
Definition: dwarf.c:479
#define st8
Definition: rz_types_base.h:16

References RzBinDwarfLineHeader::address_size, calloc(), RzBinDwarfLineHeader::default_is_stmt, dwarf_read_initial_length(), dwarf_read_offset(), RzBinDwarfLineHeader::file_names, RzBinDwarfLineHeader::header_length, i, RzBinDwarfLineHeader::is_64bit, RzBinDwarfLineHeader::line_base, RzBinDwarfLineHeader::line_range, RzBinDwarfLineHeader::max_ops_per_inst, RzBinDwarfLineHeader::min_inst_len, NULL, RzBinDwarfLineHeader::offset, RzBinDwarfLineHeader::opcode_base, parse_line_header_source(), READ16, READ8, rz_return_val_if_fail, RzBinDwarfLineHeader::segment_selector_size, st8, RzBinDwarfLineHeader::std_opcode_lengths, RzBinDwarfLineHeader::unit_length, and RzBinDwarfLineHeader::version.

Referenced by parse_line_raw().

◆ parse_line_header_source()

static const ut8* parse_line_header_source ( RzBinFile bf,
const ut8 buf,
const ut8 buf_end,
RzBinDwarfLineHeader hdr 
)
static

Definition at line 479 of file dwarf.c.

479  {
480  RzPVector incdirs;
481  rz_pvector_init(&incdirs, free);
482  while (buf + 1 < buf_end) {
483  size_t maxlen = RZ_MIN((size_t)(buf_end - buf) - 1, 0xfff);
484  size_t len = rz_str_nlen((const char *)buf, maxlen);
485  char *str = rz_str_ndup((const char *)buf, len);
486  if (len < 1 || len >= 0xfff || !str) {
487  buf += 1;
488  free(str);
489  break;
490  }
491  rz_pvector_push(&incdirs, str);
492  buf += len + 1;
493  }
494  hdr->include_dirs_count = rz_pvector_len(&incdirs);
495  hdr->include_dirs = (char **)rz_pvector_flush(&incdirs);
496  rz_pvector_fini(&incdirs);
497 
498  RzVector file_names;
499  rz_vector_init(&file_names, sizeof(RzBinDwarfLineFileEntry), NULL, NULL);
500  while (buf + 1 < buf_end) {
501  const char *filename = (const char *)buf;
502  size_t maxlen = RZ_MIN((size_t)(buf_end - buf - 1), 0xfff);
503  ut64 id_idx, mod_time, file_len;
504  size_t len = rz_str_nlen(filename, maxlen);
505 
506  if (!len) {
507  buf++;
508  break;
509  }
510  buf += len + 1;
511  if (buf >= buf_end) {
512  buf = NULL;
513  goto beach;
514  }
515  buf = rz_uleb128(buf, buf_end - buf, &id_idx, NULL);
516  if (buf >= buf_end) {
517  buf = NULL;
518  goto beach;
519  }
520  buf = rz_uleb128(buf, buf_end - buf, &mod_time, NULL);
521  if (buf >= buf_end) {
522  buf = NULL;
523  goto beach;
524  }
525  buf = rz_uleb128(buf, buf_end - buf, &file_len, NULL);
526  if (buf >= buf_end) {
527  buf = NULL;
528  goto beach;
529  }
532  entry->id_idx = id_idx;
533  entry->mod_time = mod_time;
534  entry->file_len = file_len;
535  }
536  hdr->file_names_count = rz_vector_len(&file_names);
537  hdr->file_names = rz_vector_flush(&file_names);
538  rz_vector_fini(&file_names);
539 
540 beach:
541  return buf;
542 }
const char * filename
Definition: ioapi.h:137
RZ_API void * rz_vector_flush(RzVector *vec)
Turn the vector into a fixed-size array. This will clear the vector and return an array of its origin...
Definition: vector.c:230
RZ_API void rz_pvector_init(RzPVector *vec, RzPVectorFree free)
Definition: vector.c:298
RZ_API void rz_pvector_fini(RzPVector *vec)
Definition: vector.c:331
static size_t rz_pvector_len(const RzPVector *vec)
Definition: rz_vector.h:231
RZ_API void * rz_vector_push(RzVector *vec, void *x)
Definition: vector.c:197
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
RZ_API void rz_vector_fini(RzVector *vec)
Definition: vector.c:61
static void ** rz_pvector_flush(RzPVector *vec)
Definition: rz_vector.h:320
static size_t rz_vector_len(const RzVector *vec)
Definition: rz_vector.h:82
RZ_API void rz_vector_init(RzVector *vec, size_t elem_size, RzVectorFree free, void *free_user)
Definition: vector.c:33
Definition: zipcmp.c:77
char * name
Definition: zipcmp.c:78
Definition: rz_bin_dwarf.h:822
ut64 maxlen
Definition: core.c:76

References RzBinDwarfLineHeader::file_names, RzBinDwarfLineHeader::file_names_count, free(), RzBinDwarfLineHeader::include_dirs, RzBinDwarfLineHeader::include_dirs_count, len, maxlen, entry::name, NULL, RZ_MIN, rz_pvector_fini(), rz_pvector_flush(), rz_pvector_init(), rz_pvector_len(), rz_pvector_push(), rz_str_ndup(), rz_str_nlen(), rz_uleb128(), rz_vector_fini(), rz_vector_flush(), rz_vector_init(), rz_vector_len(), rz_vector_push(), cmd_descs_generate::str, and ut64().

Referenced by parse_line_header().

◆ parse_line_raw()

static RzBinDwarfLineInfo* parse_line_raw ( RzBinFile binfile,
const ut8 obuf,
ut64  len,
RzBinDwarfLineInfoMask  mask,
bool  big_endian,
RZ_NULLABLE RzBinDwarfDebugInfo info 
)
static

Definition at line 996 of file dwarf.c.

997  {
998  // Dwarf 3 Standard 6.2 Line Number Information
999  rz_return_val_if_fail(binfile && obuf, NULL);
1000 
1001  const ut8 *buf = obuf;
1002  const ut8 *buf_start = buf;
1003  const ut8 *buf_end = obuf + len;
1004  const ut8 *tmpbuf = NULL;
1005  ut64 buf_size;
1006 
1007  // Dwarf < 5 needs this size to be supplied from outside
1008  RzBinObject *o = binfile->o;
1009  ut8 target_addr_size = o && o->info && o->info->bits ? o->info->bits / 8 : 4;
1010 
1012  if (!li) {
1013  return NULL;
1014  }
1016  if (!li->units) {
1017  free(li);
1018  return NULL;
1019  }
1020 
1024  }
1025 
1026  // each iteration we read one header AKA comp. unit
1027  while (buf <= buf_end) {
1029  if (!unit) {
1030  break;
1031  }
1032 
1033  // How much did we read from the compilation unit
1034  size_t bytes_read = 0;
1035  // calculate how much we've read by parsing header
1036  // because header unit_length includes itself
1037  buf_size = buf_end - buf;
1038 
1039  tmpbuf = buf;
1040  buf = parse_line_header(binfile, buf, buf_end, &unit->header, buf - buf_start, big_endian);
1041  if (!buf) {
1042  line_unit_free(unit);
1043  break;
1044  }
1045 
1046  bytes_read = buf - tmpbuf;
1047 
1050 
1051  // If there is more bytes in the buffer than size of the header
1052  // It means that there has to be another header/comp.unit
1053  buf_size = RZ_MIN(buf_size, unit->header.unit_length + (unit->header.is_64bit * 8 + 4)); // length field + rest of the unit
1054  if (buf_size <= bytes_read) {
1055  // no info or truncated
1056  line_unit_free(unit);
1057  continue;
1058  }
1059  if (buf_size > (buf_end - buf) + bytes_read || buf > buf_end) {
1060  line_unit_free(unit);
1061  break;
1062  }
1063  size_t tmp_read = 0;
1064 
1065  RzVector ops;
1068  }
1069 
1073  }
1074 
1075  // we read the whole compilation unit (that might be composed of more sequences)
1076  do {
1077  // reads one whole sequence
1078  tmp_read = parse_opcodes(buf, buf_size - bytes_read, &unit->header,
1081  info, fnc, big_endian, target_addr_size);
1082  bytes_read += tmp_read;
1083  buf += tmp_read; // Move in the buffer forward
1084  } while (bytes_read < buf_size && tmp_read != 0); // if nothing is read -> error, exit
1085 
1087 
1089  unit->ops_count = rz_vector_len(&ops);
1090  unit->ops = rz_vector_flush(&ops);
1091  rz_vector_fini(&ops);
1092  }
1093 
1094  if (!tmp_read) {
1095  line_unit_free(unit);
1096  break;
1097  }
1098  rz_list_push(li->units, unit);
1099  }
1102  }
1103  return li;
1104 }
static struct @29 ops[]
#define mask()
static char * regs[]
Definition: analysis_sh.c:203
RZ_API void rz_bin_source_line_info_builder_init(RzBinSourceLineInfoBuilder *builder)
Definition: dbginfo.c:9
RZ_API RzBinSourceLineInfo * rz_bin_source_line_info_builder_build_and_fini(RzBinSourceLineInfoBuilder *builder)
Definition: dbginfo.c:87
static int buf_size
Definition: debug_qnx.c:35
RZ_API void rz_bin_dwarf_line_header_free_file_cache(const RzBinDwarfLineHeader *hdr, RzBinDwarfLineFileCache fnc)
Definition: dwarf.c:589
RZ_API void rz_bin_dwarf_line_header_reset_regs(const RzBinDwarfLineHeader *hdr, RzBinDwarfSMRegisters *regs)
Definition: dwarf.c:824
static const ut8 * parse_line_header(RzBinFile *bf, const ut8 *buf, const ut8 *buf_end, RzBinDwarfLineHeader *hdr, ut64 offset_cur, bool big_endian)
Definition: dwarf.c:638
static size_t parse_opcodes(const ut8 *obuf, size_t len, const RzBinDwarfLineHeader *hdr, RzVector *ops_out, RzBinDwarfSMRegisters *regs, RZ_NULLABLE RzBinSourceLineInfoBuilder *bob, RZ_NULLABLE RzBinDwarfDebugInfo *info, RZ_NULLABLE RzBinDwarfLineFileCache fnc, bool big_endian, ut8 target_addr_size)
Definition: dwarf.c:939
RZ_API RzBinDwarfLineFileCache rz_bin_dwarf_line_header_new_file_cache(const RzBinDwarfLineHeader *hdr)
Definition: dwarf.c:585
static void line_unit_free(RzBinDwarfLineUnit *unit)
Definition: dwarf.c:982
@ RZ_BIN_DWARF_LINE_INFO_MASK_OPS
Definition: rz_bin_dwarf.h:908
@ RZ_BIN_DWARF_LINE_INFO_MASK_LINES
Definition: rz_bin_dwarf.h:909
char ** RzBinDwarfLineFileCache
Opaque cache for fully resolved filenames during Dwarf Line Info Generation This cache stores full fi...
Definition: rz_bin_dwarf.h:965
Line info of all compilation units from the entire debug_line section.
Definition: rz_bin_dwarf.h:901
struct rz_bin_source_line_info_t * lines
Definition: rz_bin_dwarf.h:903
DWARF 3 Standard Section 6.2 Line Number Information This contains the entire raw line info for one c...
Definition: rz_bin_dwarf.h:891
RzBinInfo * info
Definition: rz_bin.h:287

References rz_bin_info_t::bits, buf_size, free(), RzBinDwarfLineUnit::header, info(), rz_bin_object_t::info, RzBinDwarfLineHeader::is_64bit, len, line_unit_free(), RzBinDwarfLineInfo::lines, mask, NULL, rz_bin_file_t::o, obuf, ops, RzBinDwarfLineUnit::ops, RzBinDwarfLineUnit::ops_count, parse_line_header(), parse_opcodes(), regs, rz_bin_dwarf_line_header_free_file_cache(), rz_bin_dwarf_line_header_new_file_cache(), rz_bin_dwarf_line_header_reset_regs(), RZ_BIN_DWARF_LINE_INFO_MASK_LINES, RZ_BIN_DWARF_LINE_INFO_MASK_OPS, rz_bin_source_line_info_builder_build_and_fini(), rz_bin_source_line_info_builder_init(), rz_list_newf(), rz_list_push(), RZ_MIN, RZ_NEW0, rz_return_val_if_fail, rz_vector_fini(), rz_vector_flush(), rz_vector_init(), rz_vector_len(), RzBinDwarfLineHeader::unit_length, RzBinDwarfLineInfo::units, and ut64().

Referenced by rz_bin_dwarf_parse_line().

◆ parse_loc_raw()

static HtUP* parse_loc_raw ( HtUP *  loc_table,
const ut8 buf,
size_t  len,
size_t  addr_size,
bool  big_endian 
)
static

Definition at line 2199 of file dwarf.c.

2200  {
2201  /* GNU has their own extensions GNU locviews that we can't parse */
2202  const ut8 *const buf_start = buf;
2203  const ut8 *buf_end = buf + len;
2204  /* for recognizing Base address entry */
2205  ut64 max_offset = get_max_offset(addr_size);
2206 
2207  ut64 address_base = 0; /* remember base of the loclist */
2208  ut64 list_offset = 0;
2209 
2210  RzBinDwarfLocList *loc_list = NULL;
2212  while (buf && buf < buf_end) {
2213  ut64 start_addr = dwarf_read_address(addr_size, big_endian, &buf, buf_end);
2214  ut64 end_addr = dwarf_read_address(addr_size, big_endian, &buf, buf_end);
2215 
2216  if (start_addr == 0 && end_addr == 0) { /* end of list entry: 0, 0 */
2217  if (loc_list) {
2218  ht_up_insert(loc_table, loc_list->offset, loc_list);
2219  list_offset = buf - buf_start;
2220  loc_list = NULL;
2221  }
2222  address_base = 0;
2223  continue;
2224  } else if (start_addr == max_offset && end_addr != max_offset) {
2225  /* base address, DWARF2 doesn't have this type of entry, these entries shouldn't
2226  be in the list, they are just informational entries for further parsing (address_base) */
2227  address_base = end_addr;
2228  } else { /* location list entry: */
2229  if (!loc_list) {
2230  loc_list = create_loc_list(list_offset);
2231  }
2232  /* TODO in future parse expressions to better structure in dwarf.c and not in dwarf_process.c */
2234  block->length = READ16(buf);
2235  buf = fill_block_data(buf, buf_end, block);
2236  range = create_loc_range(start_addr + address_base, end_addr + address_base, block);
2237  if (!range) {
2238  free(block);
2239  }
2240  rz_list_append(loc_list->list, range);
2241  range = NULL;
2242  }
2243  }
2244  /* if for some reason end of list is missing, then loc_list would leak */
2245  if (loc_list) {
2246  free_loc_table_list(loc_list);
2247  }
2248  return loc_table;
2249 }
static RzBinDwarfLocList * create_loc_list(ut64 offset)
Definition: dwarf.c:2168
static ut64 get_max_offset(size_t addr_size)
Definition: dwarf.c:2156
static RzBinDwarfLocRange * create_loc_range(ut64 start, ut64 end, RzBinDwarfBlock *block)
Definition: dwarf.c:2177
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288

References create_loc_list(), create_loc_range(), dwarf_read_address(), fill_block_data(), free(), free_loc_table_list(), get_max_offset(), len, RzBinDwarfBlock::length, rz_bin_dwarf_loc_list_t::list, NULL, rz_bin_dwarf_loc_list_t::offset, capstone::range, READ16, rz_list_append(), RZ_NEW0, and ut64().

Referenced by rz_bin_dwarf_parse_loc().

◆ parse_opcodes()

static size_t parse_opcodes ( const ut8 obuf,
size_t  len,
const RzBinDwarfLineHeader hdr,
RzVector ops_out,
RzBinDwarfSMRegisters regs,
RZ_NULLABLE RzBinSourceLineInfoBuilder bob,
RZ_NULLABLE RzBinDwarfDebugInfo info,
RZ_NULLABLE RzBinDwarfLineFileCache  fnc,
bool  big_endian,
ut8  target_addr_size 
)
static

Definition at line 939 of file dwarf.c.

942  {
943  const ut8 *buf, *buf_end;
944  ut8 opcode;
945 
946  if (!obuf || !len) {
947  return 0;
948  }
949  buf = obuf;
950  buf_end = obuf + len;
951 
952  while (buf < buf_end) {
953  opcode = *buf++;
954  RzBinDwarfLineOp op = { 0 };
955  if (!opcode) {
956  buf = parse_ext_opcode(&op, hdr, buf, (buf_end - buf), big_endian, target_addr_size);
957  } else if (opcode >= hdr->opcode_base) {
958  // special opcode without args, no further parsing needed
960  op.opcode = opcode;
961  } else {
962  buf = parse_std_opcode(&op, hdr, buf, (buf_end - buf), opcode, big_endian);
963  }
964  if (!buf) {
965  break;
966  }
967  if (bob) {
968  rz_bin_dwarf_line_op_run(hdr, regs, &op, bob, info, fnc);
969  }
970  if (ops_out) {
971  rz_vector_push(ops_out, &op);
972  } else {
974  }
975  }
976  if (!buf) {
977  return 0;
978  }
979  return (size_t)(buf - obuf); // number of bytes we've moved by
980 }
RZ_API bool rz_bin_dwarf_line_op_run(const RzBinDwarfLineHeader *hdr, RzBinDwarfSMRegisters *regs, RzBinDwarfLineOp *op, RZ_NULLABLE RzBinSourceLineInfoBuilder *bob, RZ_NULLABLE RzBinDwarfDebugInfo *info, RZ_NULLABLE RzBinDwarfLineFileCache fnc)
Execute a single line op on regs and optionally store the resulting line info in bob.
Definition: dwarf.c:851
static const ut8 * parse_ext_opcode(RzBinDwarfLineOp *op, const RzBinDwarfLineHeader *hdr, const ut8 *obuf, size_t len, bool big_endian, ut8 target_addr_size)
Definition: dwarf.c:706
static const ut8 * parse_std_opcode(RzBinDwarfLineOp *op, const RzBinDwarfLineHeader *hdr, const ut8 *obuf, size_t len, ut8 opcode, bool big_endian)
Definition: dwarf.c:774
@ RZ_BIN_DWARF_LINE_OP_TYPE_SPEC
Definition: rz_bin_dwarf.h:859

References info(), len, obuf, RzBinDwarfLineHeader::opcode_base, parse_ext_opcode(), parse_std_opcode(), regs, rz_bin_dwarf_line_op_fini(), rz_bin_dwarf_line_op_run(), RZ_BIN_DWARF_LINE_OP_TYPE_SPEC, and rz_vector_push().

Referenced by parse_line_raw().

◆ parse_std_opcode()

static const ut8* parse_std_opcode ( RzBinDwarfLineOp op,
const RzBinDwarfLineHeader hdr,
const ut8 obuf,
size_t  len,
ut8  opcode,
bool  big_endian 
)
static

Definition at line 774 of file dwarf.c.

774  {
775  rz_return_val_if_fail(op && hdr && obuf, NULL);
776  const ut8 *buf = obuf;
777  const ut8 *buf_end = obuf + len;
778 
780  op->opcode = opcode;
781  switch (opcode) {
782  case DW_LNS_advance_pc:
783  buf = rz_uleb128(buf, buf_end - buf, &op->args.advance_pc, NULL);
784  break;
785  case DW_LNS_advance_line:
786  buf = rz_leb128(buf, buf_end - buf, &op->args.advance_line);
787  break;
788  case DW_LNS_set_file:
789  buf = rz_uleb128(buf, buf_end - buf, &op->args.set_file, NULL);
790  break;
791  case DW_LNS_set_column:
792  buf = rz_uleb128(buf, buf_end - buf, &op->args.set_column, NULL);
793  break;
795  op->args.fixed_advance_pc = READ16(buf);
796  break;
797  case DW_LNS_set_isa:
798  buf = rz_uleb128(buf, buf_end - buf, &op->args.set_isa, NULL);
799  break;
800 
801  // known opcodes that take no args
802  case DW_LNS_copy:
803  case DW_LNS_negate_stmt:
805  case DW_LNS_const_add_pc:
808  break;
809 
810  // unknown operands, skip the number of args given in the header.
811  default: {
812  size_t args_count = std_opcode_args_count(hdr, opcode);
813  for (size_t i = 0; i < args_count; i++) {
814  buf = rz_uleb128(buf, buf_end - buf, &op->args.advance_pc, NULL);
815  if (!buf) {
816  break;
817  }
818  }
819  }
820  }
821  return buf;
822 }
static size_t std_opcode_args_count(const RzBinDwarfLineHeader *hdr, ut8 opcode)
Definition: dwarf.c:767
#define DW_LNS_set_column
Definition: rz_bin_dwarf.h:23
#define DW_LNS_advance_pc
Definition: rz_bin_dwarf.h:20
#define DW_LNS_advance_line
Definition: rz_bin_dwarf.h:21
#define DW_LNS_set_file
Definition: rz_bin_dwarf.h:22
#define DW_LNS_copy
Definition: rz_bin_dwarf.h:19
#define DW_LNS_set_isa
Definition: rz_bin_dwarf.h:30
#define DW_LNS_negate_stmt
Definition: rz_bin_dwarf.h:24
#define DW_LNS_set_epilogue_begin
Definition: rz_bin_dwarf.h:29
@ RZ_BIN_DWARF_LINE_OP_TYPE_STD
Definition: rz_bin_dwarf.h:860
#define DW_LNS_fixed_advance_pc
Definition: rz_bin_dwarf.h:27
#define DW_LNS_set_basic_block
Definition: rz_bin_dwarf.h:25
#define DW_LNS_set_prologue_end
Definition: rz_bin_dwarf.h:28
#define DW_LNS_const_add_pc
Definition: rz_bin_dwarf.h:26

References DW_LNS_advance_line, DW_LNS_advance_pc, DW_LNS_const_add_pc, DW_LNS_copy, DW_LNS_fixed_advance_pc, DW_LNS_negate_stmt, DW_LNS_set_basic_block, DW_LNS_set_column, DW_LNS_set_epilogue_begin, DW_LNS_set_file, DW_LNS_set_isa, DW_LNS_set_prologue_end, i, len, NULL, obuf, READ16, RZ_BIN_DWARF_LINE_OP_TYPE_STD, rz_leb128(), rz_return_val_if_fail, rz_uleb128(), and std_opcode_args_count().

Referenced by parse_opcodes().

◆ rz_bin_dwarf_arange_set_free()

RZ_API void rz_bin_dwarf_arange_set_free ( RzBinDwarfARangeSet set)

Definition at line 1106 of file dwarf.c.

1106  {
1107  if (!set) {
1108  return;
1109  }
1110  free(set->aranges);
1111  free(set);
1112 }

References rz_bin_dwarf_arange_set_t::aranges, and free().

Referenced by parse_aranges_raw().

◆ rz_bin_dwarf_debug_abbrev_free()

RZ_API void rz_bin_dwarf_debug_abbrev_free ( RzBinDwarfDebugAbbrev da)

Definition at line 1340 of file dwarf.c.

1340  {
1341  size_t i;
1342  if (!da) {
1343  return;
1344  }
1345  for (i = 0; i < da->count; i++) {
1346  RZ_FREE(da->decls[i].defs);
1347  }
1348  RZ_FREE(da->decls);
1349  free(da);
1350 }

References RzBinDwarfDebugAbbrev::count, RzBinDwarfDebugAbbrev::decls, RzBinDwarfAbbrevDecl::defs, free(), i, and RZ_FREE.

Referenced by bin_dwarf(), and rz_core_bin_apply_dwarf().

◆ rz_bin_dwarf_debug_info_free()

RZ_API void rz_bin_dwarf_debug_info_free ( RzBinDwarfDebugInfo inf)

Definition at line 1407 of file dwarf.c.

1407  {
1408  if (!inf) {
1409  return;
1410  }
1411  for (size_t i = 0; i < inf->count; i++) {
1412  free_comp_unit(&inf->comp_units[i]);
1413  }
1414  ht_up_free(inf->line_info_offset_comp_dir);
1415  ht_up_free(inf->lookup_table);
1416  free(inf->comp_units);
1417  free(inf);
1418 }
static void free_comp_unit(RzBinDwarfCompUnit *cu)
Definition: dwarf.c:1394

References free(), free_comp_unit(), i, and inf().

Referenced by bin_dwarf(), parse_info_raw(), rz_bin_dwarf_parse_info(), and rz_core_bin_apply_dwarf().

◆ rz_bin_dwarf_get_attr_form_name()

RZ_API const char* rz_bin_dwarf_get_attr_form_name ( ut64  form_code)

Definition at line 373 of file dwarf.c.

373  {
374  if (form_code < DW_FORM_addr || form_code > DW_FORM_addrx4) {
375  return NULL;
376  }
377  return dwarf_attr_form_encodings[form_code];
378 }
static const char * dwarf_attr_form_encodings[]
Definition: dwarf.c:228

References DW_FORM_addrx4, dwarf_attr_form_encodings, and NULL.

Referenced by rz_core_bin_dwarf_print_abbrev_section().

◆ rz_bin_dwarf_get_attr_name()

RZ_API const char* rz_bin_dwarf_get_attr_name ( ut64  attr_code)

Definition at line 323 of file dwarf.c.

323  {
324  if (attr_code < RZ_ARRAY_SIZE(dwarf_attr_encodings)) {
325  return dwarf_attr_encodings[attr_code];
326  }
327  // the below codes are much sparser, so putting them in an array would require a lot of
328  // unused memory
329  switch (attr_code) {
330  case DW_AT_lo_user:
331  return "DW_AT_lo_user";
333  return "DW_AT_MIPS_linkage_name";
335  return "DW_AT_GNU_call_site_value";
337  return "DW_AT_GNU_call_site_data_value";
339  return "DW_AT_GNU_call_site_target";
341  return "DW_AT_GNU_call_site_target_clobbered";
342  case DW_AT_GNU_tail_call:
343  return "DW_AT_GNU_tail_call";
345  return "DW_AT_GNU_all_tail_call_sites";
347  return "DW_AT_GNU_all_call_sites";
349  return "DW_AT_GNU_all_source_call_sites";
350  case DW_AT_GNU_macros:
351  return "DW_AT_GNU_macros";
352  case DW_AT_GNU_deleted:
353  return "DW_AT_GNU_deleted";
354  case DW_AT_GNU_dwo_name:
355  return "DW_AT_GNU_dwo_name";
356  case DW_AT_GNU_dwo_id:
357  return "DW_AT_GNU_dwo_id";
359  return "DW_AT_GNU_ranges_base";
360  case DW_AT_GNU_addr_base:
361  return "DW_AT_GNU_addr_base";
362  case DW_AT_GNU_pubnames:
363  return "DW_AT_GNU_pubnames";
364  case DW_AT_GNU_pubtypes:
365  return "DW_AT_GNU_pubtypes";
366  case DW_AT_hi_user:
367  return "DW_AT_hi_user";
368  default:
369  return NULL;
370  }
371 }
static const char * dwarf_attr_encodings[]
Definition: dwarf.c:105
#define DW_AT_hi_user
Definition: rz_bin_dwarf.h:277
#define DW_AT_GNU_pubtypes
Definition: rz_bin_dwarf.h:276
#define DW_AT_GNU_all_call_sites
Definition: rz_bin_dwarf.h:267
#define DW_AT_GNU_call_site_target_clobbered
Definition: rz_bin_dwarf.h:264
#define DW_AT_GNU_all_source_call_sites
Definition: rz_bin_dwarf.h:268
#define DW_AT_GNU_deleted
Definition: rz_bin_dwarf.h:270
#define DW_AT_GNU_call_site_data_value
Definition: rz_bin_dwarf.h:262
#define DW_AT_GNU_addr_base
Definition: rz_bin_dwarf.h:274
#define DW_AT_MIPS_linkage_name
Definition: rz_bin_dwarf.h:260
#define DW_AT_GNU_call_site_value
Definition: rz_bin_dwarf.h:261
#define DW_AT_GNU_macros
Definition: rz_bin_dwarf.h:269
#define DW_AT_lo_user
Definition: rz_bin_dwarf.h:258
#define DW_AT_GNU_ranges_base
Definition: rz_bin_dwarf.h:273
#define DW_AT_GNU_dwo_name
Definition: rz_bin_dwarf.h:271
#define DW_AT_GNU_pubnames
Definition: rz_bin_dwarf.h:275
#define DW_AT_GNU_dwo_id
Definition: rz_bin_dwarf.h:272
#define DW_AT_GNU_tail_call
Definition: rz_bin_dwarf.h:265
#define DW_AT_GNU_call_site_target
Definition: rz_bin_dwarf.h:263
#define DW_AT_GNU_all_tail_call_sites
Definition: rz_bin_dwarf.h:266
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300

References DW_AT_GNU_addr_base, DW_AT_GNU_all_call_sites, DW_AT_GNU_all_source_call_sites, DW_AT_GNU_all_tail_call_sites, DW_AT_GNU_call_site_data_value, DW_AT_GNU_call_site_target, DW_AT_GNU_call_site_target_clobbered, DW_AT_GNU_call_site_value, DW_AT_GNU_deleted, DW_AT_GNU_dwo_id, DW_AT_GNU_dwo_name, DW_AT_GNU_macros, DW_AT_GNU_pubnames, DW_AT_GNU_pubtypes, DW_AT_GNU_ranges_base, DW_AT_GNU_tail_call, DW_AT_hi_user, DW_AT_lo_user, DW_AT_MIPS_linkage_name, dwarf_attr_encodings, NULL, and RZ_ARRAY_SIZE.

Referenced by rz_core_bin_dwarf_print_abbrev_section(), and rz_core_bin_dwarf_print_debug_info().

◆ rz_bin_dwarf_get_lang_name()

RZ_API const char* rz_bin_dwarf_get_lang_name ( ut64  lang)

Definition at line 387 of file dwarf.c.

387  {
388  if (lang >= RZ_ARRAY_SIZE(dwarf_langs)) {
389  return NULL;
390  }
391  return dwarf_langs[lang];
392 }
static const char * dwarf_langs[]
Definition: dwarf.c:274

References dwarf_langs, NULL, and RZ_ARRAY_SIZE.

Referenced by rz_core_bin_dwarf_print_attr_value().

◆ rz_bin_dwarf_get_tag_name()

RZ_API const char* rz_bin_dwarf_get_tag_name ( ut64  tag)

Definition at line 316 of file dwarf.c.

316  {
317  if (tag >= DW_TAG_LAST) {
318  return NULL;
319  }
321 }
static const char * dwarf_tag_name_encodings[]
Definition: dwarf.c:39
#define DW_TAG_LAST
Definition: rz_bin_dwarf.h:125

References DW_TAG_LAST, dwarf_tag_name_encodings, NULL, and test-lz4-versions::tag.

Referenced by rz_core_bin_dwarf_print_abbrev_section(), and rz_core_bin_dwarf_print_debug_info().

◆ rz_bin_dwarf_get_unit_type_name()

RZ_API const char* rz_bin_dwarf_get_unit_type_name ( ut64  unit_type)

Definition at line 380 of file dwarf.c.

380  {
381  if (!unit_type || unit_type > DW_UT_split_type) {
382  return NULL;
383  }
384  return dwarf_unit_types[unit_type];
385 }
static const char * dwarf_unit_types[]
Definition: dwarf.c:305

References DW_UT_split_type, dwarf_unit_types, and NULL.

Referenced by rz_core_bin_dwarf_print_debug_info().

◆ rz_bin_dwarf_line_header_free_file_cache()

RZ_API void rz_bin_dwarf_line_header_free_file_cache ( const RzBinDwarfLineHeader hdr,
RzBinDwarfLineFileCache  fnc 
)

Definition at line 589 of file dwarf.c.

589  {
590  if (!fnc) {
591  return;
592  }
593  for (size_t i = 0; i < hdr->file_names_count; i++) {
594  free(fnc[i]);
595  }
596  free(fnc);
597 }

References RzBinDwarfLineHeader::file_names_count, free(), and i.

Referenced by parse_line_raw().

◆ rz_bin_dwarf_line_header_get_adj_opcode()

RZ_API ut64 rz_bin_dwarf_line_header_get_adj_opcode ( const RzBinDwarfLineHeader header,
ut8  opcode 
)

Definition at line 613 of file dwarf.c.

613  {
615  return opcode - header->opcode_base;
616 }

References header, and rz_return_val_if_fail.

Referenced by print_line_op(), rz_bin_dwarf_line_header_get_spec_op_advance_line(), and rz_bin_dwarf_line_header_get_spec_op_advance_pc().

◆ rz_bin_dwarf_line_header_get_full_file_path()

RZ_API char* rz_bin_dwarf_line_header_get_full_file_path ( RZ_NULLABLE const RzBinDwarfDebugInfo info,
const RzBinDwarfLineHeader header,
ut64  file_index 
)
Parameters
infoif not NULL, filenames can get resolved to absolute paths using the compilation unit dirs from it

Definition at line 547 of file dwarf.c.

547  {
549  if (file_index >= header->file_names_count) {
550  return NULL;
551  }
552  RzBinDwarfLineFileEntry *file = &header->file_names[file_index];
553  if (!file->name) {
554  return NULL;
555  }
556 
557  /*
558  * Dwarf standard does not seem to specify the exact separator (slash/backslash) of paths
559  * so apparently it is target-dependent. However we have yet to see a Windows binary that
560  * also contains dwarf and contains backslashes. The ones we have seen from MinGW have regular
561  * slashes.
562  * And since there seems to be no way to reliable check whether the target uses slashes
563  * or backslashes anyway, we will simply use slashes always here.
564  */
565 
566  const char *comp_dir = info ? ht_up_find(info->line_info_offset_comp_dir, header->offset, NULL) : NULL;
567  const char *include_dir = NULL;
568  char *own_str = NULL;
569  if (file->id_idx > 0 && file->id_idx - 1 < header->include_dirs_count) {
570  include_dir = header->include_dirs[file->id_idx - 1];
571  if (include_dir && include_dir[0] != '/' && comp_dir) {
572  include_dir = own_str = rz_str_newf("%s/%s/", comp_dir, include_dir);
573  }
574  } else {
575  include_dir = comp_dir;
576  }
577  if (!include_dir) {
578  include_dir = "./";
579  }
580  char *r = rz_str_newf("%s/%s", include_dir, file->name);
581  free(own_str);
582  return r;
583 }
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
Definition: gzappend.c:170
char * name
Definition: gzappend.c:176

References free(), header, info(), file::name, NULL, r, rz_return_val_if_fail, and rz_str_newf().

Referenced by get_full_file_path().

◆ rz_bin_dwarf_line_header_get_spec_op_advance_line()

RZ_API st64 rz_bin_dwarf_line_header_get_spec_op_advance_line ( const RzBinDwarfLineHeader header,
ut8  opcode 
)

Definition at line 628 of file dwarf.c.

628  {
630  if (!header->line_range) {
631  // to dodge division by zero
632  return 0;
633  }
634  ut8 adj_opcode = rz_bin_dwarf_line_header_get_adj_opcode(header, opcode);
635  return header->line_base + (adj_opcode % header->line_range);
636 }
RZ_API ut64 rz_bin_dwarf_line_header_get_adj_opcode(const RzBinDwarfLineHeader *header, ut8 opcode)
Definition: dwarf.c:613

References header, rz_bin_dwarf_line_header_get_adj_opcode(), and rz_return_val_if_fail.

Referenced by print_line_op(), and rz_bin_dwarf_line_op_run().

◆ rz_bin_dwarf_line_header_get_spec_op_advance_pc()

RZ_API ut64 rz_bin_dwarf_line_header_get_spec_op_advance_pc ( const RzBinDwarfLineHeader header,
ut8  opcode 
)

Definition at line 618 of file dwarf.c.

618  {
620  if (!header->line_range) {
621  // to dodge division by zero
622  return 0;
623  }
624  ut8 adj_opcode = rz_bin_dwarf_line_header_get_adj_opcode(header, opcode);
625  return (adj_opcode / header->line_range) * header->min_inst_len;
626 }

References header, rz_bin_dwarf_line_header_get_adj_opcode(), and rz_return_val_if_fail.

Referenced by print_line_op(), and rz_bin_dwarf_line_op_run().

◆ rz_bin_dwarf_line_header_new_file_cache()

RZ_API RzBinDwarfLineFileCache rz_bin_dwarf_line_header_new_file_cache ( const RzBinDwarfLineHeader hdr)

Definition at line 585 of file dwarf.c.

585  {
586  return RZ_NEWS0(char *, hdr->file_names_count);
587 }

References RzBinDwarfLineHeader::file_names_count, and RZ_NEWS0.

Referenced by parse_line_raw().

◆ rz_bin_dwarf_line_header_reset_regs()

RZ_API void rz_bin_dwarf_line_header_reset_regs ( const RzBinDwarfLineHeader hdr,
RzBinDwarfSMRegisters regs 
)

Definition at line 824 of file dwarf.c.

824  {
825  rz_return_if_fail(hdr && regs);
826  regs->address = 0;
827  regs->file = 1;
828  regs->line = 1;
829  regs->column = 0;
830  regs->is_stmt = hdr->default_is_stmt;
831  regs->basic_block = DWARF_FALSE;
832  regs->end_sequence = DWARF_FALSE;
833  regs->prologue_end = DWARF_FALSE;
834  regs->epilogue_begin = DWARF_FALSE;
835  regs->isa = 0;
836 }
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define DWARF_FALSE
Definition: rz_bin_dwarf.h:804

References RzBinDwarfLineHeader::default_is_stmt, DWARF_FALSE, regs, and rz_return_if_fail.

Referenced by parse_line_raw(), rz_bin_dwarf_line_op_run(), and rz_core_bin_dwarf_print_line_units().

◆ rz_bin_dwarf_line_info_free()

RZ_API void rz_bin_dwarf_line_info_free ( RzBinDwarfLineInfo li)

Definition at line 1352 of file dwarf.c.

1352  {
1353  if (!li) {
1354  return;
1355  }
1356  rz_list_free(li->units);
1358  free(li);
1359 }
RZ_API void rz_bin_source_line_info_free(RzBinSourceLineInfo *sli)
Definition: dbginfo.c:137

References free(), RzBinDwarfLineInfo::lines, rz_bin_source_line_info_free(), rz_list_free(), and RzBinDwarfLineInfo::units.

Referenced by bin_dwarf().

◆ rz_bin_dwarf_line_op_fini()

RZ_API void rz_bin_dwarf_line_op_fini ( RzBinDwarfLineOp op)

Definition at line 699 of file dwarf.c.

699  {
701  if (op->type == RZ_BIN_DWARF_LINE_OP_TYPE_EXT && op->opcode == DW_LNE_define_file) {
702  free(op->args.define_file.filename);
703  }
704 }

References DW_LNE_define_file, free(), RZ_BIN_DWARF_LINE_OP_TYPE_EXT, and rz_return_if_fail.

Referenced by line_unit_free(), and parse_opcodes().

◆ rz_bin_dwarf_line_op_run()

Execute a single line op on regs and optionally store the resulting line info in bob.

Parameters
fncif not null, filenames will be resolved to their full paths using this cache.

Definition at line 851 of file dwarf.c.

852  {
853  rz_return_val_if_fail(hdr && regs && op, false);
854  switch (op->type) {
856  switch (op->opcode) {
857  case DW_LNS_copy:
858  if (bob) {
859  store_line_sample(bob, hdr, regs, info, fnc);
860  }
861  regs->basic_block = DWARF_FALSE;
862  break;
863  case DW_LNS_advance_pc:
864  regs->address += op->args.advance_pc * hdr->min_inst_len;
865  break;
866  case DW_LNS_advance_line:
867  regs->line += op->args.advance_line;
868  break;
869  case DW_LNS_set_file:
870  regs->file = op->args.set_file;
871  break;
872  case DW_LNS_set_column:
873  regs->column = op->args.set_column;
874  break;
875  case DW_LNS_negate_stmt:
876  regs->is_stmt = regs->is_stmt ? DWARF_FALSE : DWARF_TRUE;
877  break;
879  regs->basic_block = DWARF_TRUE;
880  break;
881  case DW_LNS_const_add_pc:
883  break;
885  regs->address += op->args.fixed_advance_pc;
886  break;
888  regs->prologue_end = ~0;
889  break;
891  regs->epilogue_begin = ~0;
892  break;
893  case DW_LNS_set_isa:
894  regs->isa = op->args.set_isa;
895  break;
896  default:
897  return false;
898  }
899  break;
901  switch (op->opcode) {
902  case DW_LNE_end_sequence:
903  regs->end_sequence = DWARF_TRUE;
904  if (bob) {
905  // closing entry
907  }
909  break;
910  case DW_LNE_set_address:
911  regs->address = op->args.set_address;
912  break;
913  case DW_LNE_define_file:
914  break;
916  regs->discriminator = op->args.set_discriminator;
917  break;
918  default:
919  return false;
920  }
921  break;
923  regs->address += rz_bin_dwarf_line_header_get_spec_op_advance_pc(hdr, op->opcode);
925  if (bob) {
926  store_line_sample(bob, hdr, regs, info, fnc);
927  }
928  regs->basic_block = DWARF_FALSE;
929  regs->prologue_end = DWARF_FALSE;
930  regs->epilogue_begin = DWARF_FALSE;
931  regs->discriminator = 0;
932  break;
933  default:
934  return false;
935  }
936  return true;
937 }
RZ_API void rz_bin_source_line_info_builder_push_sample(RzBinSourceLineInfoBuilder *builder, ut64 address, ut32 line, ut32 column, const char *file)
Push a new sample into the builder.
Definition: dbginfo.c:28
RZ_API st64 rz_bin_dwarf_line_header_get_spec_op_advance_line(const RzBinDwarfLineHeader *header, ut8 opcode)
Definition: dwarf.c:628
RZ_API ut64 rz_bin_dwarf_line_header_get_spec_op_advance_pc(const RzBinDwarfLineHeader *header, ut8 opcode)
Definition: dwarf.c:618
static void store_line_sample(RzBinSourceLineInfoBuilder *bob, const RzBinDwarfLineHeader *hdr, RzBinDwarfSMRegisters *regs, RZ_NULLABLE RzBinDwarfDebugInfo *info, RZ_NULLABLE RzBinDwarfLineFileCache fnc)
Definition: dwarf.c:838
#define DWARF_TRUE
Definition: rz_bin_dwarf.h:805

References DW_LNE_define_file, DW_LNE_end_sequence, DW_LNE_set_address, DW_LNE_set_discriminator, DW_LNS_advance_line, DW_LNS_advance_pc, DW_LNS_const_add_pc, DW_LNS_copy, DW_LNS_fixed_advance_pc, DW_LNS_negate_stmt, DW_LNS_set_basic_block, DW_LNS_set_column, DW_LNS_set_epilogue_begin, DW_LNS_set_file, DW_LNS_set_isa, DW_LNS_set_prologue_end, DWARF_FALSE, DWARF_TRUE, info(), RzBinDwarfLineHeader::min_inst_len, NULL, regs, rz_bin_dwarf_line_header_get_spec_op_advance_line(), rz_bin_dwarf_line_header_get_spec_op_advance_pc(), rz_bin_dwarf_line_header_reset_regs(), RZ_BIN_DWARF_LINE_OP_TYPE_EXT, RZ_BIN_DWARF_LINE_OP_TYPE_SPEC, RZ_BIN_DWARF_LINE_OP_TYPE_STD, rz_bin_source_line_info_builder_push_sample(), rz_return_val_if_fail, and store_line_sample().

Referenced by parse_opcodes(), and rz_core_bin_dwarf_print_line_units().

◆ rz_bin_dwarf_loc_free()

RZ_API void rz_bin_dwarf_loc_free ( HtUP *  loc_table)

Definition at line 2283 of file dwarf.c.

2283  {
2284  rz_return_if_fail(loc_table);
2285  loc_table->opt.freefn = free_loc_table_entry;
2286  ht_up_free(loc_table);
2287 }
static void free_loc_table_entry(HtUPKv *kv)
Definition: dwarf.c:2277

References free_loc_table_entry(), and rz_return_if_fail.

Referenced by bin_dwarf(), and rz_core_bin_apply_dwarf().

◆ rz_bin_dwarf_parse_abbrev()

RZ_API RzBinDwarfDebugAbbrev* rz_bin_dwarf_parse_abbrev ( RzBinFile binfile)

Definition at line 2144 of file dwarf.c.

2144  {
2145  rz_return_val_if_fail(binfile, NULL);
2146  size_t len = 0;
2147  ut8 *buf = get_section_bytes(binfile, "debug_abbrev", &len);
2148  if (!buf) {
2149  return NULL;
2150  }
2152  free(buf);
2153  return abbrevs;
2154 }
static RzBinDwarfDebugAbbrev * parse_abbrev_raw(const ut8 *obuf, size_t len)
Definition: dwarf.c:1973
static ut8 * get_section_bytes(RzBinFile *binfile, const char *sect_name, size_t *len)
Definition: dwarf.c:2053

References free(), get_section_bytes(), len, NULL, parse_abbrev_raw(), and rz_return_val_if_fail.

Referenced by bin_dwarf(), and rz_core_bin_apply_dwarf().

◆ rz_bin_dwarf_parse_aranges()

RZ_API RzList* rz_bin_dwarf_parse_aranges ( RzBinFile binfile)

Definition at line 2132 of file dwarf.c.

2132  {
2133  rz_return_val_if_fail(binfile, NULL);
2134  size_t len;
2135  ut8 *buf = get_section_bytes(binfile, "debug_aranges", &len);
2136  if (!buf) {
2137  return NULL;
2138  }
2139  RzList *r = parse_aranges_raw(buf, len, binfile->o && binfile->o->info && binfile->o->info->big_endian);
2140  free(buf);
2141  return r;
2142 }
static RzList * parse_aranges_raw(const ut8 *obuf, size_t obuf_sz, bool big_endian)
Definition: dwarf.c:1114
int big_endian
Definition: rz_bin.h:235

References rz_bin_info_t::big_endian, free(), get_section_bytes(), rz_bin_object_t::info, len, NULL, rz_bin_file_t::o, parse_aranges_raw(), r, and rz_return_val_if_fail.

Referenced by bin_dwarf().

◆ rz_bin_dwarf_parse_info()

RZ_API RzBinDwarfDebugInfo* rz_bin_dwarf_parse_info ( RzBinFile binfile,
RzBinDwarfDebugAbbrev da 
)

Parses .debug_info section.

Parameters
daParsed abbreviations
bin
Returns
RzBinDwarfDebugInfo* Parsed information, NULL if error

Definition at line 2075 of file dwarf.c.

2075  {
2076  rz_return_val_if_fail(binfile && da, NULL);
2078 
2079  size_t debug_str_len = 0;
2080  ut8 *debug_str_buf = get_section_bytes(binfile, "debug_str", &debug_str_len);
2081 
2082  size_t len;
2083  ut8 *buf = get_section_bytes(binfile, "debug_info", &len);
2084  if (!buf) {
2085  goto cave_debug_str_buf;
2086  }
2087  info = parse_info_raw(da, buf, len, debug_str_buf, debug_str_len,
2088  binfile->o && binfile->o->info && binfile->o->info->big_endian);
2089  if (!info) {
2090  goto cave_buf;
2091  }
2092  info->lookup_table = ht_up_new_size(info->n_dwarf_dies, NULL, NULL, NULL);
2093  if (!info->lookup_table) {
2095  info = NULL;
2096  goto cave_buf;
2097  }
2098  // build hashtable after whole parsing because of possible relocations
2099  if (info) {
2100  size_t i, j;
2101  for (i = 0; i < info->count; i++) {
2102  RzBinDwarfCompUnit *unit = &info->comp_units[i];
2103  for (j = 0; j < unit->count; j++) {
2104  RzBinDwarfDie *die = &unit->dies[j];
2105  ht_up_insert(info->lookup_table, die->offset, die); // optimization for further processing}
2106  }
2107  }
2108  }
2109 cave_buf:
2110  free(buf);
2111 cave_debug_str_buf:
2112  free(debug_str_buf);
2113  return info;
2114 }
static RzBinDwarfDebugInfo * parse_info_raw(RzBinDwarfDebugAbbrev *da, const ut8 *obuf, size_t len, const ut8 *debug_str, size_t debug_str_len, bool big_endian)
Parses whole .debug_info section.
Definition: dwarf.c:1897

References rz_bin_info_t::big_endian, RzBinDwarfCompUnit::count, RzBinDwarfCompUnit::dies, free(), get_section_bytes(), i, info(), rz_bin_object_t::info, len, NULL, rz_bin_file_t::o, RzBinDwarfDie::offset, parse_info_raw(), rz_bin_dwarf_debug_info_free(), and rz_return_val_if_fail.

Referenced by bin_dwarf(), and rz_core_bin_apply_dwarf().

◆ rz_bin_dwarf_parse_line()

RZ_API RzBinDwarfLineInfo* rz_bin_dwarf_parse_line ( RzBinFile binfile,
RZ_NULLABLE RzBinDwarfDebugInfo info,
RzBinDwarfLineInfoMask  mask 
)
Parameters
infoif not NULL, filenames can get resolved to absolute paths using the compilation unit dirs from it

Definition at line 2119 of file dwarf.c.

2119  {
2120  rz_return_val_if_fail(binfile, NULL);
2121  size_t len;
2122  ut8 *buf = get_section_bytes(binfile, "debug_line", &len);
2123  if (!buf) {
2124  return NULL;
2125  }
2126  // Actually parse the section
2127  RzBinDwarfLineInfo *r = parse_line_raw(binfile, buf, len, mask, binfile->o && binfile->o->info && binfile->o->info->big_endian, info);
2128  free(buf);
2129  return r;
2130 }
static RzBinDwarfLineInfo * parse_line_raw(RzBinFile *binfile, const ut8 *obuf, ut64 len, RzBinDwarfLineInfoMask mask, bool big_endian, RZ_NULLABLE RzBinDwarfDebugInfo *info)
Definition: dwarf.c:996

References rz_bin_info_t::big_endian, free(), get_section_bytes(), info(), rz_bin_object_t::info, len, mask, NULL, rz_bin_file_t::o, parse_line_raw(), r, and rz_return_val_if_fail.

Referenced by bin_dwarf(), and rz_core_bin_apply_dwarf().

◆ rz_bin_dwarf_parse_loc()

RZ_API HtUP* rz_bin_dwarf_parse_loc ( RzBinFile binfile,
int  addr_size 
)

Parses out the .debug_loc section into a table that maps each list as offset of a list -> LocationList.

Parameters
binfile
addr_sizemachine address size used in executable (necessary for parsing)
Returns
RZ_API*

Definition at line 2259 of file dwarf.c.

2259  {
2260  rz_return_val_if_fail(binfile, NULL);
2261  /* The standarparse_loc_raw_frame, not sure why is that */
2262  size_t len = 0;
2263  ut8 *buf = get_section_bytes(binfile, "debug_loc", &len);
2264  if (!buf) {
2265  return NULL;
2266  }
2267  HtUP /*<offset, RzBinDwarfLocList*/ *loc_table = ht_up_new0();
2268  if (!loc_table) {
2269  free(buf);
2270  return NULL;
2271  }
2272  loc_table = parse_loc_raw(loc_table, buf, len, addr_size, binfile->o && binfile->o->info && binfile->o->info->big_endian);
2273  free(buf);
2274  return loc_table;
2275 }
static HtUP * parse_loc_raw(HtUP *loc_table, const ut8 *buf, size_t len, size_t addr_size, bool big_endian)
Definition: dwarf.c:2199

References rz_bin_info_t::big_endian, free(), get_section_bytes(), rz_bin_object_t::info, len, NULL, rz_bin_file_t::o, parse_loc_raw(), and rz_return_val_if_fail.

Referenced by bin_dwarf(), and rz_core_bin_apply_dwarf().

◆ std_opcode_args_count()

static size_t std_opcode_args_count ( const RzBinDwarfLineHeader hdr,
ut8  opcode 
)
static
Returns
the number of leb128 args the std opcode takes, EXCEPT for DW_LNS_fixed_advance_pc! (see Dwarf spec)

Definition at line 767 of file dwarf.c.

767  {
768  if (!opcode || opcode > hdr->opcode_base - 1 || !hdr->std_opcode_lengths) {
769  return 0;
770  }
771  return hdr->std_opcode_lengths[opcode - 1];
772 }

References RzBinDwarfLineHeader::opcode_base, and RzBinDwarfLineHeader::std_opcode_lengths.

Referenced by parse_std_opcode().

◆ store_line_sample()

static void store_line_sample ( RzBinSourceLineInfoBuilder bob,
const RzBinDwarfLineHeader hdr,
RzBinDwarfSMRegisters regs,
RZ_NULLABLE RzBinDwarfDebugInfo info,
RZ_NULLABLE RzBinDwarfLineFileCache  fnc 
)
static

Definition at line 838 of file dwarf.c.

839  {
840  const char *file = NULL;
841  if (regs->file) {
842  file = get_full_file_path(info, hdr, fnc, regs->file - 1);
843  }
844  rz_bin_source_line_info_builder_push_sample(bob, regs->address, (ut32)regs->line, (ut32)regs->column, file);
845 }
static const char * get_full_file_path(const RzBinDwarfDebugInfo *info, const RzBinDwarfLineHeader *header, RZ_NULLABLE RzBinDwarfLineFileCache cache, ut64 file_index)
Definition: dwarf.c:599

References get_full_file_path(), info(), NULL, regs, and rz_bin_source_line_info_builder_push_sample().

Referenced by rz_bin_dwarf_line_op_run().

Variable Documentation

◆ dwarf_attr_encodings

const char* dwarf_attr_encodings[]
static

Definition at line 105 of file dwarf.c.

Referenced by rz_bin_dwarf_get_attr_name().

◆ dwarf_attr_form_encodings

const char* dwarf_attr_form_encodings[]
static

Definition at line 228 of file dwarf.c.

Referenced by rz_bin_dwarf_get_attr_form_name().

◆ dwarf_langs

const char* dwarf_langs[]
static
Initial value:
= {
[DW_LANG_C89] = "C89",
[DW_LANG_C] = "C",
[DW_LANG_Ada83] = "Ada83",
[DW_LANG_Cobol74] = "Cobol74",
[DW_LANG_Cobol85] = "Cobol85",
[DW_LANG_Fortran77] = "Fortran77",
[DW_LANG_Fortran90] = "Fortran90",
[DW_LANG_Pascal83] = "Pascal83",
[DW_LANG_Modula2] = "Modula2",
[DW_LANG_Java] = "Java",
[DW_LANG_C99] = "C99",
[DW_LANG_Ada95] = "Ada95",
[DW_LANG_Fortran95] = "Fortran95",
[DW_LANG_PLI] = "PLI",
[DW_LANG_ObjC] = "ObjC",
[DW_LANG_ObjC_plus_plus] = "ObjC_plus_plus",
[DW_LANG_UPC] = "UPC",
[DW_LANG_D] = "D",
[DW_LANG_Python] = "Python",
[DW_LANG_Rust] = "Rust",
[DW_LANG_C11] = "C11",
[DW_LANG_Swift] = "Swift",
[DW_LANG_Julia] = "Julia",
[DW_LANG_Dylan] = "Dylan",
[DW_LANG_Fortran03] = "Fortran03",
[DW_LANG_Fortran08] = "Fortran08"
}
#define DW_LANG_Rust
Definition: rz_bin_dwarf.h:549
#define DW_LANG_C89
Definition: rz_bin_dwarf.h:529
#define DW_LANG_Swift
Definition: rz_bin_dwarf.h:551
#define DW_LANG_Julia
Definition: rz_bin_dwarf.h:552
#define DW_LANG_ObjC
Definition: rz_bin_dwarf.h:544
#define DW_LANG_Java
Definition: rz_bin_dwarf.h:539
#define DW_LANG_Dylan
Definition: rz_bin_dwarf.h:553
#define DW_LANG_Modula2
Definition: rz_bin_dwarf.h:538
#define DW_LANG_PLI
Definition: rz_bin_dwarf.h:543
#define DW_LANG_Python
Definition: rz_bin_dwarf.h:548
#define DW_LANG_C_plus_plus
Definition: rz_bin_dwarf.h:532
#define DW_LANG_Cobol85
Definition: rz_bin_dwarf.h:534
#define DW_LANG_C
Definition: rz_bin_dwarf.h:530
#define DW_LANG_Fortran03
Definition: rz_bin_dwarf.h:555
#define DW_LANG_C_plus_plus_14
Definition: rz_bin_dwarf.h:554
#define DW_LANG_C99
Definition: rz_bin_dwarf.h:540
#define DW_LANG_Fortran08
Definition: rz_bin_dwarf.h:556
#define DW_LANG_ObjC_plus_plus
Definition: rz_bin_dwarf.h:545
#define DW_LANG_Pascal83
Definition: rz_bin_dwarf.h:537
#define DW_LANG_Fortran77
Definition: rz_bin_dwarf.h:535
#define DW_LANG_Ada95
Definition: rz_bin_dwarf.h:541
#define DW_LANG_D
Definition: rz_bin_dwarf.h:547
#define DW_LANG_Cobol74
Definition: rz_bin_dwarf.h:533
#define DW_LANG_Fortran95
Definition: rz_bin_dwarf.h:542
#define DW_LANG_Ada83
Definition: rz_bin_dwarf.h:531
#define DW_LANG_C11
Definition: rz_bin_dwarf.h:550
#define DW_LANG_Fortran90
Definition: rz_bin_dwarf.h:536
#define DW_LANG_UPC
Definition: rz_bin_dwarf.h:546

Definition at line 274 of file dwarf.c.

Referenced by rz_bin_dwarf_get_lang_name().

◆ dwarf_tag_name_encodings

const char* dwarf_tag_name_encodings[]
static

Definition at line 39 of file dwarf.c.

Referenced by rz_bin_dwarf_get_tag_name().

◆ dwarf_unit_types

const char* dwarf_unit_types[]
static
Initial value:
= {
[DW_UT_compile] = "DW_UT_compile",
[DW_UT_type] = "DW_UT_type",
[DW_UT_partial] = "DW_UT_partial",
[DW_UT_skeleton] = "DW_UT_skeleton",
[DW_UT_split_compile] = "DW_UT_split_compile",
[DW_UT_split_type] = "DW_UT_split_type",
[DW_UT_lo_user] = "DW_UT_lo_user",
[DW_UT_hi_user] = "DW_UT_hi_user",
}
#define DW_UT_compile
Definition: rz_bin_dwarf.h:618
#define DW_UT_partial
Definition: rz_bin_dwarf.h:620
#define DW_UT_lo_user
Definition: rz_bin_dwarf.h:624
#define DW_UT_hi_user
Definition: rz_bin_dwarf.h:625

Definition at line 305 of file dwarf.c.

Referenced by rz_bin_dwarf_get_unit_type_name().