#include "config.h"
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "dwarf_incl.h"
#include "dwarf_alloc.h"
#include "dwarf_error.h"
#include "dwarf_util.h"
#include "dwarf_line.h"
#include "dwarfstring.h"
static struct Dwarf_Line_Registers_s _dwarf_line_table_regs_default_values = {
0,
1,
1,
0,
false,
false,
false,
false,
false,
0,
0,
0,
0,
0,
};
void
_dwarf_set_line_table_regs_default_values(Dwarf_Line_Registers regs,
unsigned lineversion,
Dwarf_Bool is_stmt)
{
*regs = _dwarf_line_table_regs_default_values;
if (lineversion == DW_LINE_VERSION5) {
regs->lr_file = 0;
}
regs->lr_is_stmt = is_stmt;
}
static int
is_path_separator(Dwarf_Small s)
{
if (s == '/') {
return 1;
}
#ifdef HAVE_WINDOWS_PATH
if (s == '\\') {
return 1;
}
#endif
return 0;
}
int
_dwarf_file_name_is_full_path(Dwarf_Small *fname)
{
Dwarf_Small firstc = *fname;
if (is_path_separator(firstc)) {
return 1;
}
if (!firstc) {
return 0;
}
if ((firstc >= 'A' && firstc <= 'Z') ||
(firstc >= 'a' && firstc <= 'z')) {
Dwarf_Small secondc = fname[1];
if (secondc == ':') {
return 1;
}
}
return 0;
}
#include "dwarf_line_table_reader_common.h"
static void
special_cat(char *dst,char *src,
UNUSEDARG int srclen)
{
#if defined (HAVE_WINDOWS_PATH)
int i1 = 0;
int i2 = 0;
for ( ; dst[i1] ; ++i1) {
}
for (; i2 < srclen; ++i2,++i1) {
dst[i1] = src[i2];
if (dst[i1] == '\\') {
dst[i1] = '/';
}
}
#else
strcat(dst, src);
#endif
return;
}
static int
create_fullest_file_path(Dwarf_Debug dbg,
Dwarf_File_Entry fe,
Dwarf_Line_Context line_context,
char ** name_ptr_out,
Dwarf_Error *error)
{
Dwarf_Unsigned dirno = 0;
char *full_name = 0;
char *file_name = 0;
dirno = fe->fi_dir_index;
file_name = (char *) fe->fi_file_name;
if (!file_name) {
_dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
return (DW_DLV_ERROR);
}
if (_dwarf_file_name_is_full_path((Dwarf_Small *)file_name)) {
{ unsigned len = strlen(file_name);
char *tmp = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING,
len+1);
if(tmp) {
tmp[0] = 0;
special_cat(tmp,file_name,len);
*name_ptr_out = tmp;
return DW_DLV_OK;
}
_dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL);
return DW_DLV_ERROR;
}
} else {
char *comp_dir_name = "";
char *inc_dir_name = "";
Dwarf_Unsigned incdirnamelen = 0;
Dwarf_Unsigned filenamelen = strlen(file_name);
Dwarf_Unsigned compdirnamelen = 0;
if (line_context->lc_compilation_directory) {
comp_dir_name =
(char *)line_context->lc_compilation_directory;
compdirnamelen = strlen(comp_dir_name);
}
if (dirno > line_context->lc_include_directories_count) {
_dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD);
return (DW_DLV_ERROR);
}
if (dirno > 0 && fe->fi_dir_index > 0) {
inc_dir_name = (char *) line_context->lc_include_directories[
fe->fi_dir_index - 1];
if (!inc_dir_name) {
inc_dir_name = "<erroneous NULL include dir pointer>";
}
incdirnamelen = strlen(inc_dir_name);
}
full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING,
compdirnamelen + 1 +
incdirnamelen + 1 +
filenamelen + 1);
if (full_name == NULL) {
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
if (fe->fi_dir_index == 0) {
if (compdirnamelen > 0) {
special_cat(full_name,comp_dir_name,compdirnamelen);
strcat(full_name, "/");
}
special_cat(full_name,file_name,filenamelen);
*name_ptr_out = full_name;
return DW_DLV_OK;
}
if (incdirnamelen > 0 &&
_dwarf_file_name_is_full_path((Dwarf_Small*)inc_dir_name) ) {
special_cat(full_name,inc_dir_name,incdirnamelen);
strcat(full_name,"/");
special_cat(full_name,file_name,filenamelen);
*name_ptr_out = full_name;
return DW_DLV_OK;
}
if (compdirnamelen > 0) {
special_cat(full_name,comp_dir_name,compdirnamelen);
strcat(full_name, "/");
}
if (incdirnamelen > 0) {
special_cat(full_name,inc_dir_name,incdirnamelen);
strcat(full_name, "/");
}
special_cat(full_name,file_name,filenamelen);
}
*name_ptr_out = full_name;
return DW_DLV_OK;
}
int
dwarf_srcfiles(Dwarf_Die die,
char ***srcfiles,
Dwarf_Signed * srcfilecount, Dwarf_Error * error)
{
Dwarf_Small *line_ptr = 0;
Dwarf_Attribute stmt_list_attr = 0;
const char * const_comp_name = 0;
const char * const_comp_dir = 0;
Dwarf_Small *comp_dir = 0;
Dwarf_Unsigned line_offset = 0;
char **ret_files = 0;
Dwarf_Debug dbg = 0;
Dwarf_CU_Context context = 0;
Dwarf_Line_Context line_context = 0;
Dwarf_Chain curr_chain = NULL;
Dwarf_Chain prev_chain = NULL;
Dwarf_Chain head_chain = NULL;
Dwarf_Half attrform = 0;
int resattr = DW_DLV_ERROR;
int lres = DW_DLV_ERROR;
unsigned i = 0;
int res = DW_DLV_ERROR;
Dwarf_Small *section_start = 0;
if (error != NULL) {
*error = NULL;
}
CHECK_DIE(die, DW_DLV_ERROR);
context = die->di_cu_context;
dbg = context->cc_dbg;
resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
if (resattr != DW_DLV_OK) {
return resattr;
}
if (dbg->de_debug_line.dss_index == 0) {
dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
_dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL);
return (DW_DLV_ERROR);
}
res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
if (res != DW_DLV_OK) {
dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
return res;
}
if (!dbg->de_debug_line.dss_size) {
dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
return (DW_DLV_NO_ENTRY);
}
section_start = dbg->de_debug_line.dss_data;
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 &&
attrform != DW_FORM_GNU_ref_alt) {
dwarfstring m;
dwarfstring f;
const char *formname = 0;
dwarfstring_constructor(&f);
dwarf_get_FORM_name(attrform,&formname);
if (!formname) {
dwarfstring_append_printf_u(&f,"Invalid Form Code "
" 0x" DW_PR_DUx,attrform);
} else {
dwarfstring_append(&f,(char *)formname);
}
dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
dwarfstring_constructor(&m);
dwarfstring_append_printf_s(&m,
"DW_DLE_LINE_OFFSET_WRONG_FORM: form %s "
"instead of an allowed section offset form.",
dwarfstring_string(&f));
_dwarf_error_string(dbg, error, DW_DLE_LINE_OFFSET_WRONG_FORM,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
dwarfstring_destructor(&f);
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);
}
line_ptr = dbg->de_debug_line.dss_data + line_offset;
{
Dwarf_Unsigned fission_offset = 0;
Dwarf_Unsigned fission_size = 0;
int resl = _dwarf_get_fission_addition_die(die, DW_SECT_LINE,
&fission_offset,&fission_size,error);
if(resl != DW_DLV_OK) {
dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
return resl;
}
line_ptr += fission_offset;
if (line_ptr > dbg->de_debug_line.dss_data +
dbg->de_debug_line.dss_size) {
dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
_dwarf_error(dbg, error, DW_DLE_FISSION_ADDITION_ERROR);
return DW_DLV_ERROR;
}
}
dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
stmt_list_attr = 0;
resattr = _dwarf_internal_get_die_comp_dir(die, &const_comp_dir,
&const_comp_name,error);
if (resattr == DW_DLV_ERROR) {
return resattr;
}
comp_dir = (Dwarf_Small *)const_comp_dir;
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);
}
line_context->lc_new_style_access = false;
{
Dwarf_Small *line_ptr_out = 0;
int dres = 0;
dres = _dwarf_read_line_table_header(dbg,
context,
section_start,
line_ptr,
dbg->de_debug_line.dss_size,
&line_ptr_out,
line_context,
NULL, NULL,error,
0);
if (dres == DW_DLV_ERROR) {
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
line_context = 0;
return dres;
}
if (dres == DW_DLV_NO_ENTRY) {
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
line_context = 0;
return dres;
}
}
line_context->lc_compilation_directory = comp_dir;
{
Dwarf_File_Entry fe = 0;
Dwarf_File_Entry fe2 =line_context->lc_file_entries;
Dwarf_Signed baseindex = 0;
Dwarf_Signed file_count = 0;
Dwarf_Signed endindex = 0;
res = dwarf_srclines_files_indexes(line_context, &baseindex,
&file_count, &endindex, error);
if (res != DW_DLV_OK) {
return res;
}
for (i = baseindex; i < endindex; ++i,fe2 = fe->fi_next ) {
int sres = 0;
char *name_out = 0;
fe = fe2;
sres = create_fullest_file_path(dbg,fe,line_context,
&name_out,error);
if (sres != DW_DLV_OK) {
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
return sres;
}
curr_chain =
(Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
if (curr_chain == NULL) {
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
curr_chain->ch_item = name_out;
if (head_chain == NULL) {
head_chain = prev_chain = curr_chain;
} else {
prev_chain->ch_next = curr_chain;
prev_chain = curr_chain;
}
}
}
if (!head_chain) {
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
*srcfiles = NULL;
*srcfilecount = 0;
return DW_DLV_NO_ENTRY;
}
if (line_context->lc_file_entry_count == 0) {
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
*srcfiles = NULL;
*srcfilecount = 0;
return DW_DLV_NO_ENTRY;
}
ret_files = (char **)
_dwarf_get_alloc(dbg, DW_DLA_LIST,
line_context->lc_file_entry_count);
if (ret_files == NULL) {
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
curr_chain = head_chain;
for (i = 0; i < line_context->lc_file_entry_count; i++) {
*(ret_files + i) = curr_chain->ch_item;
curr_chain->ch_item = 0;
prev_chain = curr_chain;
curr_chain = curr_chain->ch_next;
dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
}
*srcfiles = ret_files;
*srcfilecount = line_context->lc_file_entry_count;
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
return (DW_DLV_OK);
}
int
_dwarf_internal_srclines(Dwarf_Die die,
Dwarf_Bool is_new_interface,
Dwarf_Unsigned * version,
Dwarf_Small * table_count,
Dwarf_Line_Context *line_context_out,
Dwarf_Line ** linebuf,
Dwarf_Signed * linecount,
Dwarf_Line ** linebuf_actuals,
Dwarf_Signed * linecount_actuals,
Dwarf_Bool doaddrs,
Dwarf_Bool dolines,
Dwarf_Error * error)
{
Dwarf_Small *line_ptr = 0;
Dwarf_Small *line_ptr_end = 0;
Dwarf_Small *line_ptr_actuals = 0;
Dwarf_Small *section_start = 0;
Dwarf_Small *section_end = 0;
Dwarf_Attribute stmt_list_attr = 0;
const char * const_comp_name = 0;
const char * const_comp_dir = NULL;
Dwarf_Small *comp_dir = NULL;
Dwarf_Unsigned line_offset = 0;
Dwarf_Line_Context line_context = 0;
Dwarf_CU_Context cu_context = 0;
Dwarf_Unsigned fission_offset = 0;
Dwarf_Debug dbg = 0;
int resattr = DW_DLV_ERROR;
int lres = DW_DLV_ERROR;
Dwarf_Half address_size = 0;
Dwarf_Small * orig_line_ptr = 0;
int res = DW_DLV_ERROR;
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_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;
section_end = section_start +dbg->de_debug_line.dss_size;
{
Dwarf_Unsigned fission_size = 0;
int resf = _dwarf_get_fission_addition_die(die, DW_SECT_LINE,
&fission_offset,&fission_size,error);
if(resf != DW_DLV_OK) {
dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
return resf;
}
line_ptr += fission_offset;
if (line_ptr > section_end) {
_dwarf_error(dbg, error, DW_DLE_FISSION_ADDITION_ERROR);
return DW_DLV_ERROR;
}
}
section_start = dbg->de_debug_line.dss_data;
section_end = section_start +dbg->de_debug_line.dss_size;
orig_line_ptr = section_start + line_offset + fission_offset;
line_ptr = orig_line_ptr;
dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
if ((line_offset + fission_offset) > dbg->de_debug_line.dss_size) {
_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
return DW_DLV_ERROR;
}
if (line_ptr > section_end) {
_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
return DW_DLV_ERROR;
}
resattr = _dwarf_internal_get_die_comp_dir(die, &const_comp_dir,
&const_comp_name,error);
if (resattr == DW_DLV_ERROR) {
return resattr;
}
comp_dir = (Dwarf_Small *)const_comp_dir;
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);
}
line_context->lc_new_style_access = is_new_interface;
line_context->lc_compilation_directory = comp_dir;
{
Dwarf_Small *newlinep = 0;
int resp = _dwarf_read_line_table_header(dbg,
cu_context,
section_start,
line_ptr,
dbg->de_debug_line.dss_size,
&newlinep,
line_context,
NULL,NULL,
error,
0);
if (resp == DW_DLV_ERROR) {
if(is_new_interface) {
dwarf_srclines_dealloc_b(line_context);
} else {
dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT);
}
return resp;
}
if (resp == DW_DLV_NO_ENTRY) {
if(is_new_interface) {
dwarf_srclines_dealloc_b(line_context);
} else {
dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT);
}
return resp;
}
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;
}
}
if (line_ptr_actuals == 0) {
int err_count_out = 0;
Dwarf_Bool is_actuals_table = false;
Dwarf_Bool local_is_single_table = true;
res = read_line_table_program(dbg,
line_ptr, line_ptr_end, orig_line_ptr,
section_start,
line_context,
address_size, doaddrs, dolines,
local_is_single_table,
is_actuals_table,
error,
&err_count_out);
if (res != DW_DLV_OK) {
if(is_new_interface) {
dwarf_srclines_dealloc_b(line_context);
} else {
dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT);
}
return res;
}
if (linebuf)
*linebuf = line_context->lc_linebuf_logicals;
if (linecount)
*linecount = line_context->lc_linecount_logicals;
if (linebuf_actuals) {
*linebuf_actuals = NULL;
}
if (linecount_actuals) {
*linecount_actuals = 0;
}
} else {
Dwarf_Bool is_actuals_table = false;
Dwarf_Bool local2_is_single_table = false;
int err_count_out = 0;
line_context->lc_is_single_table = false;
res = read_line_table_program(dbg,
line_ptr, line_ptr_actuals, orig_line_ptr,
section_start,
line_context,
address_size, doaddrs, dolines,
local2_is_single_table,
is_actuals_table, error,
&err_count_out);
if (res != DW_DLV_OK) {
if(is_new_interface) {
dwarf_srclines_dealloc_b(line_context);
} else {
dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT);
}
return res;
}
if (linebuf) {
*linebuf = line_context->lc_linebuf_logicals;
} else {
}
if (linecount) {
*linecount = line_context->lc_linecount_logicals;
}
if (is_new_interface) {
is_actuals_table = true;
res = read_line_table_program(dbg,
line_ptr_actuals, line_ptr_end, orig_line_ptr,
section_start,
line_context,
address_size, doaddrs, dolines,
local2_is_single_table,
is_actuals_table, error,
&err_count_out);
if (res != DW_DLV_OK) {
dwarf_srclines_dealloc_b(line_context);
return res;
}
if (linebuf_actuals) {
*linebuf_actuals = line_context->lc_linebuf_actuals;
}
if (linecount_actuals != NULL) {
*linecount_actuals = line_context->lc_linecount_actuals;
}
}
}
if (!is_new_interface && linecount &&
(linecount == 0 ||*linecount == 0) &&
(linecount_actuals == 0 || *linecount_actuals == 0)) {
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
line_context = 0;
return DW_DLV_OK;
}
*table_count = line_context->lc_table_count;
if (version != NULL) {
*version = line_context->lc_version_number;
}
*line_context_out = line_context;
return (DW_DLV_OK);
}
int
dwarf_get_ranges_section_name(Dwarf_Debug dbg,
const char **section_name_out,
Dwarf_Error * error)
{
struct Dwarf_Section_s *sec = 0;
if (error != NULL) {
*error = NULL;
}
sec = &dbg->de_debug_ranges;
if (sec->dss_size == 0) {
return DW_DLV_NO_ENTRY;
}
*section_name_out = sec->dss_name;
return DW_DLV_OK;
}
int
dwarf_get_aranges_section_name(Dwarf_Debug dbg,
const char **section_name_out,
Dwarf_Error * error)
{
struct Dwarf_Section_s *sec = 0;
if (error != NULL) {
*error = NULL;
}
sec = &dbg->de_debug_aranges;
if (sec->dss_size == 0) {
return DW_DLV_NO_ENTRY;
}
*section_name_out = sec->dss_name;
return DW_DLV_OK;
}
int
dwarf_get_line_section_name_from_die(Dwarf_Die die,
const char **section_name_out,
Dwarf_Error * error)
{
Dwarf_Debug dbg = 0;
struct Dwarf_Section_s *sec = 0;
if (error) {
*error = NULL;
}
CHECK_DIE(die, DW_DLV_ERROR);
dbg = die->di_cu_context->cc_dbg;
sec = &dbg->de_debug_line;
if (sec->dss_size == 0) {
return DW_DLV_NO_ENTRY;
}
*section_name_out = sec->dss_name;
return DW_DLV_OK;
}
int
dwarf_get_string_section_name(Dwarf_Debug dbg,
const char **section_name_out,
Dwarf_Error * error)
{
struct Dwarf_Section_s *sec = 0;
if (error != NULL) {
*error = NULL;
}
sec = &dbg->de_debug_str;
if (sec->dss_size == 0) {
return DW_DLV_NO_ENTRY;
}
*section_name_out = sec->dss_name;
return DW_DLV_OK;
}
int
dwarf_srclines(Dwarf_Die die,
Dwarf_Line ** linebuf,
Dwarf_Signed * linecount, Dwarf_Error * error)
{
Dwarf_Unsigned version = 0;
Dwarf_Line_Context line_context = 0;
Dwarf_Small table_count = 0;
Dwarf_Bool is_new_interface = false;
int res = _dwarf_internal_srclines(die,
is_new_interface,
&version,
&table_count,
&line_context,
linebuf,
linecount,
0,
0,
false,
true,
error);
return res;
}
int
dwarf_srclines_two_level(Dwarf_Die die,
Dwarf_Unsigned * version,
Dwarf_Line ** linebuf,
Dwarf_Signed * linecount,
Dwarf_Line ** linebuf_actuals,
Dwarf_Signed * linecount_actuals,
Dwarf_Error * error)
{
Dwarf_Line_Context line_context = 0;
Dwarf_Small table_count = 0;
Dwarf_Bool is_new_interface = false;
int res = _dwarf_internal_srclines(die,
is_new_interface,
version,
&table_count,
&line_context,
linebuf,
linecount,
linebuf_actuals,
linecount_actuals,
false,
true,
error);
return res;
}
int
dwarf_srclines_b(Dwarf_Die die,
Dwarf_Unsigned * version_out,
Dwarf_Small * table_count,
Dwarf_Line_Context * line_context,
Dwarf_Error * error)
{
Dwarf_Signed linecount_actuals = 0;
Dwarf_Line *linebuf = 0;
Dwarf_Line *linebuf_actuals = 0;
Dwarf_Signed linecount = 0;
Dwarf_Bool is_new_interface = true;
int res = 0;
Dwarf_Unsigned tcount = 0;
res = _dwarf_internal_srclines(die,
is_new_interface,
version_out,
table_count,
line_context,
&linebuf,
&linecount,
&linebuf_actuals,
&linecount_actuals,
false,
true,
error);
if (res == DW_DLV_OK) {
(*line_context)->lc_new_style_access = true;
}
if(linecount_actuals ) {
tcount++;
}
if(linecount ) {
tcount++;
}
*table_count = tcount;
return res;
}
int
dwarf_srclines_from_linecontext(Dwarf_Line_Context line_context,
Dwarf_Line** linebuf,
Dwarf_Signed * linecount,
Dwarf_Error * error)
{
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
if (!line_context->lc_new_style_access) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
*linebuf = line_context->lc_linebuf_logicals;
*linecount = line_context->lc_linecount_logicals;
return DW_DLV_OK;
}
int
dwarf_srclines_two_level_from_linecontext(Dwarf_Line_Context line_context,
Dwarf_Line** linebuf,
Dwarf_Signed * linecount,
Dwarf_Line** linebuf_actuals,
Dwarf_Signed * linecount_actuals,
Dwarf_Error * error)
{
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
if (!line_context->lc_new_style_access) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
*linebuf = line_context->lc_linebuf_logicals;
*linecount = line_context->lc_linecount_logicals;
*linebuf_actuals = line_context->lc_linebuf_actuals;
*linecount_actuals = line_context->lc_linecount_actuals;
return DW_DLV_OK;
}
int
dwarf_srclines_table_offset(Dwarf_Line_Context line_context,
Dwarf_Unsigned * offset,
Dwarf_Error * error)
{
if (!line_context ){
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
if( line_context->lc_magic != DW_CONTEXT_MAGIC) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
*offset = line_context->lc_section_offset;
return DW_DLV_OK;
}
int dwarf_srclines_comp_dir(Dwarf_Line_Context line_context,
const char ** compilation_directory,
Dwarf_Error * error)
{
if (!line_context ){
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
if( line_context->lc_magic != DW_CONTEXT_MAGIC) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
*compilation_directory =
(const char *)line_context->lc_compilation_directory;
return DW_DLV_OK;
}
int
dwarf_srclines_subprog_count(Dwarf_Line_Context line_context,
Dwarf_Signed * count_out,
Dwarf_Error * error)
{
if (!line_context ){
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
if( line_context->lc_magic != DW_CONTEXT_MAGIC) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
*count_out = line_context->lc_subprogs_count;
return DW_DLV_OK;
}
int
dwarf_srclines_subprog_data(Dwarf_Line_Context line_context,
Dwarf_Signed index_in,
const char ** name,
Dwarf_Unsigned *decl_file,
Dwarf_Unsigned *decl_line,
Dwarf_Error *error)
{
Dwarf_Unsigned index = (Dwarf_Unsigned)index_in;
Dwarf_Subprog_Entry sub = 0;
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
if (index < 1 || index > line_context->lc_subprogs_count) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG);
return (DW_DLV_ERROR);
}
sub = line_context->lc_subprogs + (index-1);
*name = (const char *)sub->ds_subprog_name;
*decl_file = sub->ds_decl_file;
*decl_line = sub->ds_decl_line;
return DW_DLV_OK;
}
int
dwarf_srclines_files_count(Dwarf_Line_Context line_context,
Dwarf_Signed *count_out,
Dwarf_Error *error)
{
if (!line_context ||
line_context->lc_magic != DW_CONTEXT_MAGIC) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
*count_out = (Dwarf_Signed)line_context->lc_file_entry_count;
return DW_DLV_OK;
}
int
dwarf_srclines_files_data(Dwarf_Line_Context line_context,
Dwarf_Signed index_in,
const char ** name,
Dwarf_Unsigned * directory_index,
Dwarf_Unsigned * last_mod_time,
Dwarf_Unsigned * file_length,
Dwarf_Error * error)
{
return dwarf_srclines_files_data_b(
line_context,index_in,name,directory_index,
last_mod_time,file_length,0,error);
}
int
dwarf_srclines_files_indexes(Dwarf_Line_Context line_context,
Dwarf_Signed *baseindex,
Dwarf_Signed *file_count,
Dwarf_Signed *endindex,
Dwarf_Error * error)
{
if(line_context->lc_magic != DW_CONTEXT_MAGIC) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return DW_DLV_ERROR;
}
*baseindex = line_context->lc_file_entry_baseindex;
*file_count = line_context->lc_file_entry_count;
*endindex = line_context->lc_file_entry_endindex;
return DW_DLV_OK;
}
int
dwarf_srclines_files_data_b(Dwarf_Line_Context line_context,
Dwarf_Signed index_in,
const char ** name,
Dwarf_Unsigned * directory_index,
Dwarf_Unsigned * last_mod_time,
Dwarf_Unsigned * file_length,
Dwarf_Form_Data16 ** data16ptr,
Dwarf_Error * error)
{
Dwarf_File_Entry fi = 0;
Dwarf_Signed i =0;
Dwarf_Signed baseindex = 0;
Dwarf_Signed file_count = 0;
Dwarf_Signed endindex = 0;
Dwarf_Signed index = index_in;
int res = 0;
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
res = dwarf_srclines_files_indexes(line_context, &baseindex,
&file_count, &endindex, error);
if (res != DW_DLV_OK) {
return res;
}
fi = line_context->lc_file_entries;
if (index < baseindex || index >= endindex) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG);
return DW_DLV_ERROR;
}
for ( i = baseindex;i < index; i++) {
fi = fi->fi_next;
if(!fi) {
_dwarf_error(NULL, error, DW_DLE_LINE_HEADER_CORRUPT);
return DW_DLV_ERROR;
}
}
if(name) {
*name = (const char *)fi->fi_file_name;
}
if (directory_index) {
*directory_index = fi->fi_dir_index;
}
if (last_mod_time) {
*last_mod_time = fi->fi_time_last_mod;
}
if (file_length) {
*file_length = fi->fi_file_length;
}
if (data16ptr) {
if (fi->fi_md5_present) {
*data16ptr = &fi->fi_md5_value;
} else {
*data16ptr = 0;
}
}
return DW_DLV_OK;
}
int
dwarf_srclines_include_dir_count(Dwarf_Line_Context line_context,
Dwarf_Signed * count,
Dwarf_Error * error)
{
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
*count = line_context->lc_include_directories_count;
return DW_DLV_OK;
}
int
dwarf_srclines_include_dir_data(Dwarf_Line_Context line_context,
Dwarf_Signed index_in,
const char ** name,
Dwarf_Error * error)
{
Dwarf_Unsigned index = index_in;
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
if (index < 1 || index > line_context->lc_include_directories_count) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG);
return (DW_DLV_ERROR);
}
*name = (const char *)(line_context->lc_include_directories[index-1]);
return DW_DLV_OK;
}
int
dwarf_srclines_version(Dwarf_Line_Context line_context,
Dwarf_Unsigned *version_out,
Dwarf_Small *table_count_out,
Dwarf_Error *error)
{
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
return (DW_DLV_ERROR);
}
*version_out = line_context->lc_version_number;
*table_count_out = line_context->lc_table_count;
return DW_DLV_OK;
}
int
dwarf_linebeginstatement(Dwarf_Line line,
Dwarf_Bool * return_bool, Dwarf_Error * error)
{
if (line == NULL || return_bool == 0) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return (DW_DLV_ERROR);
}
*return_bool = (line->li_addr_line.li_l_data.li_is_stmt);
return DW_DLV_OK;
}
int
dwarf_lineendsequence(Dwarf_Line line,
Dwarf_Bool * return_bool, Dwarf_Error * error)
{
if (line == NULL) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return (DW_DLV_ERROR);
}
*return_bool = (line->li_addr_line.li_l_data.li_end_sequence);
return DW_DLV_OK;
}
int
dwarf_lineno(Dwarf_Line line,
Dwarf_Unsigned * ret_lineno, Dwarf_Error * error)
{
if (line == NULL || ret_lineno == 0) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return (DW_DLV_ERROR);
}
*ret_lineno = (line->li_addr_line.li_l_data.li_line);
return DW_DLV_OK;
}
int
dwarf_line_srcfileno(Dwarf_Line line,
Dwarf_Unsigned * ret_fileno, Dwarf_Error * error)
{
if (line == NULL || ret_fileno == 0) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return DW_DLV_ERROR;
}
*ret_fileno = (line->li_addr_line.li_l_data.li_file);
return DW_DLV_OK;
}
int
dwarf_line_is_addr_set(Dwarf_Line line,
Dwarf_Bool *is_addr_set, Dwarf_Error * error)
{
if (line == NULL) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return (DW_DLV_ERROR);
}
*is_addr_set = (line->li_addr_line.li_l_data.li_is_addr_set);
return DW_DLV_OK;
}
int
dwarf_lineaddr(Dwarf_Line line,
Dwarf_Addr * ret_lineaddr, Dwarf_Error * error)
{
if (line == NULL || ret_lineaddr == 0) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return (DW_DLV_ERROR);
}
*ret_lineaddr = (line->li_address);
return DW_DLV_OK;
}
int
dwarf_lineoff(Dwarf_Line line,
Dwarf_Signed * ret_lineoff, Dwarf_Error * error)
{
if (line == NULL || ret_lineoff == 0) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return (DW_DLV_ERROR);
}
*ret_lineoff = (
(line->li_addr_line.li_l_data.li_column == 0) ?
-1 : line->li_addr_line.li_l_data.li_column);
return DW_DLV_OK;
}
int
dwarf_lineoff_b(Dwarf_Line line,
Dwarf_Unsigned * ret_lineoff, Dwarf_Error * error)
{
if (line == NULL || ret_lineoff == 0) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return (DW_DLV_ERROR);
}
*ret_lineoff = line->li_addr_line.li_l_data.li_column;
return DW_DLV_OK;
}
static int
dwarf_filename(Dwarf_Line_Context context,
Dwarf_Signed fileno_in,
char **ret_filename, Dwarf_Error *error)
{
Dwarf_Signed i = 0;
Dwarf_File_Entry file_entry = 0;
Dwarf_Debug dbg = context->lc_dbg;
int res = 0;
Dwarf_Signed baseindex = 0;
Dwarf_Signed file_count = 0;
Dwarf_Signed endindex = 0;
Dwarf_Signed fileno = fileno_in;
unsigned linetab_version = context->lc_version_number;
res = dwarf_srclines_files_indexes(context, &baseindex,
&file_count, &endindex, error);
if (res != DW_DLV_OK) {
return res;
}
if (fileno >= endindex) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_i(&m,
"DW_DLE_NO_FILE_NAME: the file number is %d ",
fileno);
dwarfstring_append_printf_u(&m,
"( this is a DWARF 0x%x linetable)",
linetab_version);
dwarfstring_append_printf_i(&m,
" yet the highest allowed file name index is %d.",
endindex-1);
_dwarf_error_string(dbg, error, DW_DLE_NO_FILE_NAME,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
} else {
if (linetab_version <= DW_LINE_VERSION4 ||
linetab_version == EXPERIMENTAL_LINE_TABLES_VERSION) {
if (!fileno) {
return DW_DLV_NO_ENTRY;
}
}
}
file_entry = context->lc_file_entries;
for (i = baseindex; i < fileno ; i++) {
file_entry = file_entry->fi_next;
}
res = create_fullest_file_path(dbg,
file_entry,context, ret_filename,error);
return res;
}
int
dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error)
{
if (line == NULL) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return DW_DLV_ERROR;
}
if (line->li_context == NULL) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL);
return DW_DLV_ERROR;
}
return dwarf_filename(line->li_context,
line->li_addr_line.li_l_data.li_file, ret_linesrc, error);
}
int
dwarf_lineblock(Dwarf_Line line,
Dwarf_Bool * return_bool, Dwarf_Error * error)
{
if (line == NULL) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return (DW_DLV_ERROR);
}
*return_bool = (line->li_addr_line.li_l_data.li_basic_block);
return DW_DLV_OK;
}
int dwarf_prologue_end_etc(Dwarf_Line line,
Dwarf_Bool * prologue_end,
Dwarf_Bool * epilogue_begin,
Dwarf_Unsigned * isa,
Dwarf_Unsigned * discriminator,
Dwarf_Error * error)
{
if (line == NULL) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return (DW_DLV_ERROR);
}
*prologue_end = (line->li_addr_line.li_l_data.li_prologue_end);
*epilogue_begin = (line->li_addr_line.li_l_data.li_epilogue_begin);
*isa = (line->li_addr_line.li_l_data.li_isa);
*discriminator = (line->li_addr_line.li_l_data.li_discriminator);
return DW_DLV_OK;
}
int
dwarf_linelogical(Dwarf_Line line,
Dwarf_Unsigned * logical,
Dwarf_Error* error)
{
if (line == NULL) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return (DW_DLV_ERROR);
}
*logical = (line->li_addr_line.li_l_data.li_line);
return DW_DLV_OK;
}
int
dwarf_linecontext(Dwarf_Line line,
Dwarf_Unsigned * context,
Dwarf_Error* error)
{
if (line == NULL) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return (DW_DLV_ERROR);
}
*context = (line->li_addr_line.li_l_data.li_call_context);
return DW_DLV_OK;
}
int
dwarf_line_subprogno(Dwarf_Line line,
Dwarf_Unsigned * subprog,
Dwarf_Error * error)
{
if (line == NULL) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return (DW_DLV_ERROR);
}
*subprog = (line->li_addr_line.li_l_data.li_subprogram);
return DW_DLV_OK;
}
int
dwarf_line_subprog(Dwarf_Line line,
char ** subprog_name,
char ** decl_filename,
Dwarf_Unsigned * decl_line,
Dwarf_Error * error)
{
Dwarf_Unsigned subprog_no;
Dwarf_Subprog_Entry subprog;
Dwarf_Debug dbg;
int res;
if (line == NULL) {
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
return DW_DLV_ERROR;
}
if (line->li_context == NULL) {
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL);
return DW_DLV_ERROR;
}
dbg = line->li_context->lc_dbg;
subprog_no = line->li_addr_line.li_l_data.li_subprogram;
if (subprog_no == 0) {
*subprog_name = NULL;
*decl_filename = NULL;
*decl_line = 0;
return DW_DLV_OK;
}
if (subprog_no > line->li_context->lc_subprogs_count) {
_dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
return DW_DLV_ERROR;
}
subprog = &line->li_context->lc_subprogs[subprog_no - 1];
*subprog_name = (char *)subprog->ds_subprog_name;
*decl_line = subprog->ds_decl_line;
res = dwarf_filename(line->li_context,
subprog->ds_decl_file,
decl_filename, error);
if (res != DW_DLV_OK) {
*decl_filename = NULL;
return res;
}
return DW_DLV_OK;
}
static void
delete_line_context_itself(Dwarf_Line_Context context)
{
Dwarf_Debug dbg = 0;
Dwarf_File_Entry fe = 0;
if(context->lc_magic != DW_CONTEXT_MAGIC) {
return;
}
dbg = context->lc_dbg;
fe = context->lc_file_entries;
while (fe) {
Dwarf_File_Entry fenext = fe->fi_next;
fe->fi_next = 0;
free(fe);
fe = fenext;
}
context->lc_file_entries = 0;
context->lc_file_entry_count = 0;
context->lc_file_entry_baseindex = 0;
context->lc_file_entry_endindex = 0;
if (context->lc_subprogs) {
free(context->lc_subprogs);
context->lc_subprogs = 0;
}
free(context->lc_directory_format_values);
context->lc_directory_format_values = 0;
free(context->lc_file_format_values);
context->lc_file_format_values = 0;
if (context->lc_include_directories) {
free(context->lc_include_directories);
context->lc_include_directories = 0;
}
context->lc_magic = 0xdead;
dwarf_dealloc(dbg, context, DW_DLA_LINE_CONTEXT);
}
void
dwarf_srclines_dealloc(Dwarf_Debug dbg, Dwarf_Line * linebuf,
Dwarf_Signed count)
{
Dwarf_Signed i = 0;
Dwarf_Bool alternate_data_count = 0;
struct Dwarf_Line_Context_s *line_context = 0;
if(!linebuf) {
return;
}
if (count > 0) {
line_context = linebuf[0]->li_context;
if (line_context && line_context->lc_magic != DW_CONTEXT_MAGIC ) {
line_context = 0;
} else if (line_context) {
if (linebuf == line_context->lc_linebuf_logicals) {
line_context->lc_linebuf_logicals = 0;
line_context->lc_linecount_logicals = 0;
alternate_data_count = line_context->lc_linecount_actuals;
} else if (linebuf == line_context->lc_linebuf_actuals) {
line_context->lc_linebuf_actuals = 0;
line_context->lc_linecount_actuals = 0;
alternate_data_count = line_context->lc_linecount_logicals;
} else {
return;
}
} else {
line_context = 0;
}
}
for (i = 0; i < count; ++i) {
dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);
}
dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
if (line_context && !line_context->lc_new_style_access
&& !alternate_data_count ) {
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
}
return;
}
void
dwarf_srclines_dealloc_b(Dwarf_Line_Context line_context)
{
Dwarf_Line *linestable = 0;
Dwarf_Signed linescount = 0;
Dwarf_Signed i = 0;
Dwarf_Debug dbg = 0;
if(!line_context) {
return;
}
if(line_context->lc_magic != DW_CONTEXT_MAGIC) {
return; }
dbg = line_context->lc_dbg;
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
return;
}
linestable = line_context->lc_linebuf_logicals;
if (linestable) {
linescount = line_context->lc_linecount_logicals;
for (i = 0; i < linescount ; ++i) {
dwarf_dealloc(dbg, linestable[i], DW_DLA_LINE);
}
dwarf_dealloc(dbg, linestable, DW_DLA_LIST);
}
line_context->lc_linebuf_logicals = 0;
line_context->lc_linecount_logicals = 0;
linestable = line_context->lc_linebuf_actuals;
if (linestable) {
linescount = line_context->lc_linecount_actuals;
for (i = 0; i <linescount ; ++i) {
dwarf_dealloc(dbg, linestable[i], DW_DLA_LINE);
}
dwarf_dealloc(dbg, linestable, DW_DLA_LIST);
}
line_context->lc_linebuf_actuals = 0;
line_context->lc_linecount_actuals = 0;
delete_line_context_itself(line_context);
}
void
_dwarf_print_header_issue(Dwarf_Debug dbg,
const char *specific_msg,
Dwarf_Small *data_start,
Dwarf_Signed value,
unsigned index,
unsigned tabv,
unsigned linetabv,
int *err_count_out)
{
if (!err_count_out) {
return;
}
if (dwarf_cmdline_options.check_verbose_mode){
dwarfstring m1;
dwarfstring_constructor(&m1);
dwarfstring_append(&m1,
"\n*** DWARF CHECK: "
".debug_line: ");
dwarfstring_append(&m1,(char *)specific_msg);
dwarfstring_append_printf_i(&m1,
" %" DW_PR_DSd,value);
if (index || tabv || linetabv) {
dwarfstring_append_printf_u(&m1,
"; Mismatch index %u",index);
dwarfstring_append_printf_u(&m1,
" stdval %u",tabv);
dwarfstring_append_printf_u(&m1,
" linetabval %u",linetabv);
}
if (data_start >= dbg->de_debug_line.dss_data &&
(data_start < (dbg->de_debug_line.dss_data +
dbg->de_debug_line.dss_size))) {
Dwarf_Unsigned off =
data_start - dbg->de_debug_line.dss_data;
dwarfstring_append_printf_u(&m1,
" at offset 0x%" DW_PR_XZEROS DW_PR_DUx,off);
dwarfstring_append_printf_u(&m1,
" ( %" DW_PR_DUu " ) ",off);
} else {
dwarfstring_append(&m1,
" (unknown section location) ");
}
dwarfstring_append(&m1,"***\n");
_dwarf_printf(dbg,dwarfstring_string(&m1));
dwarfstring_destructor(&m1);
}
*err_count_out += 1;
}
int
_dwarf_decode_line_string_form(Dwarf_Debug dbg,
Dwarf_Unsigned form,
Dwarf_Unsigned offset_size,
Dwarf_Small **line_ptr,
Dwarf_Small *line_ptr_end,
char **return_str,
Dwarf_Error * error)
{
int res = 0;
switch (form) {
case DW_FORM_line_strp: {
Dwarf_Small *secstart = 0;
Dwarf_Small *secend = 0;
Dwarf_Small *strptr = 0;
Dwarf_Unsigned offset = 0;
Dwarf_Small *offsetptr = *line_ptr;
res = _dwarf_load_section(dbg, &dbg->de_debug_line_str,error);
if (res != DW_DLV_OK) {
return res;
}
secstart = dbg->de_debug_line_str.dss_data;
secend = secstart + dbg->de_debug_line_str.dss_size;
READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,offsetptr, offset_size,
error,line_ptr_end);
*line_ptr += offset_size;
strptr = secstart + offset;
res = _dwarf_check_string_valid(dbg,
secstart,strptr,secend,
DW_DLE_LINE_STRP_OFFSET_BAD,error);
if (res != DW_DLV_OK) {
return res;
}
*return_str = (char *) strptr;
return DW_DLV_OK;
}
case DW_FORM_string: {
Dwarf_Small *secend = line_ptr_end;
Dwarf_Small *strptr = *line_ptr;
res = _dwarf_check_string_valid(dbg,
strptr ,strptr,secend,DW_DLE_LINE_STRING_BAD,error);
if (res != DW_DLV_OK) {
return res;
}
*return_str = (char *)strptr;
*line_ptr += strlen((const char *)strptr) + 1;
return DW_DLV_OK;
}
default:
_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
return DW_DLV_ERROR;
}
}
int
_dwarf_decode_line_udata_form(Dwarf_Debug dbg,
Dwarf_Unsigned form,
Dwarf_Small **line_ptr,
Dwarf_Unsigned *return_val,
Dwarf_Small *line_end_ptr,
Dwarf_Error * error)
{
Dwarf_Unsigned val = 0;
Dwarf_Small * lp = *line_ptr;
switch (form) {
case DW_FORM_udata:
DECODE_LEB128_UWORD_CK(lp, val,dbg,error,line_end_ptr);
*return_val = val;
*line_ptr = lp;
return DW_DLV_OK;
default:
_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
return DW_DLV_ERROR;
}
}
void
_dwarf_update_chain_list( Dwarf_Chain chain_line,
Dwarf_Chain *head_chain, Dwarf_Chain *curr_chain)
{
if (*head_chain == NULL) {
*head_chain = chain_line;
} else {
(*curr_chain)->ch_next = chain_line;
}
*curr_chain = chain_line;
}
void
_dwarf_free_chain_entries(Dwarf_Debug dbg,Dwarf_Chain head,int count)
{
int i = 0;
Dwarf_Chain curr_chain = head;
for (i = 0; i < count; i++) {
Dwarf_Chain t = curr_chain;
void *item = t->ch_item;
int itype = t->ch_itemtype;
if (item && itype) {
dwarf_dealloc(dbg,item,itype);
t->ch_item = 0;
}
curr_chain = curr_chain->ch_next;
dwarf_dealloc(dbg, t, DW_DLA_CHAIN);
}
}
int
_dwarf_add_to_files_list(Dwarf_Line_Context context, Dwarf_File_Entry fe)
{
if (!context->lc_file_entries) {
context->lc_file_entries = fe;
} else {
context->lc_last_entry->fi_next = fe;
}
context->lc_last_entry = fe;
context->lc_file_entry_count++;
if (context->lc_version_number >= DW_LINE_VERSION5 &&
context->lc_version_number != EXPERIMENTAL_LINE_TABLES_VERSION) {
context->lc_file_entry_baseindex = 0;
context->lc_file_entry_endindex = context->lc_file_entry_count;
} else {
context->lc_file_entry_baseindex = 1;
context->lc_file_entry_endindex = context->lc_file_entry_count+1;
}
return DW_DLV_OK;
}
int
_dwarf_line_context_constructor(Dwarf_Debug dbg, void *m)
{
Dwarf_Line_Context line_context = (Dwarf_Line_Context)m;
line_context->lc_magic = DW_CONTEXT_MAGIC;
line_context->lc_dbg = dbg;
return DW_DLV_OK;
}
void
_dwarf_line_context_destructor(void *m)
{
Dwarf_Line_Context line_context = (Dwarf_Line_Context)m;
if (line_context->lc_magic != DW_CONTEXT_MAGIC) {
return;
}
if (line_context->lc_include_directories) {
free(line_context->lc_include_directories);
line_context->lc_include_directories = 0;
line_context->lc_include_directories_count = 0;
}
if (line_context->lc_file_entries) {
Dwarf_File_Entry fe = line_context->lc_file_entries;
while(fe) {
Dwarf_File_Entry t = fe;
fe = t->fi_next;
t->fi_next = 0;
free(t);
}
line_context->lc_file_entries = 0;
line_context->lc_last_entry = 0;
line_context->lc_file_entry_count = 0;
line_context->lc_file_entry_baseindex = 0;
line_context->lc_file_entry_endindex = 0;
}
free(line_context->lc_directory_format_values);
line_context->lc_directory_format_values = 0;
free(line_context->lc_file_format_values);
line_context->lc_file_format_values = 0;
if (line_context->lc_subprogs) {
free(line_context->lc_subprogs);
line_context->lc_subprogs = 0;
line_context->lc_subprogs_count = 0;
}
line_context->lc_magic = 0;
return;
}