|
|
@ -119,6 +119,7 @@ abbrev_entry_offset(u8 *file, u64 abbrev_offset, u32 requested_code) |
|
|
|
|
|
|
|
|
|
|
|
u32 has_children = file[abbrev_offset + offset++]; |
|
|
|
u32 has_children = file[abbrev_offset + offset++]; |
|
|
|
(void) has_children; |
|
|
|
(void) has_children; |
|
|
|
|
|
|
|
|
|
|
|
if (code == requested_code) { |
|
|
|
if (code == requested_code) { |
|
|
|
return(abbrev_offset); |
|
|
|
return(abbrev_offset); |
|
|
|
} |
|
|
|
} |
|
|
@ -654,7 +655,7 @@ TODO: The DW_OP_form_tls_address operation pops a value from the stack, translat |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static u32 |
|
|
|
static u32 |
|
|
|
read_actual_debug_data(u8 *file, u64 string_offset, u32 address_size, u64 base_data_offset, u32 form, u64 data_offset, u64 *value) |
|
|
|
read_actual_debug_data(u8 *file, u64 string_offset, u32 address_size, u32 form, u64 data_offset, u64 *value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
u32 increment = 0; |
|
|
|
u32 increment = 0; |
|
|
|
|
|
|
|
|
|
|
@ -691,7 +692,8 @@ read_actual_debug_data(u8 *file, u64 string_offset, u32 address_size, u64 base_d |
|
|
|
u32 offset; |
|
|
|
u32 offset; |
|
|
|
memcpy(&offset, file + data_offset, 4); |
|
|
|
memcpy(&offset, file + data_offset, 4); |
|
|
|
increment = 4; |
|
|
|
increment = 4; |
|
|
|
*value = file[base_data_offset + offset]; |
|
|
|
//*value = file[base_data_offset + offset];
|
|
|
|
|
|
|
|
*value = offset; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -765,15 +767,21 @@ read_debug_info_for_compilation_unit(u8 *file, struct mi_debuginfo *dest, |
|
|
|
u32 code, tag; |
|
|
|
u32 code, tag; |
|
|
|
u64 schema_offset; |
|
|
|
u64 schema_offset; |
|
|
|
u32 depth = 0; |
|
|
|
u32 depth = 0; |
|
|
|
u64 base_data_offset = data_offset - header_size; |
|
|
|
//u64 base_data_offset = data_offset - header_size;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int vars_from = dest->var_count; |
|
|
|
|
|
|
|
int types_from = dest->type_count; |
|
|
|
|
|
|
|
|
|
|
|
struct mi_compunit *comp_unit = dest->compilation_units + dest->cu_count; |
|
|
|
struct mi_compunit *comp_unit = dest->compilation_units + dest->cu_count; |
|
|
|
struct mi_function *func = dest->functions + dest->func_count; |
|
|
|
struct mi_function *func = dest->functions + dest->func_count; |
|
|
|
struct mi_variable *variable = dest->variables + dest->var_count; |
|
|
|
struct mi_variable *variable = dest->variables + dest->var_count; |
|
|
|
|
|
|
|
struct mi_type *type = dest->types + dest->type_count; |
|
|
|
|
|
|
|
|
|
|
|
comp_unit->functions_from = dest->func_count; |
|
|
|
comp_unit->functions_from = dest->func_count; |
|
|
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
|
|
|
|
|
s64 record_offset = data_offset - debug_info_offset; |
|
|
|
|
|
|
|
|
|
|
|
data_offset += decode_leb128(file + data_offset, &code); |
|
|
|
data_offset += decode_leb128(file + data_offset, &code); |
|
|
|
|
|
|
|
|
|
|
|
if (code == 0) { |
|
|
|
if (code == 0) { |
|
|
@ -804,7 +812,7 @@ read_debug_info_for_compilation_unit(u8 *file, struct mi_debuginfo *dest, |
|
|
|
|
|
|
|
|
|
|
|
u64 value; |
|
|
|
u64 value; |
|
|
|
|
|
|
|
|
|
|
|
data_offset += read_actual_debug_data(file, debug_str_offset, di_header.address_size, base_data_offset, form, data_offset, &value); |
|
|
|
data_offset += read_actual_debug_data(file, debug_str_offset, di_header.address_size, form, data_offset, &value); |
|
|
|
|
|
|
|
|
|
|
|
if (tag == DW_TAG_compile_unit) { |
|
|
|
if (tag == DW_TAG_compile_unit) { |
|
|
|
if (attribute == DW_AT_low_pc) { |
|
|
|
if (attribute == DW_AT_low_pc) { |
|
|
@ -827,6 +835,49 @@ read_debug_info_for_compilation_unit(u8 *file, struct mi_debuginfo *dest, |
|
|
|
variable->name = (char *) value; |
|
|
|
variable->name = (char *) value; |
|
|
|
} else if (attribute == DW_AT_location) { |
|
|
|
} else if (attribute == DW_AT_location) { |
|
|
|
variable->location = value; |
|
|
|
variable->location = value; |
|
|
|
|
|
|
|
} else if (attribute == DW_AT_type) { |
|
|
|
|
|
|
|
variable->type = value; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else if (tag == DW_TAG_base_type) { |
|
|
|
|
|
|
|
type->_offset = record_offset; |
|
|
|
|
|
|
|
if (attribute == DW_AT_name) { |
|
|
|
|
|
|
|
type->name = (char *) value; |
|
|
|
|
|
|
|
} else if (attribute == DW_AT_byte_size) { |
|
|
|
|
|
|
|
type->size = value; |
|
|
|
|
|
|
|
} else if (attribute == DW_AT_encoding) { |
|
|
|
|
|
|
|
enum dwarf_type_encoding encoding = value; |
|
|
|
|
|
|
|
switch (encoding) { |
|
|
|
|
|
|
|
case DW_ATE_address: { |
|
|
|
|
|
|
|
type->encoding = MI_ADDRESS; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case DW_ATE_boolean: { |
|
|
|
|
|
|
|
type->encoding = MI_BOOLEAN; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case DW_ATE_float: { |
|
|
|
|
|
|
|
type->encoding = MI_FLOAT; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case DW_ATE_signed_char: |
|
|
|
|
|
|
|
case DW_ATE_signed: { |
|
|
|
|
|
|
|
type->encoding = MI_SIGNED; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case DW_ATE_unsigned_char: |
|
|
|
|
|
|
|
case DW_ATE_unsigned: { |
|
|
|
|
|
|
|
type->encoding = MI_UNSIGNED; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default: { |
|
|
|
|
|
|
|
DIE("unexpected type encoding!\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} while (attribute != 0 || form != 0); |
|
|
|
} while (attribute != 0 || form != 0); |
|
|
@ -843,6 +894,23 @@ read_debug_info_for_compilation_unit(u8 *file, struct mi_debuginfo *dest, |
|
|
|
++parent->variables_count; |
|
|
|
++parent->variables_count; |
|
|
|
++dest->var_count; |
|
|
|
++dest->var_count; |
|
|
|
++variable; |
|
|
|
++variable; |
|
|
|
|
|
|
|
} else if (tag == DW_TAG_base_type) { |
|
|
|
|
|
|
|
++dest->type_count; |
|
|
|
|
|
|
|
++type; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Resolve types
|
|
|
|
|
|
|
|
for (int v = vars_from; v < dest->var_count; ++v) { |
|
|
|
|
|
|
|
struct mi_variable *variable = dest->variables + v; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int t = types_from; t < dest->type_count; ++t) { |
|
|
|
|
|
|
|
struct mi_type *type = dest->types + t; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (type->_offset == variable->type) { |
|
|
|
|
|
|
|
variable->type = t; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|