#include "globals.h"
#include "naming.h"
#include "esb.h"
#include "esb_using_functions.h"
#include "sanitized.h"
#include "print_sections.h"
static
void
do_checking(Dwarf_Debug dbg, Dwarf_Arange *arange_buf,Dwarf_Signed i,
Dwarf_Off cu_die_offset,Dwarf_Bool first_cu,
Dwarf_Off cu_die_offset_prev, Dwarf_Die cu_die )
{
int
dres = 0;
Dwarf_Off cuhdroff = 0;
Dwarf_Off cudieoff3 = 0;
Dwarf_Error checking_err = 0;
int
is_info = 1;
dres = dwarf_get_arange_cu_header_offset(
arange_buf[i],&cuhdroff,&checking_err);
if
(dres == DW_DLV_OK) {
Dwarf_Off cudieoff2 = 0;
if
(first_cu || cu_die_offset != cu_die_offset_prev) {
dres = dwarf_die_offsets(cu_die,&glflags.DIE_overall_offset,
&glflags.DIE_offset,&checking_err);
glflags.DIE_CU_overall_offset = glflags.DIE_overall_offset;
glflags.DIE_CU_offset = glflags.DIE_offset;
if
(dres != DW_DLV_OK) {
print_error(dbg,
"dwarf_die_offsets"
, dres, checking_err);
}
}
dres = dwarf_get_cu_die_offset_given_cu_header_offset_b(
dbg,cuhdroff,is_info,&cudieoff2,&checking_err);
if
(dres == DW_DLV_OK) {
dwarf_die_offsets(cu_die,&glflags.DIE_overall_offset,
&glflags.DIE_offset,&checking_err);
glflags.DIE_CU_overall_offset = glflags.DIE_overall_offset;
glflags.DIE_CU_offset = glflags.DIE_offset;
DWARF_CHECK_COUNT(aranges_result,1);
if
(cu_die_offset != cudieoff2) {
printf
(
"Error, cu_die offsets mismatch, 0x%"
DW_PR_DUx
" != 0x%"
DW_PR_DUx
" from arange data"
,
cu_die_offset,cudieoff2);
DWARF_CHECK_ERROR(aranges_result,
" dwarf_get_cu_die_offset_given_cu..."
" gets wrong offset"
);
}
}
else
{
print_error(dbg,
"dwarf_get_cu_die_offset_given..."
, dres, checking_err);
}
}
else
{
print_error(dbg,
"dwarf_get_arange_cu_header_offset"
, dres, checking_err);
}
dres = dwarf_get_cu_die_offset(arange_buf[i],&cudieoff3,
&checking_err);
if
(dres == DW_DLV_OK) {
DWARF_CHECK_COUNT(aranges_result,1);
if
(cudieoff3 != cu_die_offset) {
printf
(
"Error, cu_die offsets (b) mismatch , 0x%"
DW_PR_DUx
" != 0x%"
DW_PR_DUx
" from arange data"
,
cu_die_offset,cudieoff3);
DWARF_CHECK_ERROR(aranges_result,
" dwarf_get_cu_die_offset "
" gets wrong offset"
);
}
}
else
{
print_error(dbg,
"dwarf_get_cu_die_offset failed "
,
dres,checking_err);
}
}
extern
void
print_aranges(Dwarf_Debug dbg)
{
Dwarf_Signed count = 0;
Dwarf_Signed i = 0;
Dwarf_Arange *arange_buf = NULL;
int
ares = 0;
int
aires = 0;
Dwarf_Off prev_off = 0;
Dwarf_Bool first_cu = TRUE;
Dwarf_Off cu_die_offset_prev = 0;
Dwarf_Error pa_error = 0;
glflags.seen_CU = FALSE;
glflags.need_CU_name = TRUE;
glflags.need_CU_base_address = TRUE;
glflags.need_CU_high_address = TRUE;
glflags.current_section_id = DEBUG_ARANGES;
ares = dwarf_get_aranges(dbg, &arange_buf, &count, &pa_error);
if
(glflags.gf_do_print_dwarf) {
struct
esb_s truename;
char
buf[DWARF_SECNAME_BUFFER_SIZE];
esb_constructor_fixed(&truename,buf,
sizeof
(buf));
get_true_section_name(dbg,
".debug_aranges"
,
&truename,TRUE);
printf
(
"\n%s\n"
,sanitized(esb_get_string(&truename)));
esb_destructor(&truename);
}
if
(ares == DW_DLV_ERROR) {
print_error(dbg,
"dwarf_get_aranges"
, ares, pa_error);
}
else
if
(ares == DW_DLV_NO_ENTRY) {
}
else
{
for
(i = 0; i < count; i++) {
Dwarf_Unsigned segment = 0;
Dwarf_Unsigned segment_entry_size = 0;
Dwarf_Addr start = 0;
Dwarf_Unsigned length = 0;
Dwarf_Off cu_die_offset = 0;
Dwarf_Die cu_die = NULL;
aires = dwarf_get_arange_info_b(arange_buf[i],
&segment,
&segment_entry_size,
&start, &length,
&cu_die_offset, &pa_error);
if
(aires != DW_DLV_OK) {
print_error(dbg,
"dwarf_get_arange_info"
, aires, pa_error);
}
else
{
int
dres;
struct
esb_s producer_name;
esb_constructor(&producer_name);
dres = dwarf_offdie(dbg, cu_die_offset, &cu_die, &pa_error);
if
(dres != DW_DLV_OK) {
print_error(dbg,
"dwarf_offdie"
, dres, pa_error);
}
if
(glflags.gf_cu_name_flag) {
if
(should_skip_this_cu(dbg,cu_die)) {
continue
;
}
}
get_producer_name(dbg,cu_die,cu_die_offset,&producer_name);
update_compiler_target(esb_get_string(&producer_name));
esb_destructor(&producer_name);
if
(!checking_this_compiler()) {
continue
;
}
if
(glflags.gf_check_aranges) {
do_checking(dbg,arange_buf,i,
cu_die_offset,first_cu,
cu_die_offset_prev,cu_die);
}
if
(start || length) {
Dwarf_Off off = 0;
int
cures3 = dwarf_get_arange_cu_header_offset(
arange_buf[i], &off, &pa_error);
if
(cures3 != DW_DLV_OK) {
print_error(dbg,
"dwarf_get_cu_hdr_offset"
,
cures3, pa_error);
}
if
(prev_off != off || first_cu) {
first_cu = FALSE;
prev_off = off;
if
(glflags.gf_do_print_dwarf){
print_one_die(dbg, cu_die,
cu_die_offset,
(boolean) TRUE,
0,
0,
0,
TRUE);
}
glflags.seen_CU = FALSE;
glflags.need_CU_name = TRUE;
if
(glflags.gf_do_print_dwarf) {
printf
(
"\n"
);
}
}
if
(glflags.gf_do_print_dwarf) {
if
(segment_entry_size) {
printf
(
"\narange starts at seg,off 0x%"
DW_PR_XZEROS DW_PR_DUx
",0x%"
DW_PR_XZEROS DW_PR_DUx
", "
,
segment,
(Dwarf_Unsigned)start);
}
else
{
printf
(
"\narange starts at 0x%"
DW_PR_XZEROS DW_PR_DUx
", "
,
(Dwarf_Unsigned)start);
}
printf
(
"length of 0x%"
DW_PR_XZEROS DW_PR_DUx
", cu_die_offset = 0x%"
DW_PR_XZEROS DW_PR_DUx,
length,
(Dwarf_Unsigned)cu_die_offset);
}
if
(glflags.verbose && glflags.gf_do_print_dwarf) {
printf
(
" cuhdr 0x%"
DW_PR_XZEROS DW_PR_DUx
"\n"
,
(Dwarf_Unsigned)off);
}
dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
cu_die = 0;
}
else
{
if
(glflags.gf_do_print_dwarf) {
printf
(
"\narange end\n"
);
}
}
}
dwarf_dealloc(dbg, arange_buf[i], DW_DLA_ARANGE);
}
dwarf_dealloc(dbg, arange_buf, DW_DLA_LIST);
}
}