dwarf.c (struct unit): Add filename and abs_filename fields.

* dwarf.c (struct unit): Add filename and abs_filename fields.
	(build_address_map): Set new fields when reading unit.
	(dwarf_lookup_pc): If we don't find an entry in the line table,
	just return the main file name.

From-SVN: r195257
This commit is contained in:
Ian Lance Taylor 2013-01-17 01:20:28 +00:00 committed by Ian Lance Taylor
parent 2a23fddef5
commit 6b514c5361
2 changed files with 58 additions and 2 deletions

View File

@ -1,3 +1,10 @@
2013-01-16 Ian Lance Taylor <iant@google.com>
* dwarf.c (struct unit): Add filename and abs_filename fields.
(build_address_map): Set new fields when reading unit.
(dwarf_lookup_pc): If we don't find an entry in the line table,
just return the main file name.
2013-01-14 Richard Sandiford <rdsandiford@googlemail.com> 2013-01-14 Richard Sandiford <rdsandiford@googlemail.com>
Update copyright years. Update copyright years.

View File

@ -283,8 +283,12 @@ struct unit
int addrsize; int addrsize;
/* Offset into line number information. */ /* Offset into line number information. */
off_t lineoff; off_t lineoff;
/* Primary source file. */
const char *filename;
/* Compilation command working directory. */ /* Compilation command working directory. */
const char *comp_dir; const char *comp_dir;
/* Absolute file name, only set if needed. */
const char *abs_filename;
/* The abbreviations for this unit. */ /* The abbreviations for this unit. */
struct abbrevs abbrevs; struct abbrevs abbrevs;
@ -1288,6 +1292,7 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
int have_ranges; int have_ranges;
uint64_t lineoff; uint64_t lineoff;
int have_lineoff; int have_lineoff;
const char *filename;
const char *comp_dir; const char *comp_dir;
if (info.reported_underflow) if (info.reported_underflow)
@ -1346,6 +1351,7 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
have_ranges = 0; have_ranges = 0;
lineoff = 0; lineoff = 0;
have_lineoff = 0; have_lineoff = 0;
filename = NULL;
comp_dir = NULL; comp_dir = NULL;
for (i = 0; i < abbrev->num_attrs; ++i) for (i = 0; i < abbrev->num_attrs; ++i)
{ {
@ -1394,6 +1400,10 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
have_lineoff = 1; have_lineoff = 1;
} }
break; break;
case DW_AT_name:
if (val.encoding == ATTR_VAL_STRING)
filename = val.u.string;
break;
case DW_AT_comp_dir: case DW_AT_comp_dir:
if (val.encoding == ATTR_VAL_STRING) if (val.encoding == ATTR_VAL_STRING)
comp_dir = val.u.string; comp_dir = val.u.string;
@ -1421,7 +1431,9 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
u->version = version; u->version = version;
u->is_dwarf64 = is_dwarf64; u->is_dwarf64 = is_dwarf64;
u->addrsize = addrsize; u->addrsize = addrsize;
u->filename = filename;
u->comp_dir = comp_dir; u->comp_dir = comp_dir;
u->abs_filename = NULL;
u->lineoff = lineoff; u->lineoff = lineoff;
u->abbrevs = abbrevs; u->abbrevs = abbrevs;
memset (&abbrevs, 0, sizeof abbrevs); memset (&abbrevs, 0, sizeof abbrevs);
@ -2701,8 +2713,45 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
sizeof (struct line), line_search); sizeof (struct line), line_search);
if (ln == NULL) if (ln == NULL)
{ {
error_callback (data, "inconsistent DWARF line number info", 0); /* The PC is between the low_pc and high_pc attributes of the
return 0; compilation unit, but no entry in the line table covers it.
This implies that the start of the compilation unit has no
line number information. */
if (entry->u->abs_filename == NULL)
{
const char *filename;
filename = entry->u->filename;
if (filename != NULL
&& !IS_ABSOLUTE_PATH (filename)
&& entry->u->comp_dir != NULL)
{
size_t filename_len;
const char *dir;
size_t dir_len;
char *s;
filename_len = strlen (filename);
dir = entry->u->comp_dir;
dir_len = strlen (dir);
s = (char *) backtrace_alloc (state, dir_len + filename_len + 2,
error_callback, data);
if (s == NULL)
{
*found = 0;
return 0;
}
memcpy (s, dir, dir_len);
/* FIXME: Should use backslash if DOS file system. */
s[dir_len] = '/';
memcpy (s + dir_len + 1, filename, filename_len + 1);
filename = s;
}
entry->u->abs_filename = filename;
}
return callback (data, pc, entry->u->abs_filename, 0, NULL);
} }
/* Search for function name within this unit. */ /* Search for function name within this unit. */