#include "config.h"
#include "dwarf_incl.h"
#include <stdio.h>
#include "dwarf_die_deliv.h"
Dwarf_Unsigned
_dwarf_get_size_of_val(Dwarf_Debug dbg,
Dwarf_Unsigned form,
Dwarf_Small * val_ptr, int v_length_size)
{
Dwarf_Unsigned length = 0;
Dwarf_Word leb128_length = 0;
Dwarf_Unsigned form_indirect = 0;
Dwarf_Unsigned ret_value = 0;
switch (form) {
default:
return (form);
case DW_FORM_addr:
return (dbg->de_pointer_size);
case DW_FORM_ref_addr:
return (v_length_size);
case DW_FORM_block1:
return (*(Dwarf_Small *) val_ptr + 1);
case DW_FORM_block2:
READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
val_ptr, sizeof(Dwarf_Half));
return (ret_value + sizeof(Dwarf_Half));
case DW_FORM_block4:
READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
val_ptr, sizeof(Dwarf_ufixed));
return (ret_value + sizeof(Dwarf_ufixed));
case DW_FORM_data1:
return (1);
case DW_FORM_data2:
return (2);
case DW_FORM_data4:
return (4);
case DW_FORM_data8:
return (8);
case DW_FORM_string:
return (strlen((char *) val_ptr) + 1);
case DW_FORM_block:
case DW_FORM_exprloc:
length = _dwarf_decode_u_leb128(val_ptr, &leb128_length);
return (length + leb128_length);
case DW_FORM_flag_present:
return (0);
case DW_FORM_flag:
return (1);
case DW_FORM_sec_offset:
return (v_length_size);
case DW_FORM_ref_udata:
_dwarf_decode_u_leb128(val_ptr, &leb128_length);
return (leb128_length);
case DW_FORM_indirect:
{
Dwarf_Word indir_len = 0;
form_indirect = _dwarf_decode_u_leb128(val_ptr, &indir_len);
if (form_indirect == DW_FORM_indirect) {
return (0);
}
return (indir_len + _dwarf_get_size_of_val(dbg,
form_indirect,
val_ptr +
indir_len,
v_length_size));
}
case DW_FORM_ref1:
return (1);
case DW_FORM_ref2:
return (2);
case DW_FORM_ref4:
return (4);
case DW_FORM_ref8:
return (8);
case DW_FORM_sdata:
_dwarf_decode_s_leb128(val_ptr, &leb128_length);
return (leb128_length);
case DW_FORM_strp:
return (v_length_size);
case DW_FORM_udata:
_dwarf_decode_u_leb128(val_ptr, &leb128_length);
return (leb128_length);
}
}
Dwarf_Abbrev_List
_dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Word code)
{
Dwarf_Debug dbg = cu_context->cc_dbg;
Dwarf_Hash_Table hash_table = cu_context->cc_abbrev_hash_table;
Dwarf_Word hash_num;
Dwarf_Abbrev_List hash_abbrev_list;
Dwarf_Abbrev_List abbrev_list;
Dwarf_Byte_Ptr abbrev_ptr;
Dwarf_Half abbrev_code, abbrev_tag;
Dwarf_Half attr_name, attr_form;
hash_num = code % ABBREV_HASH_TABLE_SIZE;
for (hash_abbrev_list = hash_table[hash_num].at_head;
hash_abbrev_list != NULL && hash_abbrev_list->ab_code != code;
hash_abbrev_list = hash_abbrev_list->ab_next);
if (hash_abbrev_list != NULL)
return (hash_abbrev_list);
abbrev_ptr = cu_context->cc_last_abbrev_ptr != NULL ?
cu_context->cc_last_abbrev_ptr :
dbg->de_debug_abbrev + cu_context->cc_abbrev_offset;
if (*abbrev_ptr == 0) {
return (NULL);
}
do {
Dwarf_Unsigned utmp;
DECODE_LEB128_UWORD(abbrev_ptr, utmp)
abbrev_code = (Dwarf_Half) utmp;
DECODE_LEB128_UWORD(abbrev_ptr, utmp)
abbrev_tag = (Dwarf_Half) utmp;
abbrev_list = (Dwarf_Abbrev_List)
_dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1);
if (abbrev_list == NULL)
return (NULL);
hash_num = abbrev_code % ABBREV_HASH_TABLE_SIZE;
if (hash_table[hash_num].at_head == NULL) {
hash_table[hash_num].at_head =
hash_table[hash_num].at_tail = abbrev_list;
} else {
hash_table[hash_num].at_tail->ab_next = abbrev_list;
hash_table[hash_num].at_tail = abbrev_list;
}
abbrev_list->ab_code = abbrev_code;
abbrev_list->ab_tag = abbrev_tag;
abbrev_list->ab_has_child = *(abbrev_ptr++);
abbrev_list->ab_abbrev_ptr = abbrev_ptr;
do {
Dwarf_Unsigned utmp3;
DECODE_LEB128_UWORD(abbrev_ptr, utmp3)
attr_name = (Dwarf_Half) utmp3;
DECODE_LEB128_UWORD(abbrev_ptr, utmp3)
attr_form = (Dwarf_Half) utmp3;
} while (attr_name != 0 && attr_form != 0);
} while (*abbrev_ptr != 0 && abbrev_code != code);
cu_context->cc_last_abbrev_ptr = abbrev_ptr;
return (abbrev_code == code ? abbrev_list : NULL);
}
int
_dwarf_string_valid(void *startptr, void *endptr)
{
char *start = startptr;
char *end = endptr;
while (start < end) {
if (*start == 0) {
return 1;
}
++start;
++end;
}
return 0;
}
void *
_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len)
{
void *orig_s1 = s1;
unsigned char *targ = (unsigned char *) s1;
unsigned char *src = (unsigned char *) s2;
if (len == 4) {
targ[3] = src[0];
targ[2] = src[1];
targ[1] = src[2];
targ[0] = src[3];
} else if (len == 8) {
targ[7] = src[0];
targ[6] = src[1];
targ[5] = src[2];
targ[4] = src[3];
targ[3] = src[4];
targ[2] = src[5];
targ[1] = src[6];
targ[0] = src[7];
} else if (len == 2) {
targ[1] = src[0];
targ[0] = src[1];
}
else if (len == 1) {
targ[0] = src[0];
} else {
memcpy(s1, s2, len);
}
return orig_s1;
}
Dwarf_Unsigned
_dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset)
{
int local_length_size = 0;
int local_extension_size = 0;
Dwarf_Unsigned length = 0;
Dwarf_Small *cuptr = dbg->de_debug_info + offset;
READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
cuptr, local_length_size, local_extension_size);
return local_extension_size +
local_length_size +
sizeof(Dwarf_Half) +
local_length_size +
sizeof(Dwarf_Small);
}
Dwarf_Unsigned
_dwarf_length_of_cu_header_simple(Dwarf_Debug dbg)
{
return dbg->de_length_size +
sizeof(Dwarf_Half) +
dbg->de_length_size +
sizeof(Dwarf_Small);
}
int
_dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error * error)
{
int res;
if (dbg->de_debug_info) {
return DW_DLV_OK;
}
res = _dwarf_load_section(dbg, dbg->de_debug_abbrev_index,
&dbg->de_debug_abbrev, error);
if (res != DW_DLV_OK) {
return res;
}
res = _dwarf_load_section(dbg, dbg->de_debug_info_index,
&dbg->de_debug_info, error);
return res;
}