#define TRUE 1
#define FALSE 0
static unsigned char
dwarf_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_TWO_LEVEL] = {
0,
1, 1, 1, 1,
0, 0, 0,
1,
0, 0, 1,
1, 2, 0,
};
static unsigned char
dwarf_arm_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_DWARF3] = {
0,
1, 1, 1, 1,
0, 0, 0,
0,
0, 0, 1
};
static int
operandmismatch(unsigned char * table,unsigned table_length,
unsigned char *linetable,
unsigned check_count,
unsigned * mismatch_entry, unsigned * tabval,unsigned *lineval)
{
unsigned i = 0;
for (i = 0; i<check_count; ++i) {
if (i > table_length) {
*mismatch_entry = i;
*lineval = linetable[i];
*tabval = 0;
return TRUE;
}
if (table[i] == linetable[i]) {
continue;
}
*mismatch_entry = i;
*tabval = table[i];
*lineval = linetable[i];
return TRUE;
}
return FALSE;
}
static int
read_uword_de(Dwarf_Small **lp,
Dwarf_Unsigned *out_p,
Dwarf_Debug dbg,
Dwarf_Error *err,
Dwarf_Small *lpend)
{
Dwarf_Small *inptr = *lp;
Dwarf_Unsigned out = 0;
DECODE_LEB128_UWORD_CK(inptr,
out,
dbg,err,lpend);
*lp = inptr;
*out_p = out;
return DW_DLV_OK;
}
static int
read_sword_de(Dwarf_Small **lp,
Dwarf_Signed *out_p,
Dwarf_Debug dbg,
Dwarf_Error *err,
Dwarf_Small *lpend)
{
Dwarf_Small *inptr = *lp;
Dwarf_Signed out = 0;
DECODE_LEB128_SWORD_CK(inptr,
out,
dbg,err,lpend);
*lp = inptr;
*out_p = out;
return DW_DLV_OK;
}
static int
_dwarf_read_line_table_header(Dwarf_Debug dbg,
Dwarf_CU_Context cu_context,
Dwarf_Small * section_start,
Dwarf_Small * data_start,
Dwarf_Unsigned section_length,
Dwarf_Small ** updated_data_start_out,
Dwarf_Line_Context line_context,
Dwarf_Small ** bogus_bytes_ptr,
Dwarf_Unsigned *bogus_bytes,
Dwarf_Error * err,
int *err_count_out)
{
Dwarf_Small *line_ptr = data_start;
Dwarf_Small *starting_line_ptr = data_start;
Dwarf_Unsigned total_length = 0;
int local_length_size = 0;
int local_extension_size = 0;
Dwarf_Unsigned prologue_length = 0;
Dwarf_Half version = 0;
Dwarf_Small *section_end = section_start + section_length;
Dwarf_Small *line_ptr_end = 0;
Dwarf_Small *lp_begin = 0;
int res = 0;
Dwarf_Unsigned htmp = 0;
if (bogus_bytes_ptr) *bogus_bytes_ptr = 0;
if (bogus_bytes) *bogus_bytes= 0;
line_context->lc_line_ptr_start = starting_line_ptr;
READ_AREA_LENGTH_CK(dbg, total_length, Dwarf_Unsigned,
line_ptr, local_length_size, local_extension_size,
err, section_length,section_end);
line_ptr_end = line_ptr + total_length;
line_context->lc_line_ptr_end = line_ptr_end;
line_context->lc_length_field_length = local_length_size +
local_extension_size;
line_context->lc_section_offset = starting_line_ptr -
dbg->de_debug_line.dss_data;
if (line_ptr_end > section_end) {
_dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
return (DW_DLV_ERROR);
}
line_context->lc_total_length = total_length;
res = _dwarf_read_unaligned_ck_wrapper(dbg,
&htmp,line_ptr,DWARF_HALF_SIZE,line_ptr_end,err);
if (res == DW_DLV_ERROR) {
return res;
}
version = htmp;
line_context->lc_version_number = version;
line_ptr += DWARF_HALF_SIZE;
if (version != DW_LINE_VERSION2 &&
version != DW_LINE_VERSION3 &&
version != DW_LINE_VERSION4 &&
version != DW_LINE_VERSION5 &&
version != EXPERIMENTAL_LINE_TABLES_VERSION) {
_dwarf_error(dbg, err, DW_DLE_VERSION_STAMP_ERROR);
return (DW_DLV_ERROR);
}
if (version == DW_LINE_VERSION5) {
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
return (DW_DLV_ERROR);
}
line_context->lc_address_size = *(unsigned char *) line_ptr;
line_ptr = line_ptr + sizeof(Dwarf_Small);
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
return (DW_DLV_ERROR);
}
line_context->lc_segment_selector_size =
*(unsigned char *) line_ptr;
line_ptr = line_ptr + sizeof(Dwarf_Small);
} else {
line_context->lc_address_size = cu_context->cc_address_size;
line_context->lc_segment_selector_size =
cu_context->cc_segment_selector_size;
}
READ_UNALIGNED_CK(dbg, prologue_length, Dwarf_Unsigned,
line_ptr, local_length_size,
err,line_ptr_end);
line_context->lc_prologue_length = prologue_length;
line_ptr += local_length_size;
line_context->lc_line_prologue_start = line_ptr;
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
return (DW_DLV_ERROR);
}
line_context->lc_minimum_instruction_length =
*(unsigned char *) line_ptr;
line_ptr = line_ptr + sizeof(Dwarf_Small);
if (version == DW_LINE_VERSION4 ||
version == DW_LINE_VERSION5 ||
version == EXPERIMENTAL_LINE_TABLES_VERSION) {
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
return (DW_DLV_ERROR);
}
line_context->lc_maximum_ops_per_instruction =
*(unsigned char *) line_ptr;
line_ptr = line_ptr + sizeof(Dwarf_Small);
}
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
return (DW_DLV_ERROR);
}
line_context->lc_default_is_stmt = *(unsigned char *) line_ptr;
line_ptr = line_ptr + sizeof(Dwarf_Small);
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
return (DW_DLV_ERROR);
}
line_context->lc_line_base = *(signed char *) line_ptr;
line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
if(line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
return DW_DLV_ERROR;
}
line_context->lc_line_range = *(unsigned char *) line_ptr;
if (!line_context->lc_line_range) {
_dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_RANGE_ZERO);
return DW_DLV_ERROR;
}
line_ptr = line_ptr + sizeof(Dwarf_Small);
if(line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
return DW_DLV_ERROR;
}
line_context->lc_opcode_base = *(unsigned char *) line_ptr;
line_ptr = line_ptr + sizeof(Dwarf_Small);
line_context->lc_opcode_length_table = line_ptr;
line_ptr += line_context->lc_opcode_base - 1;
line_context->lc_std_op_count = line_context->lc_opcode_base -1;
if(line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
return DW_DLV_ERROR;
}
{
unsigned check_count = line_context->lc_std_op_count;
unsigned tab_count = sizeof(dwarf_standard_opcode_operand_count);
int operand_ck_fail = true;
if (line_context->lc_std_op_count > tab_count) {
_dwarf_print_header_issue(dbg,
"Too many standard operands in linetable header: ",
data_start,
line_context->lc_std_op_count,
0,0,0,
err_count_out);
check_count = tab_count;
}
{
unsigned entrynum = 0;
unsigned tabv = 0;
unsigned linetabv = 0;
int mismatch = operandmismatch(
dwarf_standard_opcode_operand_count,
tab_count,
line_context->lc_opcode_length_table,
check_count,&entrynum,&tabv,&linetabv);
if (mismatch) {
if (err_count_out) {
_dwarf_print_header_issue(dbg,
"standard-operands did not match, checked",
data_start,
check_count,
entrynum,tabv,linetabv,err_count_out);
}
if (check_count >
sizeof(dwarf_arm_standard_opcode_operand_count)) {
check_count =
sizeof(dwarf_arm_standard_opcode_operand_count);
}
mismatch = operandmismatch(
dwarf_arm_standard_opcode_operand_count,
sizeof(dwarf_arm_standard_opcode_operand_count),
line_context->lc_opcode_length_table,
check_count,&entrynum,&tabv,&linetabv);
if (!mismatch && err_count_out) {
_dwarf_print_header_issue(dbg,
"arm (incorrect) operands in use: ",
data_start,
check_count,
entrynum,tabv,linetabv,err_count_out);
}
}
if (!mismatch) {
if (version == 2) {
if (line_context->lc_std_op_count ==
STANDARD_OPERAND_COUNT_DWARF3) {
_dwarf_print_header_issue(dbg,
"standard DWARF3 operands matched,"
" but is DWARF2 linetable: count",
data_start,
check_count,
0,0,0, err_count_out);
}
}
operand_ck_fail = false;
}
}
if (operand_ck_fail) {
_dwarf_error(dbg, err, DW_DLE_LINE_NUM_OPERANDS_BAD);
return (DW_DLV_ERROR);
}
}
if(line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
return DW_DLV_ERROR;
}
if (version < DW_LINE_VERSION5){
Dwarf_Unsigned directories_count = 0;
Dwarf_Unsigned directories_malloc = 5;
line_context->lc_include_directories =
malloc(sizeof(Dwarf_Small *) * directories_malloc);
if (line_context->lc_include_directories == NULL) {
_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
memset(line_context->lc_include_directories, 0,
sizeof(Dwarf_Small *) * directories_malloc);
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
while ((*(char *) line_ptr) != '\0') {
if (directories_count >= directories_malloc) {
Dwarf_Unsigned expand = 2 * directories_malloc;
Dwarf_Unsigned bytesalloc = sizeof(Dwarf_Small *) * expand;
Dwarf_Small **newdirs =
realloc(line_context->lc_include_directories,
bytesalloc);
if (!newdirs) {
_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
memset(newdirs + directories_malloc, 0,
sizeof(Dwarf_Small *) * directories_malloc);
directories_malloc = expand;
line_context->lc_include_directories = newdirs;
}
line_context->lc_include_directories[directories_count] =
line_ptr;
res = _dwarf_check_string_valid(dbg,
data_start,line_ptr,line_ptr_end,
DW_DLE_LINE_STRING_BAD,err);
if (res != DW_DLV_OK) {
return res;
}
line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
directories_count++;
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
}
line_ptr++;
line_context->lc_include_directories_count = directories_count;
} else if (version == EXPERIMENTAL_LINE_TABLES_VERSION) {
line_ptr++;
} else if (version == DW_LINE_VERSION5) {
} else {
}
if(line_ptr > line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
return DW_DLV_ERROR;
}
if (version < DW_LINE_VERSION5) {
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
while (*(char *) line_ptr != '\0') {
Dwarf_Unsigned utmp;
Dwarf_Unsigned dir_index = 0;
Dwarf_Unsigned lastmod = 0;
Dwarf_Unsigned file_length = 0;
int resl = 0;
Dwarf_File_Entry currfile = 0;
currfile = (Dwarf_File_Entry)
malloc(sizeof(struct Dwarf_File_Entry_s));
if (currfile == NULL) {
_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
memset(currfile,0,sizeof(struct Dwarf_File_Entry_s));
_dwarf_add_to_files_list(line_context,currfile);
currfile->fi_file_name = line_ptr;
resl = _dwarf_check_string_valid(dbg,
data_start,line_ptr,line_ptr_end,
DW_DLE_LINE_STRING_BAD,err);
if (resl != DW_DLV_OK) {
return resl;
}
line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
res = read_uword_de(&line_ptr,&utmp,
dbg,err,line_ptr_end);
if (res == DW_DLV_ERROR) {
return DW_DLV_ERROR;
}
dir_index = (Dwarf_Unsigned) utmp;
if (dir_index >
line_context->lc_include_directories_count) {
_dwarf_error(dbg, err, DW_DLE_DIR_INDEX_BAD);
return (DW_DLV_ERROR);
}
currfile->fi_dir_index = dir_index;
currfile->fi_dir_index_present = TRUE;
res = read_uword_de( &line_ptr,&lastmod,
dbg,err,line_ptr_end);
if (res == DW_DLV_ERROR) {
return DW_DLV_ERROR;
}
currfile->fi_time_last_mod = lastmod;
currfile->fi_time_last_mod_present = TRUE;
DECODE_LEB128_UWORD_CK(line_ptr,file_length,
dbg,err, line_ptr_end);
currfile->fi_file_length = file_length;
currfile->fi_file_length_present = TRUE;
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
}
++line_ptr;
} else if (version == EXPERIMENTAL_LINE_TABLES_VERSION) {
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
if (*line_ptr != 0) {
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
line_ptr++;
} else if (version == 5) {
} else {
}
if(line_ptr > line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
return DW_DLV_ERROR;
}
if (version == EXPERIMENTAL_LINE_TABLES_VERSION) {
static unsigned char expbytes[5] = {0,0xff,0xff,0x7f, 0x7f };
Dwarf_Unsigned logicals_table_offset = 0;
Dwarf_Unsigned actuals_table_offset = 0;
unsigned i = 0;
for ( ; i < 5; ++i) {
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
if (*line_ptr != expbytes[i]) {
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
line_ptr++;
}
READ_UNALIGNED_CK(dbg, logicals_table_offset, Dwarf_Unsigned,
line_ptr, local_length_size,err,line_ptr_end);
line_context->lc_logicals_table_offset = logicals_table_offset;
line_ptr += local_length_size;
READ_UNALIGNED_CK(dbg, actuals_table_offset, Dwarf_Unsigned,
line_ptr, local_length_size,err,line_ptr_end);
line_context->lc_actuals_table_offset = actuals_table_offset;
line_ptr += local_length_size;
if(line_ptr > line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
return DW_DLV_ERROR;
}
}
if (version == DW_LINE_VERSION5 ||
version == EXPERIMENTAL_LINE_TABLES_VERSION) {
Dwarf_Unsigned directory_format_count = 0;
struct Dwarf_Unsigned_Pair_s * format_values = 0;
Dwarf_Unsigned directories_count = 0;
Dwarf_Unsigned i = 0;
Dwarf_Unsigned j = 0;
int dres = 0;
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
directory_format_count = *(unsigned char *) line_ptr;
line_context->lc_directory_entry_format_count =
directory_format_count;
line_ptr = line_ptr + sizeof(Dwarf_Small);
if (directory_format_count > 0) {
format_values = malloc(sizeof(struct Dwarf_Unsigned_Pair_s) *
directory_format_count);
if (format_values == NULL) {
_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
for (i = 0; i < directory_format_count; i++) {
dres=read_uword_de(&line_ptr,
&format_values[i].up_first,
dbg,err,line_ptr_end);
if (dres != DW_DLV_OK) {
free(format_values);
format_values = 0;
return dres;
}
dres=read_uword_de(&line_ptr,
&format_values[i].up_second,
dbg,err,line_ptr_end);
if (dres != DW_DLV_OK) {
free(format_values);
format_values = 0;
return dres;
}
}
}
dres = read_uword_de(&line_ptr,&directories_count,
dbg,err,line_ptr_end);
if (dres != DW_DLV_OK) {
free(format_values);
format_values = 0;
return dres;
}
line_context->lc_include_directories =
malloc(sizeof(Dwarf_Small *) * directories_count);
if (line_context->lc_include_directories == NULL) {
free(format_values);
format_values = 0;
_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
if (directory_format_count == 0 &&
directories_count > 0) {
free(format_values);
format_values = 0;
_dwarf_error_string(dbg, err,
DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH,
"DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH"
": format count is zero yet directories count > 0");
return (DW_DLV_ERROR);
}
memset(line_context->lc_include_directories, 0,
sizeof(Dwarf_Small *) * directories_count);
for(i = 0; i < directories_count; i++) {
for (j = 0; j < directory_format_count; j++) {
switch (format_values[j].up_first) {
case DW_LNCT_path: {
char *inc_dir_ptr = 0;
res = _dwarf_decode_line_string_form(dbg,
format_values[j].up_second,
local_length_size,
&line_ptr,
line_ptr_end,
&inc_dir_ptr,
err);
if (res != DW_DLV_OK) {
free(format_values);
format_values = 0;
return res;
}
line_context->lc_include_directories[i] =
(unsigned char *)inc_dir_ptr;
break;
}
default:
free(format_values);
format_values = 0;
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
}
if (line_ptr > line_ptr_end) {
free(format_values);
format_values = 0;
_dwarf_error(dbg, err,
DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
}
line_context->lc_directory_format_values = format_values;
format_values = 0;
line_context->lc_include_directories_count = directories_count;
}
if (version == DW_LINE_VERSION5 ||
version == EXPERIMENTAL_LINE_TABLES_VERSION) {
struct Dwarf_Unsigned_Pair_s * filename_entry_pairs = 0;
Dwarf_Unsigned filename_format_count = 0;
Dwarf_Unsigned files_count = 0;
Dwarf_Unsigned i = 0;
Dwarf_Unsigned j = 0;
int dres = 0;
if (line_ptr >= line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
filename_format_count = *(unsigned char *) line_ptr;
line_context->lc_file_name_format_count =
filename_format_count;
line_ptr = line_ptr + sizeof(Dwarf_Small);
filename_entry_pairs = malloc(
sizeof(struct Dwarf_Unsigned_Pair_s) *
filename_format_count);
if (!filename_entry_pairs) {
_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
return DW_DLV_ERROR;
}
for (i = 0; i < filename_format_count; i++) {
dres=read_uword_de(&line_ptr,&filename_entry_pairs[i].up_first,
dbg,err,line_ptr_end);
if (dres != DW_DLV_OK) {
free(filename_entry_pairs);
return dres;
}
dres=read_uword_de(&line_ptr,&filename_entry_pairs[i].up_second,
dbg,err,line_ptr_end);
if (dres != DW_DLV_OK) {
free(filename_entry_pairs);
return dres;
}
}
dres=read_uword_de(&line_ptr,&files_count,
dbg,err,line_ptr_end);
if (dres != DW_DLV_OK) {
free(filename_entry_pairs);
return dres;
}
for (i = 0; i < files_count; i++) {
Dwarf_File_Entry curline = 0;
curline = (Dwarf_File_Entry)
malloc(sizeof(struct Dwarf_File_Entry_s));
if (curline == NULL) {
free(filename_entry_pairs);
_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
memset(curline,0,sizeof(*curline));
_dwarf_add_to_files_list(line_context,curline);
for(j = 0; j < filename_format_count; j++) {
Dwarf_Unsigned dirindex = 0;
switch (filename_entry_pairs[j].up_first) {
case DW_LNCT_path:
res = _dwarf_decode_line_string_form(dbg,
filename_entry_pairs[j].up_second,
local_length_size,
&line_ptr,
line_ptr_end,
(char **)&curline->fi_file_name,
err);
if (res != DW_DLV_OK) {
free(filename_entry_pairs);
return res;
}
break;
case DW_LNCT_directory_index:
res = _dwarf_decode_line_udata_form(dbg,
filename_entry_pairs[j].up_second,
&line_ptr,
&dirindex,
line_ptr_end,
err);
if (res != DW_DLV_OK) {
free(filename_entry_pairs);
return res;
}
curline->fi_dir_index = dirindex;
curline->fi_dir_index_present = TRUE;
break;
case DW_LNCT_timestamp:
res = _dwarf_decode_line_udata_form(dbg,
filename_entry_pairs[j].up_second,
&line_ptr,
&curline->fi_time_last_mod,
line_ptr_end,
err);
if (res != DW_DLV_OK) {
free(filename_entry_pairs);
return res;
}
curline->fi_time_last_mod_present = TRUE;
break;
case DW_LNCT_size:
res = _dwarf_decode_line_udata_form(dbg,
filename_entry_pairs[j].up_second,
&line_ptr,
&curline->fi_file_length,
line_ptr_end,
err);
if (res != DW_DLV_OK) {
free(filename_entry_pairs);
return res;
}
curline->fi_file_length_present = TRUE;
break;
case DW_LNCT_MD5: {
if (filename_entry_pairs[j].up_second !=
DW_FORM_data16) {
free(filename_entry_pairs);
_dwarf_error(dbg, err,DW_DLE_LNCT_MD5_WRONG_FORM);
return DW_DLV_ERROR;
}
res = _dwarf_extract_data16(dbg,
line_ptr,
line_ptr,
line_ptr_end,
&curline->fi_md5_value,
err);
if (res != DW_DLV_OK) {
free(filename_entry_pairs);
return res;
}
curline->fi_md5_present = TRUE;
line_ptr = line_ptr + sizeof(curline->fi_md5_value);
}
break;
default:
free(filename_entry_pairs);
_dwarf_error(dbg, err,DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
if (line_ptr > line_ptr_end) {
free(filename_entry_pairs);
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
}
}
line_context->lc_file_format_values = filename_entry_pairs;
filename_entry_pairs = 0;
}
if (version == EXPERIMENTAL_LINE_TABLES_VERSION) {
Dwarf_Unsigned subprog_format_count = 0;
Dwarf_Unsigned *subprog_entry_types = 0;
Dwarf_Unsigned *subprog_entry_forms = 0;
Dwarf_Unsigned subprogs_count = 0;
Dwarf_Unsigned i = 0;
Dwarf_Unsigned j = 0;
int dres = 0;
if (line_ptr > line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
subprog_format_count = *(unsigned char *) line_ptr;
line_ptr = line_ptr + sizeof(Dwarf_Small);
subprog_entry_types = malloc(sizeof(Dwarf_Unsigned) *
subprog_format_count);
if (subprog_entry_types == NULL) {
_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
subprog_entry_forms = malloc(sizeof(Dwarf_Unsigned) *
subprog_format_count);
if (subprog_entry_forms == NULL) {
free(subprog_entry_types);
_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
for (i = 0; i < subprog_format_count; i++) {
dres=read_uword_de(&line_ptr,subprog_entry_types+i,
dbg,err,line_ptr_end);
if (dres != DW_DLV_OK) {
free(subprog_entry_types);
free(subprog_entry_forms);
return dres;
}
dres=read_uword_de(&line_ptr,subprog_entry_forms+i,
dbg,err,line_ptr_end);
if (dres != DW_DLV_OK) {
free(subprog_entry_types);
free(subprog_entry_forms);
return dres;
}
}
dres=read_uword_de(&line_ptr,&subprogs_count,
dbg,err,line_ptr_end);
if (dres != DW_DLV_OK) {
free(subprog_entry_types);
free(subprog_entry_forms);
return dres;
}
line_context->lc_subprogs =
malloc(sizeof(struct Dwarf_Subprog_Entry_s) * subprogs_count);
if (line_context->lc_subprogs == NULL) {
free(subprog_entry_types);
free(subprog_entry_forms);
_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
memset(line_context->lc_subprogs, 0,
sizeof(struct Dwarf_Subprog_Entry_s) * subprogs_count);
for (i = 0; i < subprogs_count; i++) {
struct Dwarf_Subprog_Entry_s *curline =
line_context->lc_subprogs + i;
for (j = 0; j < subprog_format_count; j++) {
switch (subprog_entry_types[j]) {
case DW_LNCT_GNU_subprogram_name:
res = _dwarf_decode_line_string_form(dbg,
subprog_entry_forms[j],
local_length_size,
&line_ptr,
line_ptr_end,
(char **)&curline->ds_subprog_name,
err);
if (res != DW_DLV_OK) {
free(subprog_entry_types);
free(subprog_entry_forms);
return res;
}
break;
case DW_LNCT_GNU_decl_file:
res = _dwarf_decode_line_udata_form(dbg,
subprog_entry_forms[j],
&line_ptr,
&curline->ds_decl_file,
line_ptr_end,
err);
if (res != DW_DLV_OK) {
free(subprog_entry_forms);
free(subprog_entry_types);
return res;
}
break;
case DW_LNCT_GNU_decl_line:
res = _dwarf_decode_line_udata_form(dbg,
subprog_entry_forms[j],
&line_ptr,
&curline->ds_decl_line,
line_ptr_end,
err);
if (res != DW_DLV_OK) {
free(subprog_entry_forms);
free(subprog_entry_types);
return res;
}
break;
default:
free(subprog_entry_forms);
free(subprog_entry_types);
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
if (line_ptr >= line_ptr_end) {
free(subprog_entry_types);
free(subprog_entry_forms);
_dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
return (DW_DLV_ERROR);
}
}
}
free(subprog_entry_types);
free(subprog_entry_forms);
line_context->lc_subprogs_count = subprogs_count;
}
if (version == EXPERIMENTAL_LINE_TABLES_VERSION) {
lp_begin = line_context->lc_line_prologue_start +
line_context->lc_logicals_table_offset;
} else {
lp_begin = line_context->lc_line_prologue_start +
line_context->lc_prologue_length;
}
if(line_ptr > line_ptr_end) {
_dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
return DW_DLV_ERROR;
}
if (line_ptr != lp_begin) {
if (line_ptr > lp_begin) {
_dwarf_error(dbg, err, DW_DLE_LINE_PROLOG_LENGTH_BAD);
return (DW_DLV_ERROR);
} else {
if (bogus_bytes_ptr) {
*bogus_bytes_ptr = line_ptr;
}
if (bogus_bytes) {
*bogus_bytes = (lp_begin - line_ptr);
}
}
lp_begin = line_ptr;
}
line_context->lc_line_ptr_start = lp_begin;
if (line_context->lc_actuals_table_offset) {
line_context->lc_table_count = 2;
} else {
if (line_context->lc_line_ptr_end > lp_begin) {
line_context->lc_table_count = 1;
} else {
line_context->lc_table_count = 0;
}
}
*updated_data_start_out = lp_begin;
return DW_DLV_OK;
}
static int
read_line_table_program(Dwarf_Debug dbg,
Dwarf_Small *line_ptr,
Dwarf_Small *line_ptr_end,
UNUSEDARG Dwarf_Small *orig_line_ptr,
Dwarf_Small *section_start,
Dwarf_Line_Context line_context,
Dwarf_Half address_size,
Dwarf_Bool doaddrs,
Dwarf_Bool dolines,
Dwarf_Bool is_single_table,
Dwarf_Bool is_actuals_table,
Dwarf_Error *error,
UNUSEDARG int *err_count_out)
{
Dwarf_Unsigned i = 0;
Dwarf_File_Entry cur_file_entry = 0;
Dwarf_Line *logicals = line_context->lc_linebuf_logicals;
Dwarf_Unsigned logicals_count = line_context->lc_linecount_logicals;
struct Dwarf_Line_Registers_s regs;
Dwarf_Line curr_line = 0;
Dwarf_Unsigned leb128_num = 0;
Dwarf_Signed advance_line = 0;
Dwarf_Half fixed_advance_pc = 0;
Dwarf_Unsigned line_count = 0;
Dwarf_Unsigned instr_length = 0;
Dwarf_Chain chain_line = NULL;
Dwarf_Chain head_chain = NULL;
Dwarf_Chain curr_chain = NULL;
Dwarf_Line *block_line = 0;
Dwarf_Bool is_addr_set = false;
_dwarf_set_line_table_regs_default_values(®s,
line_context->lc_version_number,
line_context->lc_default_is_stmt);
while (line_ptr < line_ptr_end) {
int type = 0;
Dwarf_Small opcode = 0;
#ifdef PRINTING_DETAILS
{
dwarfstring m9a;
dwarfstring_constructor(&m9a);
dwarfstring_append_printf_u(&m9a,
" [0x%06" DW_PR_DSx "] ",
(line_ptr - section_start));
_dwarf_printf(dbg,dwarfstring_string(&m9a));
dwarfstring_destructor(&m9a);
}
#endif
opcode = *(Dwarf_Small *) line_ptr;
line_ptr++;
WHAT_IS_OPCODE(type, opcode, line_context->lc_opcode_base,
line_context->lc_opcode_length_table, line_ptr,
line_context->lc_std_op_count);
if (type == LOP_DISCARD) {
int oc = 0;
int opcnt = line_context->lc_opcode_length_table[opcode];
#ifdef PRINTING_DETAILS
{
dwarfstring m9b;
dwarfstring_constructor(&m9b);
dwarfstring_append_printf_i(&m9b,
"*** DWARF CHECK: DISCARD standard opcode %d ",
opcode);
dwarfstring_append_printf_i(&m9b,
"with %d operands: not understood.", opcnt);
_dwarf_printf(dbg,dwarfstring_string(&m9b));
*err_count_out += 1;
dwarfstring_destructor(&m9b);
}
#endif
for (oc = 0; oc < opcnt; oc++) {
int ocres = 0;
UNUSEDARG Dwarf_Unsigned utmp2 = 0;
ocres = read_uword_de( &line_ptr,&utmp2,
dbg,error,line_ptr_end);
if (ocres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
curr_line = 0;
}
return DW_DLV_ERROR;
}
#ifdef PRINTING_DETAILS
{
dwarfstring m9e;
dwarfstring_constructor(&m9e);
dwarfstring_append_printf_u(&m9e,
" %" DW_PR_DUu,
utmp2);
dwarfstring_append_printf_u(&m9e,
" (0x%" DW_PR_XZEROS DW_PR_DUx ")",
utmp2);
_dwarf_printf(dbg,dwarfstring_string(&m9e));
dwarfstring_destructor(&m9e);
}
#endif
}
#ifdef PRINTING_DETAILS
_dwarf_printf(dbg,"***\n");
#endif
} else if (type == LOP_SPECIAL) {
#ifdef PRINTING_DETAILS
unsigned origop = opcode;
#endif
Dwarf_Unsigned operation_advance = 0;
opcode = opcode - line_context->lc_opcode_base;
operation_advance = (opcode / line_context->lc_line_range);
if (line_context->lc_maximum_ops_per_instruction < 2) {
regs.lr_address = regs.lr_address + (operation_advance *
line_context->lc_minimum_instruction_length);
} else {
regs.lr_address = regs.lr_address +
(line_context->lc_minimum_instruction_length *
((regs.lr_op_index + operation_advance)/
line_context->lc_maximum_ops_per_instruction));
regs.lr_op_index = (regs.lr_op_index +operation_advance)%
line_context->lc_maximum_ops_per_instruction;
}
regs.lr_line = regs.lr_line + line_context->lc_line_base +
opcode % line_context->lc_line_range;
if ((Dwarf_Signed)regs.lr_line < 0) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_i(&m,
"\nERROR: DW_DLE_LINE_TABLE_LINENO_ERROR "
"The line number computes as %d "
"and negative line numbers "
"are not correct.",(Dwarf_Signed)regs.lr_line);
_dwarf_error_string(dbg, error,
DW_DLE_LINE_TABLE_LINENO_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
regs.lr_line = 0;
return DW_DLV_ERROR;
}
#ifdef PRINTING_DETAILS
{
dwarfstring ma;
dwarfstring mb;
dwarfstring_constructor(&ma);
dwarfstring_constructor(&mb);
dwarfstring_append_printf_u(&mb,"Specialop %3u", origop);
_dwarf_printf(dbg,dwarfstring_string(&ma));
dwarfstring_destructor(&ma);
print_line_detail(dbg,dwarfstring_string(&mb),
opcode,line_count+1, ®s,is_single_table, is_actuals_table);
dwarfstring_destructor(&mb);
dwarfstring_destructor(&ma);
}
#endif
if (dolines) {
curr_line =
(Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
if (curr_line == NULL) {
_dwarf_free_chain_entries(dbg,head_chain,line_count);
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
curr_line->li_addr_line.li_l_data.li_is_addr_set =
is_addr_set;
is_addr_set = false;
curr_line->li_address = regs.lr_address;
curr_line->li_addr_line.li_l_data.li_file =
(Dwarf_Signed) regs.lr_file;
curr_line->li_addr_line.li_l_data.li_line =
(Dwarf_Signed) regs.lr_line;
curr_line->li_addr_line.li_l_data.li_column =
(Dwarf_Half) regs.lr_column;
curr_line->li_addr_line.li_l_data.li_is_stmt =
regs.lr_is_stmt;
curr_line->li_addr_line.li_l_data.li_basic_block =
regs.lr_basic_block;
curr_line->li_addr_line.li_l_data.li_end_sequence =
curr_line->li_addr_line.li_l_data.
li_epilogue_begin = regs.lr_epilogue_begin;
curr_line->li_addr_line.li_l_data.li_prologue_end =
regs.lr_prologue_end;
curr_line->li_addr_line.li_l_data.li_isa = regs.lr_isa;
curr_line->li_addr_line.li_l_data.li_discriminator =
regs.lr_discriminator;
curr_line->li_addr_line.li_l_data.li_call_context =
regs.lr_call_context;
curr_line->li_addr_line.li_l_data.li_subprogram =
regs.lr_subprogram;
curr_line->li_context = line_context;
curr_line->li_is_actuals_table = is_actuals_table;
line_count++;
chain_line = (Dwarf_Chain)
_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
if (chain_line == NULL) {
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
_dwarf_free_chain_entries(dbg,head_chain,line_count);
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
chain_line->ch_itemtype = DW_DLA_LINE;
chain_line->ch_item = curr_line;
_dwarf_update_chain_list(chain_line,&head_chain,&curr_chain);
curr_line = 0;
}
regs.lr_basic_block = false;
regs.lr_prologue_end = false;
regs.lr_epilogue_begin = false;
regs.lr_discriminator = 0;
#ifdef PRINTING_DETAILS
#endif
} else if (type == LOP_STANDARD) {
#ifdef PRINTING_DETAILS
dwarfstring mb;
#endif
switch (opcode) {
case DW_LNS_copy:{
#ifdef PRINTING_DETAILS
print_line_detail(dbg,"DW_LNS_copy",
opcode,line_count+1, ®s,is_single_table, is_actuals_table);
#endif
if (dolines) {
curr_line = (Dwarf_Line) _dwarf_get_alloc(dbg,
DW_DLA_LINE, 1);
if (curr_line == NULL) {
_dwarf_free_chain_entries(dbg,head_chain,line_count);
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
curr_line->li_addr_line.li_l_data.li_is_addr_set =
is_addr_set;
is_addr_set = false;
curr_line->li_address = regs.lr_address;
curr_line->li_addr_line.li_l_data.li_file =
(Dwarf_Signed) regs.lr_file;
curr_line->li_addr_line.li_l_data.li_line =
(Dwarf_Signed) regs.lr_line;
curr_line->li_addr_line.li_l_data.li_column =
(Dwarf_Half) regs.lr_column;
curr_line->li_addr_line.li_l_data.li_is_stmt =
regs.lr_is_stmt;
curr_line->li_addr_line.li_l_data.
li_basic_block = regs.lr_basic_block;
curr_line->li_addr_line.li_l_data.
li_end_sequence = regs.lr_end_sequence;
curr_line->li_context = line_context;
curr_line->li_is_actuals_table = is_actuals_table;
curr_line->li_addr_line.li_l_data.
li_epilogue_begin = regs.lr_epilogue_begin;
curr_line->li_addr_line.li_l_data.
li_prologue_end = regs.lr_prologue_end;
curr_line->li_addr_line.li_l_data.li_isa = regs.lr_isa;
curr_line->li_addr_line.li_l_data.li_discriminator =
regs.lr_discriminator;
curr_line->li_addr_line.li_l_data.li_call_context =
regs.lr_call_context;
curr_line->li_addr_line.li_l_data.li_subprogram =
regs.lr_subprogram;
line_count++;
chain_line = (Dwarf_Chain)
_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
if (chain_line == NULL) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
chain_line->ch_itemtype = DW_DLA_LINE;
chain_line->ch_item = curr_line;
_dwarf_update_chain_list(chain_line,&head_chain,
&curr_chain);
curr_line = 0;
}
regs.lr_basic_block = false;
regs.lr_prologue_end = false;
regs.lr_epilogue_begin = false;
regs.lr_discriminator = 0;
}
break;
case DW_LNS_advance_pc:{
Dwarf_Unsigned utmp2 = 0;
int advres = 0;
advres = read_uword_de( &line_ptr,&utmp2,
dbg,error,line_ptr_end);
if (advres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
#ifdef PRINTING_DETAILS
dwarfstring_constructor(&mb);
dwarfstring_append_printf_i(&mb,
"DW_LNS_advance_pc val %" DW_PR_DSd,
utmp2);
dwarfstring_append_printf_u(&mb,
" 0x%" DW_PR_XZEROS DW_PR_DUx "\n",
utmp2);
_dwarf_printf(dbg,dwarfstring_string(&mb));
dwarfstring_destructor(&mb);
#endif
leb128_num = utmp2;
regs.lr_address = regs.lr_address +
line_context->lc_minimum_instruction_length *
leb128_num;
}
break;
case DW_LNS_advance_line:{
Dwarf_Signed stmp = 0;
int alres = 0;
alres = read_sword_de( &line_ptr,&stmp,
dbg,error,line_ptr_end);
if (alres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
advance_line = (Dwarf_Signed) stmp;
#ifdef PRINTING_DETAILS
dwarfstring_constructor(&mb);
dwarfstring_append_printf_i(&mb,
"DW_LNS_advance_line val %" DW_PR_DSd,
advance_line);
dwarfstring_append_printf_u(&mb,
" 0x%" DW_PR_XZEROS DW_PR_DSx "\n",
advance_line);
_dwarf_printf(dbg,dwarfstring_string(&mb));
dwarfstring_destructor(&mb);
#endif
regs.lr_line = regs.lr_line + advance_line;
if ((Dwarf_Signed)regs.lr_line < 0) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_i(&m,
"\nERROR: DW_DLE_LINE_TABLE_LINENO_ERROR"
" The line number is %d "
"and negative line numbers after "
"DW_LNS_ADVANCE_LINE ",
(Dwarf_Signed)regs.lr_line);
dwarfstring_append_printf_i(&m,
" of %d "
"are not correct.",stmp);
_dwarf_error_string(dbg, error,
DW_DLE_LINE_TABLE_LINENO_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
regs.lr_line = 0;
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
_dwarf_free_chain_entries(dbg,head_chain,line_count);
return DW_DLV_ERROR;
}
}
break;
case DW_LNS_set_file:{
Dwarf_Unsigned utmp2 = 0;
int sfres = 0;
sfres = read_uword_de( &line_ptr,&utmp2,
dbg,error,line_ptr_end);
if (sfres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
regs.lr_file = utmp2;
#ifdef PRINTING_DETAILS
dwarfstring_constructor(&mb);
dwarfstring_append_printf_i(&mb,
"DW_LNS_set_file %ld\n",
regs.lr_file);
_dwarf_printf(dbg,dwarfstring_string(&mb));
dwarfstring_destructor(&mb);
#endif
}
break;
case DW_LNS_set_column:{
Dwarf_Unsigned utmp2 = 0;
int scres = 0;
scres = read_uword_de( &line_ptr,&utmp2,
dbg,error,line_ptr_end);
if (scres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
regs.lr_column = utmp2;
#ifdef PRINTING_DETAILS
dwarfstring_constructor(&mb);
dwarfstring_append_printf_i(&mb,
"DW_LNS_set_column val %" DW_PR_DSd ,
regs.lr_column);
dwarfstring_append_printf_u(&mb,
" 0x%" DW_PR_XZEROS DW_PR_DSx "\n",
regs.lr_column);
_dwarf_printf(dbg,dwarfstring_string(&mb));
dwarfstring_destructor(&mb);
#endif
}
break;
case DW_LNS_negate_stmt:{
regs.lr_is_stmt = !regs.lr_is_stmt;
#ifdef PRINTING_DETAILS
_dwarf_printf(dbg, "DW_LNS_negate_stmt\n");
#endif
}
break;
case DW_LNS_set_basic_block:{
regs.lr_basic_block = true;
#ifdef PRINTING_DETAILS
_dwarf_printf(dbg,
"DW_LNS_set_basic_block\n");
#endif
}
break;
case DW_LNS_const_add_pc:{
opcode = MAX_LINE_OP_CODE -
line_context->lc_opcode_base;
if (line_context->lc_maximum_ops_per_instruction < 2) {
Dwarf_Unsigned operation_advance =
(opcode / line_context->lc_line_range);
regs.lr_address = regs.lr_address +
line_context->lc_minimum_instruction_length *
operation_advance;
} else {
Dwarf_Unsigned operation_advance =
(opcode / line_context->lc_line_range);
regs.lr_address = regs.lr_address +
line_context->lc_minimum_instruction_length *
((regs.lr_op_index + operation_advance)/
line_context->lc_maximum_ops_per_instruction);
regs.lr_op_index = (regs.lr_op_index +operation_advance)%
line_context->lc_maximum_ops_per_instruction;
}
#ifdef PRINTING_DETAILS
dwarfstring_constructor(&mb);
dwarfstring_append_printf_u(&mb,
"DW_LNS_const_add_pc new address 0x%"
DW_PR_XZEROS DW_PR_DSx "\n",
regs.lr_address);
_dwarf_printf(dbg,dwarfstring_string(&mb));
dwarfstring_destructor(&mb);
#endif
}
break;
case DW_LNS_fixed_advance_pc:{
Dwarf_Unsigned fpc = 0;
int apres = 0;
apres = _dwarf_read_unaligned_ck_wrapper(dbg,
&fpc,line_ptr,DWARF_HALF_SIZE,line_ptr_end,
error);
fixed_advance_pc = fpc;
if (apres == DW_DLV_ERROR) {
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
return apres;
}
line_ptr += DWARF_HALF_SIZE;
if (line_ptr > line_ptr_end) {
dwarfstring g;
ptrdiff_t d = 0;
d = line_ptr - section_start;
dwarfstring_constructor(&g);
dwarfstring_append_printf_u(&g,
"DW_DLE_LINE_TABLE_BAD reading "
"DW_LNS_fixed_advance_pc we are "
"off this line table at section "
"offset. 0x%x .",
d);
_dwarf_error_string(dbg, error,
DW_DLE_LINE_TABLE_BAD,
dwarfstring_string(&g));
dwarfstring_destructor(&g);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
_dwarf_free_chain_entries(dbg,head_chain,line_count);
return DW_DLV_ERROR;
}
regs.lr_address = regs.lr_address + fixed_advance_pc;
regs.lr_op_index = 0;
#ifdef PRINTING_DETAILS
dwarfstring_constructor(&mb);
dwarfstring_append_printf_i(&mb,
"DW_LNS_fixed_advance_pc val %"
DW_PR_DSd, fixed_advance_pc);
dwarfstring_append_printf_u(&mb,
" 0x%" DW_PR_XZEROS DW_PR_DSx,
fixed_advance_pc);
dwarfstring_append_printf_u(&mb,
" new address 0x%"
DW_PR_XZEROS DW_PR_DSx "\n",
regs.lr_address);
_dwarf_printf(dbg,
dwarfstring_string(&mb));
dwarfstring_destructor(&mb);
#endif
}
break;
case DW_LNS_set_prologue_end:{
regs.lr_prologue_end = true;
}
break;
case DW_LNS_set_epilogue_begin:{
regs.lr_epilogue_begin = true;
#ifdef PRINTING_DETAILS
_dwarf_printf(dbg,
"DW_LNS_set_prologue_end set true.\n");
#endif
}
break;
case DW_LNS_set_isa:{
Dwarf_Unsigned utmp2 = 0;
int sires = 0;
sires = read_uword_de( &line_ptr,&utmp2,
dbg,error,line_ptr_end);
if (sires == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
regs.lr_isa = utmp2;
#ifdef PRINTING_DETAILS
dwarfstring_constructor(&mb);
dwarfstring_append_printf_u(&mb,
"DW_LNS_set_isa new value 0x%"
DW_PR_XZEROS DW_PR_DUx ".\n",
utmp2);
_dwarf_printf(dbg,dwarfstring_string(&mb));
dwarfstring_destructor(&mb);
#endif
if (regs.lr_isa != utmp2) {
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
_dwarf_free_chain_entries(dbg,head_chain,line_count);
_dwarf_error(dbg, error,
DW_DLE_LINE_NUM_OPERANDS_BAD);
return (DW_DLV_ERROR);
}
}
break;
case DW_LNS_set_subprogram:
if (is_actuals_table) {
Dwarf_Signed stmp = 0;
int atres = 0;
atres = read_sword_de( &line_ptr,&stmp,
dbg,error,line_ptr_end);
if (atres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
advance_line = (Dwarf_Signed) stmp;
regs.lr_line = regs.lr_line + advance_line;
if ((Dwarf_Signed)regs.lr_line < 0) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_i(&m,
"\nERROR: DW_DLE_LINE_TABLE_LINENO_ERROR"
" The line number is %d "
"and negative line numbers after "
"DW_LNS_set_subprogram ",
(Dwarf_Signed)regs.lr_line);
dwarfstring_append_printf_i(&m,
" of %d applied "
"are not correct.",stmp);
_dwarf_error_string(dbg, error,
DW_DLE_LINE_TABLE_LINENO_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
regs.lr_line = 0;
_dwarf_free_chain_entries(dbg,head_chain,line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
if (regs.lr_line >= 1 &&
regs.lr_line - 1 < logicals_count) {
regs.lr_address =
logicals[regs.lr_line - 1]->li_address;
regs.lr_op_index = 0;
#ifdef PRINTING_DETAILS
dwarfstring_constructor(&mb);
dwarfstring_append_printf_i(&mb,
"DW_LNS_set_address_from"
"_logical "
"%" DW_PR_DSd,
stmp);
dwarfstring_append_printf_u(&mb,
" 0x%" DW_PR_XZEROS DW_PR_DSx,
stmp);
dwarfstring_append_printf_u(&mb,
" newaddr="
" 0x%" DW_PR_XZEROS DW_PR_DUx ".\n",
regs.lr_address);
_dwarf_printf(dbg,
dwarfstring_string(&mb));
dwarfstring_destructor(&mb);
#endif
} else {
#ifdef PRINTING_DETAILS
dwarfstring_constructor(&mb);
dwarfstring_append_printf_i(&mb,
"DW_LNS_set_address_from_logical line"
" is %" DW_PR_DSd ,
regs.lr_line);
dwarfstring_append_printf_u(&mb,
" 0x%" DW_PR_XZEROS DW_PR_DSx ".\n",
regs.lr_line);
_dwarf_printf(dbg,
dwarfstring_string(&mb));
dwarfstring_destructor(&mb);
#endif
}
} else {
Dwarf_Unsigned utmp2 = 0;
int spres = 0;
regs.lr_call_context = 0;
spres = read_uword_de( &line_ptr,&utmp2,
dbg,error,line_ptr_end);
if (spres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
regs.lr_subprogram = utmp2;
#ifdef PRINTING_DETAILS
dwarfstring_constructor(&mb);
dwarfstring_append_printf_i(&mb,
"DW_LNS_set_subprogram "
"%" DW_PR_DSd,
utmp2);
dwarfstring_append_printf_u(&mb,
" 0x%" DW_PR_XZEROS DW_PR_DSx "\n",
utmp2);
_dwarf_printf(dbg,
dwarfstring_string(&mb));
#endif
}
break;
case DW_LNS_inlined_call: {
Dwarf_Signed stmp = 0;
Dwarf_Unsigned ilcuw = 0;
int icres = 0;
icres = read_sword_de( &line_ptr,&stmp,
dbg,error,line_ptr_end);
if (icres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
regs.lr_call_context = line_count + stmp;
icres = read_uword_de(&line_ptr,&ilcuw,
dbg,error,line_ptr_end);
regs.lr_subprogram = ilcuw;
if (icres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
#ifdef PRINTING_DETAILS
dwarfstring_constructor(&mb);
dwarfstring_append_printf_i(&mb,
"DW_LNS_inlined_call "
"%" DW_PR_DSd ,stmp);
dwarfstring_append_printf_u(&mb,
" (0x%" DW_PR_XZEROS DW_PR_DSx "),",
stmp);
dwarfstring_append_printf_i(&mb,
"%" DW_PR_DSd,
regs.lr_subprogram);
dwarfstring_append_printf_u(&mb,
" (0x%" DW_PR_XZEROS DW_PR_DSx ")",
regs.lr_subprogram);
dwarfstring_append_printf_i(&mb,
" callcontext=" "%" DW_PR_DSd ,
regs.lr_call_context);
dwarfstring_append_printf_u(&mb,
" (0x%" DW_PR_XZEROS DW_PR_DSx ")\n",
regs.lr_call_context);
_dwarf_printf(dbg,
dwarfstring_string(&mb));
dwarfstring_destructor(&mb);
#endif
}
break;
case DW_LNS_pop_context: {
Dwarf_Unsigned logical_num = regs.lr_call_context;
Dwarf_Chain logical_chain = head_chain;
Dwarf_Line logical_line = 0;
if (logical_num > 0 && logical_num <= line_count) {
for (i = 1; i < logical_num; i++) {
logical_chain = logical_chain->ch_next;
}
logical_line = (Dwarf_Line) logical_chain->ch_item;
regs.lr_file =
logical_line->li_addr_line.li_l_data.li_file;
regs.lr_line =
logical_line->li_addr_line.li_l_data.li_line;
regs.lr_column =
logical_line->li_addr_line.li_l_data.li_column;
regs.lr_discriminator =
logical_line->li_addr_line.li_l_data.li_discriminator;
regs.lr_is_stmt =
logical_line->li_addr_line.li_l_data.li_is_stmt;
regs.lr_call_context =
logical_line->li_addr_line.li_l_data.li_call_context;
regs.lr_subprogram =
logical_line->li_addr_line.li_l_data.li_subprogram;
#ifdef PRINTING_DETAILS
{
dwarfstring pcon;
dwarfstring_constructor(&pcon);
dwarfstring_append_printf_u(&pcon,
"DW_LNS_pop_context set"
" from logical "
"%" DW_PR_DUu ,logical_num);
dwarfstring_append_printf_u(&pcon,
" (0x%" DW_PR_XZEROS DW_PR_DUx ")\n",
logical_num);
_dwarf_printf(dbg,
dwarfstring_string(&pcon));
dwarfstring_destructor(&pcon);
}
} else {
dwarfstring pcon;
dwarfstring_constructor(&pcon);
dwarfstring_append_printf_u(&pcon,
"DW_LNS_pop_context does nothing, logical"
"%" DW_PR_DUu ,
logical_num);
dwarfstring_append_printf_u(&pcon,
" (0x%" DW_PR_XZEROS DW_PR_DUx ")\n",
logical_num);
_dwarf_printf(dbg,
dwarfstring_string(&pcon));
dwarfstring_destructor(&pcon);
#endif
}
}
break;
}
} else if (type == LOP_EXTENDED) {
Dwarf_Unsigned utmp3 = 0;
Dwarf_Small ext_opcode = 0;
int leres = 0;
leres = read_uword_de( &line_ptr,&utmp3,
dbg,error,line_ptr_end);
if (leres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
instr_length = utmp3;
if (line_ptr >= line_ptr_end) {
dwarfstring g;
ptrdiff_t d = 0;
d = line_ptr - section_start;
dwarfstring_constructor(&g);
dwarfstring_append_printf_u(&g,
"DW_DLE_LINE_TABLE_BAD reading "
"extended op we are "
"off this line table at section "
"offset 0x%x .",
d);
_dwarf_error_string(dbg, error,
DW_DLE_LINE_TABLE_BAD,
dwarfstring_string(&g));
dwarfstring_destructor(&g);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
_dwarf_free_chain_entries(dbg,head_chain,line_count);
return DW_DLV_ERROR;
}
ext_opcode = *(Dwarf_Small *) line_ptr;
line_ptr++;
if (line_ptr > line_ptr_end) {
dwarfstring g;
ptrdiff_t d = 0;
d = line_ptr - section_start;
dwarfstring_constructor(&g);
dwarfstring_append_printf_u(&g,
"DW_DLE_LINE_TABLE_BAD reading "
"extended op opcode we are "
"off this line table at section "
"offset 0x%x .",
d);
_dwarf_error_string(dbg, error,
DW_DLE_LINE_TABLE_BAD,
dwarfstring_string(&g));
dwarfstring_destructor(&g);
_dwarf_free_chain_entries(dbg,head_chain,line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
switch (ext_opcode) {
case DW_LNE_end_sequence:{
regs.lr_end_sequence = true;
if (dolines) {
curr_line = (Dwarf_Line)
_dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
if (!curr_line) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
#ifdef PRINTING_DETAILS
print_line_detail(dbg,
"DW_LNE_end_sequence extended",
ext_opcode, line_count+1,®s,
is_single_table, is_actuals_table);
#endif
curr_line->li_address = regs.lr_address;
curr_line->li_addr_line.li_l_data.li_file =
(Dwarf_Signed) regs.lr_file;
curr_line->li_addr_line.li_l_data.li_line =
(Dwarf_Signed) regs.lr_line;
curr_line->li_addr_line.li_l_data.li_column =
(Dwarf_Half) regs.lr_column;
curr_line->li_addr_line.li_l_data.li_is_stmt =
regs.lr_is_stmt;
curr_line->li_addr_line.li_l_data.
li_basic_block = regs.lr_basic_block;
curr_line->li_addr_line.li_l_data.
li_end_sequence = regs.lr_end_sequence;
curr_line->li_context = line_context;
curr_line->li_is_actuals_table = is_actuals_table;
curr_line->li_addr_line.li_l_data.
li_epilogue_begin = regs.lr_epilogue_begin;
curr_line->li_addr_line.li_l_data.
li_prologue_end = regs.lr_prologue_end;
curr_line->li_addr_line.li_l_data.li_isa = regs.lr_isa;
curr_line->li_addr_line.li_l_data.li_discriminator =
regs.lr_discriminator;
curr_line->li_addr_line.li_l_data.li_call_context =
regs.lr_call_context;
curr_line->li_addr_line.li_l_data.li_subprogram =
regs.lr_subprogram;
line_count++;
chain_line = (Dwarf_Chain)
_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
if (chain_line == NULL) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
_dwarf_free_chain_entries(dbg,head_chain,line_count);
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
chain_line->ch_itemtype = DW_DLA_LINE;
chain_line->ch_item = curr_line;
_dwarf_update_chain_list(chain_line,
&head_chain,&curr_chain);
curr_line = 0;
}
_dwarf_set_line_table_regs_default_values(®s,
line_context->lc_version_number,
line_context->lc_default_is_stmt);
}
break;
case DW_LNE_set_address:{
int sares = 0;
sares = _dwarf_read_unaligned_ck_wrapper(dbg,
®s.lr_address,line_ptr,
address_size,line_ptr_end,
error);
if (sares == DW_DLV_ERROR) {
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
return sares;
}
is_addr_set = true;
#ifdef PRINTING_DETAILS
{
dwarfstring sadd;
dwarfstring_constructor(&sadd);
dwarfstring_append_printf_u(&sadd,
"DW_LNE_set_address address 0x%"
DW_PR_XZEROS DW_PR_DUx "\n",
regs.lr_address);
_dwarf_printf(dbg,dwarfstring_string(&sadd));
dwarfstring_destructor(&sadd);
}
#endif
if (doaddrs) {
curr_line = (Dwarf_Line) _dwarf_get_alloc(dbg,
DW_DLA_LINE, 1);
if (!curr_line) {
_dwarf_free_chain_entries(dbg,head_chain,line_count);
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
curr_line->li_addr_line.li_l_data.li_is_addr_set =
is_addr_set;
is_addr_set = false;
curr_line->li_address = regs.lr_address;
#ifdef __sgi
curr_line->li_addr_line.li_offset =
line_ptr - dbg->de_debug_line.dss_data;
#endif
line_count++;
chain_line = (Dwarf_Chain)
_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
if (chain_line == NULL) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
_dwarf_free_chain_entries(dbg,head_chain,line_count);
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
chain_line->ch_itemtype = DW_DLA_LINE;
chain_line->ch_item = curr_line;
_dwarf_update_chain_list(chain_line,&head_chain,&curr_chain);
curr_line = 0;
}
regs.lr_op_index = 0;
line_ptr += address_size;
if (line_ptr > line_ptr_end) {
dwarfstring g;
ptrdiff_t d = 0;
d = line_ptr - section_start;
dwarfstring_constructor(&g);
dwarfstring_append_printf_u(&g,
"DW_DLE_LINE_TABLE_BAD reading "
"DW_LNE_set_address we are "
"off this line table at section "
"offset 0x%x .",
d);
_dwarf_error_string(dbg, error,
DW_DLE_LINE_TABLE_BAD,
dwarfstring_string(&g));
dwarfstring_destructor(&g);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
_dwarf_free_chain_entries(dbg,head_chain,line_count);
return DW_DLV_ERROR;
}
}
break;
case DW_LNE_define_file:
if (dolines) {
int dlres = 0;
Dwarf_Unsigned value = 0;
cur_file_entry = (Dwarf_File_Entry)
malloc(sizeof(struct Dwarf_File_Entry_s));
if (cur_file_entry == NULL) {
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
_dwarf_free_chain_entries(dbg,head_chain,line_count);
return DW_DLV_ERROR;
}
memset(cur_file_entry,0,
sizeof(struct Dwarf_File_Entry_s));
_dwarf_add_to_files_list(line_context,
cur_file_entry);
cur_file_entry->fi_file_name =
(Dwarf_Small *) line_ptr;
dlres = _dwarf_check_string_valid(dbg,
line_ptr,line_ptr,line_ptr_end,
DW_DLE_DEFINE_FILE_STRING_BAD,error);
if (dlres != DW_DLV_OK) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return dlres;
}
line_ptr = line_ptr + strlen((char *) line_ptr)
+ 1;
dlres = read_uword_de( &line_ptr,&value,
dbg,error,line_ptr_end);
if (dlres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
cur_file_entry->fi_dir_index = (Dwarf_Signed)value;
cur_file_entry->fi_dir_index_present = TRUE;
dlres = read_uword_de( &line_ptr,&value,
dbg,error,line_ptr_end);
if (dlres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
cur_file_entry->fi_time_last_mod = value;
dlres = read_uword_de( &line_ptr,&value,
dbg,error,line_ptr_end);
if (dlres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
return DW_DLV_ERROR;
}
cur_file_entry->fi_file_length = value;
cur_file_entry->fi_dir_index_present = TRUE;
cur_file_entry->fi_time_last_mod_present = TRUE;
cur_file_entry->fi_file_length_present = TRUE;
#ifdef PRINTING_DETAILS
{
dwarfstring m9c;
dwarfstring_constructor(&m9c);
dwarfstring_append_printf_s(&m9c,
"DW_LNE_define_file %s \n",
(char *)cur_file_entry->fi_file_name);
dwarfstring_append_printf_i(&m9c,
" dir index %d\n",
(int) cur_file_entry->fi_dir_index);
{
time_t tt3 = (time_t) cur_file_entry->
fi_time_last_mod;
dwarfstring_append_printf_u(&m9c,
" last time 0x%x ",
(Dwarf_Unsigned)tt3);
dwarfstring_append_printf_s(&m9c,
"%s",
ctime(&tt3));
}
dwarfstring_append_printf_i(&m9c,
" file length %ld ",
cur_file_entry->fi_file_length);
dwarfstring_append_printf_u(&m9c,
"0x%lx\n",
cur_file_entry->fi_file_length);
_dwarf_printf(dbg,dwarfstring_string(&m9c));
dwarfstring_destructor(&m9c);
}
#endif
}
break;
case DW_LNE_set_discriminator:{
int sdres = 0;
Dwarf_Unsigned utmp2 = 0;
sdres = read_uword_de( &line_ptr,&utmp2,
dbg,error,line_ptr_end);
if (sdres == DW_DLV_ERROR) {
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
return DW_DLV_ERROR;
}
regs.lr_discriminator = utmp2;
#ifdef PRINTING_DETAILS
{
dwarfstring mk;
dwarfstring_constructor(&mk);
dwarfstring_append_printf_u(&mk,
"DW_LNE_set_discriminator 0x%"
DW_PR_XZEROS DW_PR_DUx "\n",
utmp2);
_dwarf_printf(dbg,dwarfstring_string(&mk));
dwarfstring_destructor(&mk);
}
#endif
}
break;
default:{
Dwarf_Unsigned remaining_bytes = instr_length -1;
if (instr_length < 1 ||
remaining_bytes > DW_LNE_LEN_MAX) {
dwarfstring g;
ptrdiff_t d = 0;
_dwarf_free_chain_entries(dbg,head_chain,
line_count);
d = line_ptr - section_start;
dwarfstring_constructor(&g);
dwarfstring_append_printf_u(&g,
"DW_DLE_LINE_TABLE_BAD reading "
"unknown DW_LNE_extended op opcode 0x%x ",
ext_opcode);
dwarfstring_append_printf_u(&g,
"we are "
"off this line table at section "
"offset 0x%x and ",
d);
dwarfstring_append_printf_u(&g,"instruction length"
"%u.",instr_length);
_dwarf_error_string(dbg, error,
DW_DLE_LINE_TABLE_BAD,
dwarfstring_string(&g));
dwarfstring_destructor(&g);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
_dwarf_free_chain_entries(dbg,head_chain,line_count);
return DW_DLV_ERROR;
}
#ifdef PRINTING_DETAILS
{
dwarfstring m9d;
dwarfstring_constructor(&m9d);
dwarfstring_append_printf_u(&m9d,
"DW_LNE extended op 0x%x ",
ext_opcode);
dwarfstring_append_printf_u(&m9d,
"Bytecount: %" DW_PR_DUu ,
(Dwarf_Unsigned)instr_length);
if (remaining_bytes > 0) {
dwarfstring_append(&m9d," linedata: 0x");
while (remaining_bytes > 0) {
dwarfstring_append_printf_u(&m9d,
"%02x",
(unsigned char)(*(line_ptr)));
line_ptr++;
if (line_ptr > line_ptr_end) {
dwarfstring g;
ptrdiff_t d = 0;
d = line_ptr - section_start;
dwarfstring_constructor(&g);
dwarfstring_append_printf_u(&g,
"DW_DLE_LINE_TABLE_BAD reading "
"DW_LNE extended op remaining bytes "
"we are "
"off this line table at section "
"offset 0x%x .",
d);
_dwarf_error_string(dbg, error,
DW_DLE_LINE_TABLE_BAD,
dwarfstring_string(&g));
dwarfstring_destructor(&g);
dwarfstring_destructor(&m9d);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
_dwarf_free_chain_entries(dbg,head_chain,line_count);
return DW_DLV_ERROR;
}
remaining_bytes--;
}
}
_dwarf_printf(dbg,dwarfstring_string(&m9d));
dwarfstring_destructor(&m9d);
}
#else
line_ptr += remaining_bytes;
if (line_ptr > line_ptr_end) {
dwarfstring g;
ptrdiff_t d = 0;
d = line_ptr - section_start;
dwarfstring_constructor(&g);
dwarfstring_append_printf_u(&g,
"DW_DLE_LINE_TABLE_BAD reading "
"DW_LNE extended op remaining bytes "
"we are "
"off this line table at section "
"offset 0x%x .",
d);
_dwarf_error_string(dbg, error,
DW_DLE_LINE_TABLE_BAD,
dwarfstring_string(&g));
dwarfstring_destructor(&g);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
}
_dwarf_free_chain_entries(dbg,head_chain,line_count);
return DW_DLV_ERROR;
}
#endif
_dwarf_printf(dbg,"\n");
}
break;
}
}
}
block_line = (Dwarf_Line *)
_dwarf_get_alloc(dbg, DW_DLA_LIST, line_count);
if (block_line == NULL) {
curr_chain = head_chain;
_dwarf_free_chain_entries(dbg,head_chain,line_count);
if(curr_line) {
dwarf_dealloc(dbg,curr_line,DW_DLA_LINE);
curr_line = 0;
}
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
curr_chain = head_chain;
for (i = 0; i < line_count; i++) {
Dwarf_Chain t = 0;
*(block_line + i) = curr_chain->ch_item;
curr_chain->ch_item = 0;
curr_chain->ch_itemtype = 0;
t = curr_chain;
curr_chain = curr_chain->ch_next;
dwarf_dealloc(dbg, t, DW_DLA_CHAIN);
}
if (is_single_table || !is_actuals_table) {
line_context->lc_linebuf_logicals = block_line;
line_context->lc_linecount_logicals = line_count;
} else {
line_context->lc_linebuf_actuals = block_line;
line_context->lc_linecount_actuals = line_count;
}
#ifdef PRINTING_DETAILS
{
dwarfstring mc;
dwarfstring_constructor(&mc);
if (is_single_table) {
if(!line_count) {
dwarfstring_append_printf_u(&mc,
" Line table is present (offset 0x%"
DW_PR_XZEROS DW_PR_DUx
") but no lines present\n",
line_context->lc_section_offset);
}
} else if (is_actuals_table) {
if(!line_count) {
dwarfstring_append_printf_u(&mc,
" Line table present (offset 0x%"
DW_PR_XZEROS DW_PR_DUx
") but no actuals lines present\n",
line_context->lc_section_offset);
}
} else {
if(!line_count) {
dwarfstring_append_printf_u(&mc,
" Line table present (offset 0x%"
DW_PR_XZEROS DW_PR_DUx
") but no logicals lines present\n",
line_context->lc_section_offset);
}
}
if (dwarfstring_strlen(&mc)) {
_dwarf_printf(dbg,dwarfstring_string(&mc));
}
dwarfstring_destructor(&mc);
}
#endif
return DW_DLV_OK;
}