|
|
|
@@ -567,6 +567,8 @@ struct line
|
|
|
|
|
const char *filename;
|
|
|
|
|
/* Line number. */
|
|
|
|
|
int lineno;
|
|
|
|
|
/* Column number */
|
|
|
|
|
int column;
|
|
|
|
|
/* Index of the object in the original array read from the DWARF
|
|
|
|
|
section, before it has been sorted. The index makes it possible
|
|
|
|
|
to use Quicksort and maintain stability. */
|
|
|
|
@@ -596,6 +598,9 @@ struct function
|
|
|
|
|
/* If this is an inlined function, the line number of the call
|
|
|
|
|
site. */
|
|
|
|
|
int caller_lineno;
|
|
|
|
|
/* If this is an inlined function, the column of the call
|
|
|
|
|
site. */
|
|
|
|
|
int caller_column;
|
|
|
|
|
/* Map PC ranges to inlined functions. */
|
|
|
|
|
struct function_addrs *function_addrs;
|
|
|
|
|
size_t function_addrs_count;
|
|
|
|
@@ -2611,7 +2616,7 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
add_line (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
uintptr_t pc, const char *filename, int lineno,
|
|
|
|
|
uintptr_t pc, const char *filename, int lineno, int column,
|
|
|
|
|
backtrace_error_callback error_callback, void *data,
|
|
|
|
|
struct line_vector *vec)
|
|
|
|
|
{
|
|
|
|
@@ -2638,6 +2643,7 @@ add_line (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
|
|
|
|
|
ln->filename = filename;
|
|
|
|
|
ln->lineno = lineno;
|
|
|
|
|
ln->column = column;
|
|
|
|
|
ln->idx = vec->count;
|
|
|
|
|
|
|
|
|
|
++vec->count;
|
|
|
|
@@ -3056,6 +3062,7 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
const char *reset_filename;
|
|
|
|
|
const char *filename;
|
|
|
|
|
int lineno;
|
|
|
|
|
int column;
|
|
|
|
|
|
|
|
|
|
address = 0;
|
|
|
|
|
op_index = 0;
|
|
|
|
@@ -3064,6 +3071,7 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
else
|
|
|
|
|
reset_filename = "";
|
|
|
|
|
filename = reset_filename;
|
|
|
|
|
column = 0;
|
|
|
|
|
lineno = 1;
|
|
|
|
|
while (line_buf->left > 0)
|
|
|
|
|
{
|
|
|
|
@@ -3081,7 +3089,7 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
/ hdr->max_ops_per_insn);
|
|
|
|
|
op_index = (op_index + advance) % hdr->max_ops_per_insn;
|
|
|
|
|
lineno += hdr->line_base + (int) (op % hdr->line_range);
|
|
|
|
|
add_line (state, ddata, address, filename, lineno,
|
|
|
|
|
add_line (state, ddata, address, filename, lineno, column,
|
|
|
|
|
line_buf->error_callback, line_buf->data, vec);
|
|
|
|
|
}
|
|
|
|
|
else if (op == DW_LNS_extended_op)
|
|
|
|
@@ -3169,7 +3177,7 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
switch (op)
|
|
|
|
|
{
|
|
|
|
|
case DW_LNS_copy:
|
|
|
|
|
add_line (state, ddata, address, filename, lineno,
|
|
|
|
|
add_line (state, ddata, address, filename, lineno, column,
|
|
|
|
|
line_buf->error_callback, line_buf->data, vec);
|
|
|
|
|
break;
|
|
|
|
|
case DW_LNS_advance_pc:
|
|
|
|
@@ -3202,7 +3210,7 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case DW_LNS_set_column:
|
|
|
|
|
read_uleb128 (line_buf);
|
|
|
|
|
column = read_uleb128 (line_buf);
|
|
|
|
|
break;
|
|
|
|
|
case DW_LNS_negate_stmt:
|
|
|
|
|
break;
|
|
|
|
@@ -3642,6 +3650,10 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
if (val.encoding == ATTR_VAL_UINT)
|
|
|
|
|
function->caller_lineno = val.u.uint;
|
|
|
|
|
break;
|
|
|
|
|
case DW_AT_call_column:
|
|
|
|
|
if (val.encoding == ATTR_VAL_UINT)
|
|
|
|
|
function->caller_column = val.u.uint;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case DW_AT_abstract_origin:
|
|
|
|
|
case DW_AT_specification:
|
|
|
|
@@ -3884,7 +3896,7 @@ read_function_info (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
static int
|
|
|
|
|
report_inlined_functions (uintptr_t pc, struct function *function,
|
|
|
|
|
backtrace_full_callback callback, void *data,
|
|
|
|
|
const char **filename, int *lineno)
|
|
|
|
|
const char **filename, int *lineno, int *column)
|
|
|
|
|
{
|
|
|
|
|
struct function_addrs *p;
|
|
|
|
|
struct function_addrs *match;
|
|
|
|
@@ -3937,12 +3949,12 @@ report_inlined_functions (uintptr_t pc, struct function *function,
|
|
|
|
|
|
|
|
|
|
/* Report any calls inlined into this one. */
|
|
|
|
|
ret = report_inlined_functions (pc, inlined, callback, data,
|
|
|
|
|
filename, lineno);
|
|
|
|
|
filename, lineno, column);
|
|
|
|
|
if (ret != 0)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
/* Report this inlined call. */
|
|
|
|
|
ret = callback (data, pc, *filename, *lineno, inlined->name);
|
|
|
|
|
ret = callback (data, pc, *filename, *lineno, *column, inlined->name);
|
|
|
|
|
if (ret != 0)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
@@ -3950,6 +3962,7 @@ report_inlined_functions (uintptr_t pc, struct function *function,
|
|
|
|
|
it the appropriate filename and line number. */
|
|
|
|
|
*filename = inlined->caller_filename;
|
|
|
|
|
*lineno = inlined->caller_lineno;
|
|
|
|
|
*column = inlined->caller_column;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@@ -3976,6 +3989,7 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
struct function *function;
|
|
|
|
|
const char *filename;
|
|
|
|
|
int lineno;
|
|
|
|
|
int column;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
*found = 1;
|
|
|
|
@@ -4117,7 +4131,7 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
if (new_data)
|
|
|
|
|
return dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
|
|
|
|
|
data, found);
|
|
|
|
|
return callback (data, pc, NULL, 0, NULL);
|
|
|
|
|
return callback (data, pc, NULL, 0, 0, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Search for PC within this unit. */
|
|
|
|
@@ -4164,13 +4178,13 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
entry->u->abs_filename = filename;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return callback (data, pc, entry->u->abs_filename, 0, NULL);
|
|
|
|
|
return callback (data, pc, entry->u->abs_filename, 0, 0, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Search for function name within this unit. */
|
|
|
|
|
|
|
|
|
|
if (entry->u->function_addrs_count == 0)
|
|
|
|
|
return callback (data, pc, ln->filename, ln->lineno, NULL);
|
|
|
|
|
return callback (data, pc, ln->filename, ln->lineno, ln->column, NULL);
|
|
|
|
|
|
|
|
|
|
p = ((struct function_addrs *)
|
|
|
|
|
bsearch (&pc, entry->u->function_addrs,
|
|
|
|
@@ -4178,7 +4192,7 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
sizeof (struct function_addrs),
|
|
|
|
|
function_addrs_search));
|
|
|
|
|
if (p == NULL)
|
|
|
|
|
return callback (data, pc, ln->filename, ln->lineno, NULL);
|
|
|
|
|
return callback (data, pc, ln->filename, ln->lineno, ln->column, NULL);
|
|
|
|
|
|
|
|
|
|
/* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
|
|
|
|
|
sorted by low, so if pc > p->low we are at the end of a range of
|
|
|
|
@@ -4202,19 +4216,20 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
|
|
|
|
|
--p;
|
|
|
|
|
}
|
|
|
|
|
if (fmatch == NULL)
|
|
|
|
|
return callback (data, pc, ln->filename, ln->lineno, NULL);
|
|
|
|
|
return callback (data, pc, ln->filename, ln->lineno, ln->column, NULL);
|
|
|
|
|
|
|
|
|
|
function = fmatch->function;
|
|
|
|
|
|
|
|
|
|
filename = ln->filename;
|
|
|
|
|
lineno = ln->lineno;
|
|
|
|
|
column = ln->column;
|
|
|
|
|
|
|
|
|
|
ret = report_inlined_functions (pc, function, callback, data,
|
|
|
|
|
&filename, &lineno);
|
|
|
|
|
&filename, &lineno, &column);
|
|
|
|
|
if (ret != 0)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
return callback (data, pc, filename, lineno, function->name);
|
|
|
|
|
return callback (data, pc, filename, lineno, column, function->name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -4264,7 +4279,7 @@ dwarf_fileline (struct backtrace_state *state, uintptr_t pc,
|
|
|
|
|
|
|
|
|
|
/* FIXME: See if any libraries have been dlopen'ed. */
|
|
|
|
|
|
|
|
|
|
return callback (data, pc, NULL, 0, NULL);
|
|
|
|
|
return callback (data, pc, NULL, 0, 0, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Initialize our data structures from the DWARF debug info for a
|
|
|
|
|