#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "dwarf_incl.h"
#include "dwarf_alloc.h"
#include "dwarf_error.h"
#include "dwarf_util.h"
#include "dwarf_line.h"
#include "dwarfstring.h"
#define PRINTING_DETAILS 1
static void
print_line_header(Dwarf_Debug dbg,
Dwarf_Bool is_single_tab,
Dwarf_Bool is_actuals_tab)
{
if (!is_single_tab) {
if (is_actuals_tab) {
_dwarf_printf(dbg,"\nActuals Table\n");
_dwarf_printf(dbg,
" be\n"
" ls\n"
" ce\n"
" section op kq\n"
" offset code address/index row isa ??\n");
return;
} else {
_dwarf_printf(dbg,"\nLogicals Table\n");
_dwarf_printf(dbg,
" s pe\n"
" tirp\n"
" msoi\n"
" section op tall\n"
" offset row code address/indx fil lne col disc cntx subp ????\n");
return;
}
}
_dwarf_printf(dbg,
" s b e p e i d\n"
" t l s r p s i\n"
" m c e o i a s\n"
" section op col t k q l l c\n"
" offset code address file line umn ? ? ? ? ?\n");
}
static void
print_line_detail(
Dwarf_Debug dbg,
const char *prefix,
int opcode,
unsigned curr_line,
struct Dwarf_Line_Registers_s * regs,
Dwarf_Bool is_single_table, Dwarf_Bool is_actuals_table)
{
dwarfstring m1;
dwarfstring_constructor(&m1);
if(!is_single_table && is_actuals_table) {
dwarfstring_append_printf_s(&m1,"%-15s ",(char *)prefix);
dwarfstring_append_printf_i(&m1,"%3d ",opcode);
dwarfstring_append_printf_u(&m1,"0x%" DW_PR_XZEROS DW_PR_DUx ,
regs->lr_address);
dwarfstring_append_printf_u(&m1,"/%01u",regs->lr_op_index);
dwarfstring_append_printf_u(&m1," %5lu", regs->lr_line);
dwarfstring_append_printf_u(&m1," %3d",regs->lr_isa);
dwarfstring_append_printf_i(&m1," %1d", regs->lr_basic_block);
dwarfstring_append_printf_i(&m1,"%1d\n", regs->lr_end_sequence);
_dwarf_printf(dbg,dwarfstring_string(&m1));
dwarfstring_destructor(&m1);
return;
}
if(!is_single_table && !is_actuals_table) {
dwarfstring_append_printf_i(&m1,
"[%3d] " , curr_line);
dwarfstring_append_printf_s(&m1,
"%-15s ",(char *)prefix);
dwarfstring_append_printf_i(&m1,
"%3d ",opcode);
dwarfstring_append_printf_u(&m1,
"x%" DW_PR_XZEROS DW_PR_DUx, regs->lr_address);
dwarfstring_append_printf_u(&m1,
"/%01u", regs->lr_op_index);
dwarfstring_append_printf_u(&m1," %2lu ",regs->lr_file);
dwarfstring_append_printf_u(&m1,"%4lu ",regs->lr_line);
dwarfstring_append_printf_u(&m1,"%1lu",regs->lr_column);
if (regs->lr_discriminator ||
regs->lr_prologue_end ||
regs->lr_epilogue_begin ||
regs->lr_isa ||
regs->lr_is_stmt ||
regs->lr_call_context ||
regs->lr_subprogram) {
dwarfstring_append_printf_u(&m1,
" x%02" DW_PR_DUx ,
regs->lr_discriminator);
dwarfstring_append_printf_u(&m1,
" x%02" DW_PR_DUx , regs->lr_call_context);
dwarfstring_append_printf_u(&m1,
" x%02" DW_PR_DUx , regs->lr_subprogram);
dwarfstring_append_printf_i(&m1,
" %1d", regs->lr_is_stmt);
dwarfstring_append_printf_i(&m1,
"%1d", (int) regs->lr_isa);
dwarfstring_append_printf_i(&m1,
"%1d", regs->lr_prologue_end);
dwarfstring_append_printf_i(&m1,
"%1d", regs->lr_epilogue_begin);
}
dwarfstring_append(&m1,"\n");
_dwarf_printf(dbg,dwarfstring_string(&m1));
dwarfstring_destructor(&m1);
return;
}
dwarfstring_append_printf_s(&m1,
"%-15s ",(char *)prefix);
dwarfstring_append_printf_i(&m1,
"%2d ",opcode);
dwarfstring_append_printf_u(&m1,
"0x%" DW_PR_XZEROS DW_PR_DUx " ",
regs->lr_address);
dwarfstring_append_printf_u(&m1,
"%2lu ", regs->lr_file);
dwarfstring_append_printf_u(&m1,
"%4lu ", regs->lr_line);
dwarfstring_append_printf_u(&m1,
"%2lu ", regs->lr_column);
dwarfstring_append_printf_i(&m1,
"%1d ",regs->lr_is_stmt);
dwarfstring_append_printf_i(&m1,
"%1d ", regs->lr_basic_block);
dwarfstring_append_printf_i(&m1,
"%1d",regs->lr_end_sequence);
if (regs->lr_discriminator ||
regs->lr_prologue_end ||
regs->lr_epilogue_begin ||
regs->lr_isa) {
dwarfstring_append_printf_i(&m1,
" %1d", regs->lr_prologue_end);
dwarfstring_append_printf_i(&m1,
" %1d", regs->lr_epilogue_begin);
dwarfstring_append_printf_i(&m1,
" %1d", regs->lr_isa);
dwarfstring_append_printf_u(&m1,
" 0x%" DW_PR_DUx , regs->lr_discriminator);
}
dwarfstring_append(&m1, "\n");
_dwarf_printf(dbg,dwarfstring_string(&m1));
dwarfstring_destructor(&m1);
}
#include "dwarf_line_table_reader_common.h"
static void
print_include_directory_details(Dwarf_Debug dbg,
unsigned int line_version,
Dwarf_Line_Context line_context)
{
Dwarf_Unsigned u = 0;
dwarfstring m4;
dwarfstring_constructor(&m4);
if (line_version == DW_LINE_VERSION5) {
unsigned i = 0;
unsigned dfcount = line_context->lc_directory_entry_format_count;
dwarfstring_constructor(&m4);
dwarfstring_append_printf_u(&m4,
" directory entry format count %u\n",dfcount);
_dwarf_printf(dbg,dwarfstring_string(&m4));
dwarfstring_reset(&m4);
for ( ; i < dfcount;++i) {
struct Dwarf_Unsigned_Pair_s *valpair = 0;
const char *tname = 0;
const char *fname = 0;
int res;
valpair = line_context->lc_directory_format_values +i;
dwarfstring_append_printf_u(&m4,
" format [%2u] ",i);
res = dwarf_get_LNCT_name(valpair->up_first,
&tname);
if ( res != DW_DLV_OK) {
tname = "<unknown type>";
}
dwarfstring_append_printf_u (&m4,
" type 0x%" DW_PR_XZEROS DW_PR_DUx ,valpair->up_first);
dwarfstring_append_printf_s (&m4,
" %-20s\n",(char *)tname);
res = dwarf_get_FORM_name(valpair->up_second,&fname);
if ( res != DW_DLV_OK) {
fname = "<unknown form>";
}
dwarfstring_append_printf_u(&m4,
" code 0x%" DW_PR_XZEROS DW_PR_DUx ,
valpair->up_second);
dwarfstring_append_printf_s(&m4,
" %-20s\n", (char *)fname);
_dwarf_printf(dbg,dwarfstring_string(&m4));
dwarfstring_reset(&m4);
}
}
dwarfstring_append_printf_i(&m4,
" include directories count %d\n",
(int) line_context->lc_include_directories_count);
_dwarf_printf(dbg,dwarfstring_string(&m4));
dwarfstring_reset(&m4);
for (u = 0; u < line_context->lc_include_directories_count; ++u) {
dwarfstring_append_printf_u(&m4,
" include dir[%u] ",u);
dwarfstring_append_printf_s(&m4,
"%s\n",
(char *)line_context->lc_include_directories[u]);
_dwarf_printf(dbg,dwarfstring_string(&m4));
dwarfstring_reset(&m4);
}
dwarfstring_destructor(&m4);
}
static void
print_just_file_entry_details(Dwarf_Debug dbg,
Dwarf_Line_Context line_context)
{
unsigned fiu = 0;
Dwarf_File_Entry fe = line_context->lc_file_entries;
Dwarf_File_Entry fe2 = fe;
dwarfstring m3;
dwarfstring_constructor(&m3);
dwarfstring_append_printf_i(&m3,
" file names count %d\n",
line_context->lc_file_entry_count);
_dwarf_printf(dbg,dwarfstring_string(&m3));
dwarfstring_reset(&m3);
for (fiu = 0 ; fe2 ; fe2 = fe->fi_next,++fiu ) {
Dwarf_Unsigned tlm2 = 0;
unsigned filenum = 0;
fe = fe2;
tlm2 = fe->fi_time_last_mod;
filenum = fiu+1;
if (line_context->lc_file_entry_count > 9) {
dwarfstring_append_printf_u(&m3,
" file[%2u] ",fiu);
dwarfstring_append_printf_s(&m3,
"%-20s ",
(char *) fe->fi_file_name);
dwarfstring_append_printf_u(&m3,
"(file-number: %u)\n",
filenum);
} else {
dwarfstring_append_printf_u(&m3,
" file[%u] ", fiu);
dwarfstring_append_printf_s(&m3,
"%-20s ",(char *)fe->fi_file_name);
dwarfstring_append_printf_u(&m3,
"(file-number: %u)\n",filenum);
}
_dwarf_printf(dbg,dwarfstring_string(&m3));
dwarfstring_reset(&m3);
if (fe->fi_dir_index_present) {
Dwarf_Unsigned di = 0;
di = fe->fi_dir_index;
dwarfstring_append_printf_i(&m3,
" dir index %d\n", di);
}
if (fe->fi_time_last_mod_present) {
time_t tt = (time_t) tlm2;
dwarfstring_append_printf_u(&m3,
" last time 0x%x ",tlm2);
dwarfstring_append(&m3,(char *)ctime(&tt));
}
if (fe->fi_file_length_present) {
Dwarf_Unsigned fl = 0;
fl = fe->fi_file_length;
dwarfstring_append_printf_i(&m3,
" file length %ld ",fl);
dwarfstring_append_printf_u(&m3,
"0x%lx\n",fl);
}
if (fe->fi_md5_present) {
char *c = (char *)&fe->fi_md5_value;
char *end = c+sizeof(fe->fi_md5_value);
dwarfstring_append(&m3, " file md5 value 0x");
while(c < end) {
dwarfstring_append_printf_u(&m3,
"%02x",0xff&*c);
++c;
}
dwarfstring_append(&m3,"\n");
}
if (dwarfstring_strlen(&m3)) {
_dwarf_printf(dbg,dwarfstring_string(&m3));
dwarfstring_reset(&m3);
}
}
dwarfstring_destructor(&m3);
}
static void
print_file_entry_details(Dwarf_Debug dbg,
unsigned int line_version,
Dwarf_Line_Context line_context)
{
dwarfstring m5;
dwarfstring_constructor(&m5);
if (line_version == DW_LINE_VERSION5) {
unsigned i = 0;
unsigned dfcount = line_context->lc_file_name_format_count;
dwarfstring_append_printf_u(&m5,
" file entry format count %u\n",dfcount);
for ( ; i < dfcount;++i) {
struct Dwarf_Unsigned_Pair_s *valpair = 0;
const char *tname = 0;
const char *fname = 0;
int res;
valpair = line_context->lc_file_format_values +i;
dwarfstring_append_printf_u(&m5,
" format [%2u] ",i);
res = dwarf_get_LNCT_name(valpair->up_first,&tname);
if ( res != DW_DLV_OK) {
tname = "<unknown type>";
}
dwarfstring_append_printf_u(&m5,
" type 0x%" DW_PR_XZEROS DW_PR_DUx,
valpair->up_first);
dwarfstring_append_printf_s(&m5,
" %-20s\n",(char *)tname);
res = dwarf_get_FORM_name(valpair->up_second,&fname);
if ( res != DW_DLV_OK) {
fname = "<unknown form>";
}
dwarfstring_append_printf_u(&m5,
" code 0x%"
DW_PR_XZEROS DW_PR_DUx,
valpair->up_second);
dwarfstring_append_printf_s(&m5, " %-20s\n",
(char *)fname);
_dwarf_printf(dbg,dwarfstring_string(&m5));
dwarfstring_reset(&m5);
}
dwarfstring_destructor(&m5);
print_just_file_entry_details(dbg,line_context);
} else {
print_just_file_entry_details(dbg,line_context);
dwarfstring_destructor(&m5);
}
}
static void
print_experimental_subprograms_list(Dwarf_Debug dbg,
Dwarf_Line_Context line_context)
{
Dwarf_Unsigned count = line_context->lc_subprogs_count;
Dwarf_Unsigned exu = 0;
Dwarf_Subprog_Entry sub = line_context->lc_subprogs;
dwarfstring m6;
dwarfstring_constructor(&m6);
dwarfstring_append_printf_u(&m6,
" subprograms count %" DW_PR_DUu "\n",count);
if (count > 0) {
dwarfstring_append(&m6," indx file line name\n");
}
_dwarf_printf(dbg,dwarfstring_string(&m6));
dwarfstring_reset(&m6);
for (exu = 0 ; exu < count ; exu++,sub++) {
dwarfstring_append_printf_u(&m6,
" [%2" DW_PR_DUu,exu+1);
dwarfstring_append_printf_u(&m6,
"] %4" DW_PR_DUu,sub->ds_decl_file);
dwarfstring_append_printf_u(&m6,
" %4" DW_PR_DUu ,sub->ds_decl_line);
dwarfstring_append_printf_s(&m6,
" %s\n",(char *)sub->ds_subprog_name);
_dwarf_printf(dbg,dwarfstring_string(&m6));
dwarfstring_reset(&m6);
}
dwarfstring_destructor(&m6);
}
static void
do_line_print_now(Dwarf_Debug dbg,int line_version,
Dwarf_Small * comp_dir,
Dwarf_Line_Context line_context) ;
static void print_experimental_counts(Dwarf_Debug dbg,
int line_version,
Dwarf_Line_Context line_context);
static int print_actuals_and_locals(Dwarf_Debug dbg,
Dwarf_Line_Context line_context,
Dwarf_Unsigned bogus_bytes_count,
Dwarf_Small *bogus_bytes_ptr,
Dwarf_Small *orig_line_ptr,
Dwarf_Small *line_ptr,
Dwarf_Small *section_start,
Dwarf_Small *line_ptr_actuals,
Dwarf_Small *line_ptr_end,
Dwarf_Half address_size,
int * err_count_out,
Dwarf_Error *err);
static int
_dwarf_internal_printlines(Dwarf_Die die,
int * err_count_out,
int only_line_header,
Dwarf_Error * error)
{
Dwarf_Small *line_ptr = 0;
Dwarf_Small *orig_line_ptr = 0;
Dwarf_Attribute stmt_list_attr = 0;
Dwarf_Attribute comp_dir_attr = 0;
Dwarf_Small *comp_dir = NULL;
Dwarf_Unsigned line_offset = 0;
Dwarf_Half attrform = 0;
Dwarf_Small* bogus_bytes_ptr = 0;
Dwarf_Unsigned bogus_bytes_count = 0;
Dwarf_Half address_size = 0;
Dwarf_Unsigned fission_offset = 0;
unsigned line_version = 0;
Dwarf_Debug dbg = 0;
Dwarf_CU_Context cu_context = 0;
Dwarf_Line_Context line_context = 0;
int resattr = DW_DLV_ERROR;
int lres = DW_DLV_ERROR;
int res = DW_DLV_ERROR;
Dwarf_Small *line_ptr_actuals = 0;
Dwarf_Small *line_ptr_end = 0;
Dwarf_Small *section_start = 0;
if (error != NULL) {
*error = NULL;
}
CHECK_DIE(die, DW_DLV_ERROR);
cu_context = die->di_cu_context;
dbg = cu_context->cc_dbg;
res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
if (res != DW_DLV_OK) {
return res;
}
if (!dbg->de_debug_line.dss_size) {
return (DW_DLV_NO_ENTRY);
}
address_size = _dwarf_get_address_size(dbg, die);
resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
if (resattr != DW_DLV_OK) {
return resattr;
}
lres = dwarf_whatform(stmt_list_attr,&attrform,error);
if (lres != DW_DLV_OK) {
dwarf_dealloc(dbg,stmt_list_attr, DW_DLA_ATTR);
return lres;
}
if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 &&
attrform != DW_FORM_sec_offset ) {
dwarf_dealloc(dbg,stmt_list_attr, DW_DLA_ATTR);
_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
return (DW_DLV_ERROR);
}
lres = dwarf_global_formref(stmt_list_attr, &line_offset, error);
if (lres != DW_DLV_OK) {
dwarf_dealloc(dbg,stmt_list_attr, DW_DLA_ATTR);
return lres;
}
if (line_offset >= dbg->de_debug_line.dss_size) {
dwarf_dealloc(dbg,stmt_list_attr, DW_DLA_ATTR);
_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
return (DW_DLV_ERROR);
}
section_start = dbg->de_debug_line.dss_data;
{
Dwarf_Unsigned fission_size = 0;
int resfis = _dwarf_get_fission_addition_die(die, DW_SECT_LINE,
&fission_offset,&fission_size,error);
if(resfis != DW_DLV_OK) {
dwarf_dealloc(dbg,stmt_list_attr, DW_DLA_ATTR);
return resfis;
}
}
orig_line_ptr = section_start + line_offset + fission_offset;
line_ptr = orig_line_ptr;
dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
if (resattr == DW_DLV_ERROR) {
return resattr;
}
if (resattr == DW_DLV_OK) {
int cres = DW_DLV_ERROR;
char *cdir = 0;
cres = dwarf_formstring(comp_dir_attr, &cdir, error);
if (cres == DW_DLV_ERROR) {
return cres;
} else if (cres == DW_DLV_OK) {
comp_dir = (Dwarf_Small *) cdir;
}
}
if (resattr == DW_DLV_OK) {
dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
}
line_context = (Dwarf_Line_Context)
_dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
if (line_context == NULL) {
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
{
Dwarf_Small *newlinep = 0;
int dres = _dwarf_read_line_table_header(dbg,
cu_context,
section_start,
line_ptr,
dbg->de_debug_line.dss_size,
&newlinep,
line_context,
&bogus_bytes_ptr,
&bogus_bytes_count,
error,
err_count_out);
if (dres == DW_DLV_ERROR) {
dwarf_srclines_dealloc_b(line_context);
return dres;
}
if (dres == DW_DLV_NO_ENTRY) {
dwarf_srclines_dealloc_b(line_context);
return dres;
}
line_ptr_end = line_context->lc_line_ptr_end;
line_ptr = newlinep;
if (line_context->lc_actuals_table_offset > 0) {
line_ptr_actuals = line_context->lc_line_prologue_start +
line_context->lc_actuals_table_offset;
}
}
line_version = line_context->lc_version_number;
line_context->lc_compilation_directory = comp_dir;
if (only_line_header) {
dwarf_srclines_dealloc_b(line_context);
return DW_DLV_OK;
}
do_line_print_now(dbg,line_version,comp_dir,line_context);
print_include_directory_details(dbg,line_version,line_context);
print_file_entry_details(dbg,line_version,line_context);
print_experimental_counts(dbg, line_version,line_context);
res = print_actuals_and_locals(dbg, line_context,
bogus_bytes_count,bogus_bytes_ptr,
orig_line_ptr,
line_ptr,
section_start,
line_ptr_actuals,
line_ptr_end,
address_size,
err_count_out,
error);
if (res != DW_DLV_OK) {
return res;
}
return DW_DLV_OK;
}
static void
do_line_print_now(Dwarf_Debug dbg,
int line_version,
Dwarf_Small *comp_dir,
Dwarf_Line_Context line_context)
{
dwarfstring m7;
Dwarf_Unsigned i = 0;
dwarfstring_constructor(&m7);
dwarfstring_append_printf_i(&m7,
"total line info length %ld bytes,",
line_context->lc_total_length);
dwarfstring_append_printf_u(&m7,
" line offset 0x%" DW_PR_XZEROS DW_PR_DUx,
line_context->lc_section_offset);
dwarfstring_append_printf_u(&m7,
" %" DW_PR_DUu "\n",
line_context->lc_section_offset);
if (line_version <= DW_LINE_VERSION5) {
dwarfstring_append_printf_i(&m7,
" line table version %d\n",
(int) line_context->lc_version_number);
} else {
dwarfstring_append_printf_u(&m7,
" line table version 0x%x\n",
(int) line_context->lc_version_number);
}
if (line_version == DW_LINE_VERSION5) {
dwarfstring_append_printf_i(&m7,
" address size %d\n",
line_context->lc_address_size);
dwarfstring_append_printf_i(&m7,
" segment selector size %d\n",
line_context->lc_segment_selector_size);
}
_dwarf_printf(dbg,dwarfstring_string(&m7));
dwarfstring_reset(&m7);
dwarfstring_append_printf_i(&m7,
" line table length field length %d\n",
line_context->lc_length_field_length);
dwarfstring_append_printf_i(&m7,
" prologue length %d\n",
line_context->lc_prologue_length);
dwarfstring_append_printf_s(&m7,
" compilation_directory %s\n",
comp_dir ? ((char *) comp_dir) : "");
dwarfstring_append_printf_i(&m7,
" min instruction length %d\n",
line_context->lc_minimum_instruction_length);
_dwarf_printf(dbg,dwarfstring_string(&m7));
dwarfstring_reset(&m7);
if (line_version == DW_LINE_VERSION5 ||
line_version == DW_LINE_VERSION4 ||
line_version == EXPERIMENTAL_LINE_TABLES_VERSION) {
dwarfstring_append_printf_u(&m7,
" maximum ops per instruction %u\n",
line_context->lc_maximum_ops_per_instruction);
_dwarf_printf(dbg,dwarfstring_string(&m7));
dwarfstring_reset(&m7);
}
if (line_version == EXPERIMENTAL_LINE_TABLES_VERSION) {
dwarfstring_append_printf_u(&m7, " actuals table offset "
"0x%" DW_PR_XZEROS DW_PR_DUx "\n",
line_context->lc_actuals_table_offset);
dwarfstring_append_printf_u(&m7," logicals table offset "
"0x%" DW_PR_XZEROS DW_PR_DUx "\n",
line_context->lc_logicals_table_offset);
_dwarf_printf(dbg,dwarfstring_string(&m7));
dwarfstring_reset(&m7);
}
dwarfstring_append_printf_i(&m7,
" default is stmt %d\n",
(int)line_context->lc_default_is_stmt);
dwarfstring_append_printf_i(&m7,
" line base %d\n",
(int)line_context->lc_line_base);
dwarfstring_append_printf_i(&m7,
" line_range %d\n",
(int)line_context->lc_line_range);
dwarfstring_append_printf_i(&m7,
" opcode base %d\n",
(int)line_context->lc_opcode_base);
dwarfstring_append_printf_i(&m7,
" standard opcode count %d\n",
(int)line_context->lc_std_op_count);
_dwarf_printf(dbg,dwarfstring_string(&m7));
dwarfstring_reset(&m7);
for (i = 1; i < line_context->lc_opcode_base; i++) {
dwarfstring_append_printf_i(&m7,
" opcode[%2d] length", (int) i);
dwarfstring_append_printf_i(&m7,
" %d\n",
(int) line_context->lc_opcode_length_table[i - 1]);
_dwarf_printf(dbg,dwarfstring_string(&m7));
dwarfstring_reset(&m7);
}
dwarfstring_destructor(&m7);
}
static void
print_experimental_counts(Dwarf_Debug dbg, int line_version,
Dwarf_Line_Context line_context)
{
if (line_version == EXPERIMENTAL_LINE_TABLES_VERSION) {
print_experimental_subprograms_list(dbg,line_context);
}
}
static int
print_actuals_and_locals(Dwarf_Debug dbg,
Dwarf_Line_Context line_context,
Dwarf_Unsigned bogus_bytes_count,
Dwarf_Small *bogus_bytes_ptr,
Dwarf_Small *orig_line_ptr,
Dwarf_Small *line_ptr,
Dwarf_Small *section_start,
Dwarf_Small *line_ptr_actuals,
Dwarf_Small *line_ptr_end,
Dwarf_Half address_size,
int * err_count_out,
Dwarf_Error *error)
{
int res = 0;
dwarfstring m8;
Dwarf_Unsigned offset = 0;
dwarfstring_constructor(&m8);
if (bogus_bytes_count > 0) {
Dwarf_Unsigned wcount = bogus_bytes_count;
Dwarf_Unsigned boffset = bogus_bytes_ptr - section_start;
dwarfstring_append_printf_u(&m8,
"*** DWARF CHECK: the line table prologue header_length "
" is %" DW_PR_DUu " too high, we pretend it is smaller.",
wcount);
dwarfstring_append_printf_u(&m8,
"Section offset: 0x%"
DW_PR_XZEROS DW_PR_DUx,
boffset);
dwarfstring_append_printf_u(&m8,
" (%" DW_PR_DUu ") ***\n",
boffset);
*err_count_out += 1;
}
offset = line_ptr - section_start;
dwarfstring_append_printf_u(&m8,
" statement prog offset in section: 0x%"
DW_PR_XZEROS DW_PR_DUx,
offset);
dwarfstring_append_printf_u(&m8,
" (%" DW_PR_DUu ")\n",
offset);
_dwarf_printf(dbg,dwarfstring_string(&m8));
dwarfstring_reset(&m8);
{
Dwarf_Bool doaddrs = false;
Dwarf_Bool dolines = true;
if (!line_ptr_actuals) {
Dwarf_Bool is_single_table = true;
Dwarf_Bool is_actuals_table = false;
print_line_header(dbg, is_single_table, is_actuals_table);
res = read_line_table_program(dbg,
line_ptr, line_ptr_end, orig_line_ptr,
section_start,
line_context,
address_size, doaddrs, dolines,
is_single_table,
is_actuals_table,
error,
err_count_out);
if (res != DW_DLV_OK) {
dwarfstring_destructor(&m8);
dwarf_srclines_dealloc_b(line_context);
return res;
}
} else {
Dwarf_Bool is_single_table = false;
Dwarf_Bool is_actuals_table = false;
if (line_context->lc_version_number !=
EXPERIMENTAL_LINE_TABLES_VERSION) {
dwarf_srclines_dealloc_b(line_context);
dwarfstring_destructor(&m8);
_dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
return (DW_DLV_ERROR);
}
print_line_header(dbg, is_single_table, is_actuals_table);
res = read_line_table_program(dbg,
line_ptr, line_ptr_actuals, orig_line_ptr,
section_start,
line_context,
address_size, doaddrs, dolines,
is_single_table,
is_actuals_table,
error,err_count_out);
if (res != DW_DLV_OK) {
dwarfstring_destructor(&m8);
dwarf_srclines_dealloc_b(line_context);
return res;
}
if (line_context->lc_actuals_table_offset > 0) {
is_actuals_table = true;
print_line_header(dbg, is_single_table, is_actuals_table);
res = read_line_table_program(dbg,
line_ptr_actuals, line_ptr_end, orig_line_ptr,
section_start,
line_context,
address_size, doaddrs, dolines,
is_single_table,
is_actuals_table,
error,
err_count_out);
if (res != DW_DLV_OK) {
dwarfstring_destructor(&m8);
dwarf_srclines_dealloc_b(line_context);
return res;
}
}
}
}
dwarfstring_destructor(&m8);
dwarf_srclines_dealloc_b(line_context);
return DW_DLV_OK;
}
int
dwarf_print_lines(Dwarf_Die die,
Dwarf_Error * error,
int *error_count)
{
int only_line_header = 0;
int res = _dwarf_internal_printlines(die,
error_count,
only_line_header,error);
return res;
}
int
_dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error)
{
int only_line_header = 0;
int err_count = 0;
int res = _dwarf_internal_printlines(die,
&err_count,
only_line_header,error);
return res;
}
int
dwarf_check_lineheader_b(Dwarf_Die die, int *err_count_out,
Dwarf_Error *err)
{
int res = 0;
int only_line_header = 1;
res = _dwarf_internal_printlines(die,err_count_out,
only_line_header,err);
return res;
}
void
dwarf_check_lineheader(Dwarf_Die die, int *err_count_out)
{
int res = 0;
Dwarf_Error err = 0;
int only_line_header = 1;
res = _dwarf_internal_printlines(die,err_count_out,
only_line_header,&err);
if (res == DW_DLV_ERROR) {
Dwarf_CU_Context c = 0;
Dwarf_Debug dbg = 0;
c = die->di_cu_context;
if (!c) {
return;
}
dbg = c->cc_dbg;
dwarf_dealloc(dbg,err,DW_DLA_ERROR);
err = 0;
}
}