#ifndef DWARF_UTIL_H
#define DWARF_UTIL_H
#define DECODE_LEB128_UWORD_CK(ptr, value,dbg,errptr,endptr) \
do
{ \
Dwarf_Unsigned lu_leblen = 0; \
Dwarf_Unsigned lu_local = 0; \
int
lu_res = 0; \
lu_res = _dwarf_decode_u_leb128_chk(ptr,&lu_leblen,&lu_local,endptr); \
if
(lu_res == DW_DLV_ERROR) { \
_dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \
return
DW_DLV_ERROR; \
} \
value = lu_local; \
ptr += lu_leblen; \
}
while
(0)
#define DECODE_LEB128_UWORD_LEN_CK(ptr, value,leblen,dbg,errptr,endptr) \
do
{ \
Dwarf_Unsigned lu_leblen = 0; \
Dwarf_Unsigned lu_local = 0; \
int
lu_res = 0; \
lu_res = _dwarf_decode_u_leb128_chk(ptr,&lu_leblen,&lu_local,endptr); \
if
(lu_res == DW_DLV_ERROR) { \
_dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \
return
DW_DLV_ERROR; \
} \
value = lu_local; \
ptr += lu_leblen; \
leblen = lu_leblen; \
}
while
(0)
#define DECODE_LEB128_SWORD_CK(ptr, value,dbg,errptr,endptr) \
do
{ \
Dwarf_Unsigned uleblen = 0; \
Dwarf_Signed local = 0; \
int
lu_res = 0; \
lu_res = _dwarf_decode_s_leb128_chk(ptr,&uleblen,&local,endptr); \
if
(lu_res == DW_DLV_ERROR) { \
_dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \
return
DW_DLV_ERROR; \
} \
value = local; \
ptr += uleblen; \
}
while
(0)
#define DECODE_LEB128_SWORD_LEN_CK(ptr, value,leblen,dbg,errptr,endptr) \
do
{ \
Dwarf_Unsigned lu_leblen = 0; \
Dwarf_Signed lu_local = 0; \
int
lu_res = 0; \
lu_res = _dwarf_decode_s_leb128_chk(ptr,&lu_leblen,\
&lu_local,endptr); \
if
(lu_res == DW_DLV_ERROR) { \
_dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \
return
DW_DLV_ERROR; \
} \
leblen = lu_leblen; \
value = lu_local; \
ptr += lu_leblen; \
}
while
(0)
#define SKIP_LEB128_WORD_CK(ptr,dbg,errptr,endptr) \
do
{ \
if
((*(ptr++) & 0x80) != 0) { \
if
(ptr >= endptr) { \
_dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \
return
DW_DLV_ERROR; \
} \
if
((*(ptr++) & 0x80) != 0) { \
if
(ptr >= endptr) { \
_dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \
return
DW_DLV_ERROR; \
} \
if
((*(ptr++) & 0x80) != 0) { \
if
(ptr >= endptr) { \
_dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \
return
DW_DLV_ERROR; \
} \
ptr++; \
if
(ptr >= endptr) { \
_dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \
return
DW_DLV_ERROR; \
} \
} \
} \
} \
}
while
(0)
#define CHECK_DIE(die, error_ret_value) \
do
{ \
if
(die == NULL) { \
_dwarf_error(NULL, error, DW_DLE_DIE_NULL); \
return
(error_ret_value); \
} \
if
(die->di_cu_context == NULL) { \
_dwarf_error(NULL, error, DW_DLE_DIE_NO_CU_CONTEXT); \
return
(error_ret_value); \
} \
if
(die->di_cu_context->cc_dbg == NULL) { \
_dwarf_error(NULL, error, DW_DLE_DBG_NULL); \
return
(error_ret_value); \
} \
}
while
(0)
typedef
Dwarf_Unsigned BIGGEST_UINT;
#ifdef WORDS_BIGENDIAN
#define READ_UNALIGNED_CK(dbg,dest,desttype, source, length,error,endptr) \
do
{ \
BIGGEST_UINT _ltmp = 0; \
Dwarf_Byte_Ptr readend = source+length; \
if
(readend < source) { \
_dwarf_error(dbg, error, DW_DLE_READ_BIGENDIAN_ERROR); \
return
DW_DLV_ERROR; \
} \
if
(readend > endptr) { \
_dwarf_error(dbg, error, DW_DLE_READ_BIGENDIAN_ERROR); \
return
DW_DLV_ERROR; \
} \
dbg->de_copy_word( (((
char
*)(&_ltmp)) + \
sizeof
(_ltmp) - length),source, length) ; \
dest = (desttype)_ltmp; \
}
while
(0)
#define SIGN_EXTEND(dest, length) \
do
{ \
if
(*(Dwarf_Sbyte *)((
char
*)&dest + \
sizeof
(dest) - length) < 0) { \
memcpy
((
char
*)&dest,
"\xff\xff\xff\xff\xff\xff\xff\xff"
,\
sizeof
(dest) - length); \
} \
}
while
(0)
#else /* LITTLE ENDIAN */
#define READ_UNALIGNED_CK(dbg,dest,desttype, source, length,error,endptr) \
do
{ \
BIGGEST_UINT _ltmp = 0; \
Dwarf_Byte_Ptr readend = source+length; \
if
(readend < source) { \
_dwarf_error(dbg, error, DW_DLE_READ_LITTLEENDIAN_ERROR);\
return
DW_DLV_ERROR; \
} \
if
(readend > endptr) { \
_dwarf_error(dbg, error, DW_DLE_READ_LITTLEENDIAN_ERROR);\
return
DW_DLV_ERROR; \
} \
dbg->de_copy_word( (
char
*)(&_ltmp) , \
source, length) ; \
dest = (desttype)_ltmp; \
}
while
(0)
#define SIGN_EXTEND(dest, length) \
do
{ \
if
(*(Dwarf_Sbyte *)((
char
*)&dest + (length-1)) < 0) { \
memcpy
((
char
*)&dest+length, \
"\xff\xff\xff\xff\xff\xff\xff\xff"
, \
sizeof
(dest) - length); \
} \
}
while
(0)
#endif /* ! LITTLE_ENDIAN */
#define READ_AREA_LENGTH_CK(r_dbg,w_target,r_targtype, \
rw_src_data_p,w_length_size,w_exten_size,w_error, \
r_sectionlen,r_endptr) \
do
{ \
READ_UNALIGNED_CK(r_dbg,w_target,r_targtype, \
rw_src_data_p, ORIGINAL_DWARF_OFFSET_SIZE, \
w_error,r_endptr); \
if
(w_target == DISTINGUISHED_VALUE) { \
\
w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE; \
rw_src_data_p += ORIGINAL_DWARF_OFFSET_SIZE; \
w_exten_size = ORIGINAL_DWARF_OFFSET_SIZE; \
READ_UNALIGNED_CK(r_dbg,w_target,r_targtype, \
rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE,\
w_error,r_endptr); \
if
(w_target > r_sectionlen) { \
_dwarf_error(r_dbg,w_error, \
DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE); \
return
DW_DLV_ERROR; \
} \
rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE; \
}
else
{ \
if
(w_target == 0 && r_dbg->de_big_endian_object) {\
\
\
if
(r_dbg->de_length_size == 8) { \
\
\
\
READ_UNALIGNED_CK(r_dbg,w_target,r_targtype,\
rw_src_data_p, \
DISTINGUISHED_VALUE_OFFSET_SIZE, \
w_error,r_endptr); \
if
(w_target > r_sectionlen) { \
_dwarf_error(r_dbg,w_error, \
DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE);\
return
DW_DLV_ERROR; \
} \
w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE;\
rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE;\
w_exten_size = 0; \
}
else
{ \
\
w_length_size = ORIGINAL_DWARF_OFFSET_SIZE;\
rw_src_data_p += w_length_size; \
w_exten_size = 0; \
} \
}
else
{ \
if
(w_target > r_sectionlen) { \
_dwarf_error(r_dbg,w_error, \
DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE);\
return
DW_DLV_ERROR; \
} \
\
w_exten_size = 0; \
w_length_size = ORIGINAL_DWARF_OFFSET_SIZE; \
rw_src_data_p += w_length_size; \
} \
} \
}
while
(0)
int
_dwarf_decode_u_leb128_chk(Dwarf_Small * leb128,
Dwarf_Unsigned * leb128_length,
Dwarf_Unsigned *outval,Dwarf_Byte_Ptr endptr);
int
_dwarf_decode_s_leb128_chk(Dwarf_Small * leb128,
Dwarf_Unsigned * leb128_length,
Dwarf_Signed *outval, Dwarf_Byte_Ptr endptr);
int
_dwarf_get_size_of_val(Dwarf_Debug dbg,
Dwarf_Unsigned form,
Dwarf_Half cu_version,
Dwarf_Half address_size,
Dwarf_Small * val_ptr,
int
v_length_size,
Dwarf_Unsigned *size_out,
Dwarf_Small *section_end_ptr,
Dwarf_Error *error);
struct
Dwarf_Hash_Table_Entry_s;
struct
Dwarf_Hash_Table_s {
unsigned
long
tb_table_entry_count;
unsigned
long
tb_total_abbrev_count;
struct
Dwarf_Hash_Table_Entry_s *tb_entries;
};
struct
Dwarf_Hash_Table_Entry_s {
Dwarf_Abbrev_List at_head;
};
int
_dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context,
Dwarf_Unsigned code,
Dwarf_Abbrev_List *list_out,Dwarf_Error *error);
int
_dwarf_check_string_valid(Dwarf_Debug dbg,
void
*areaptr,
void
*startptr,
void
*endptr,
int
suggested_error, Dwarf_Error *error);
int
_dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset,
Dwarf_Bool is_info,
Dwarf_Unsigned *area_length_out,
Dwarf_Error *error);
Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug,Dwarf_Bool dinfo);
int
_dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error *error);
int
_dwarf_load_debug_types(Dwarf_Debug dbg, Dwarf_Error *error);
void
_dwarf_free_abbrev_hash_table_contents(Dwarf_Debug dbg,
struct
Dwarf_Hash_Table_s* hash_table);
int
_dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die);
int
_dwarf_reference_outside_section(Dwarf_Die die,
Dwarf_Small * startaddr,
Dwarf_Small * pastend);
void
_dwarf_error_mv_s_to_t(Dwarf_Debug dbgs,Dwarf_Error *errs,
Dwarf_Debug dbgt,Dwarf_Error *errt);
int
_dwarf_internal_get_die_comp_dir(Dwarf_Die die,
const
char
**compdir_out,
const
char
**comp_name_out,
Dwarf_Error *error);
int
_dwarf_what_section_are_we(Dwarf_Debug dbg,
Dwarf_Small *our_pointer,
const
char
** section_name_out,
Dwarf_Small **sec_start_ptr_out,
Dwarf_Unsigned *sec_len_out,
Dwarf_Small **sec_end_ptr_out,
Dwarf_Error *error);
#endif /* DWARF_UTIL_H */