/* DWARF 2 support.
Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005 Free Software Foundation, Inc.
+ 2004, 2005, 2006 Free Software Foundation, Inc.
Adapted from gdb/dwarf2read.c by Gavin Koch of Cygnus Solutions
(gavin@cygnus.com).
bfd_byte *data;
};
+struct loadable_section
+{
+ asection *section;
+ bfd_vma adj_vma;
+};
+
struct dwarf2_debug
{
/* A list of all previously read comp_units. */
calling chain for subsequent calls to bfd_find_inliner_info to
use. */
struct funcinfo *inliner_chain;
+
+ /* Number of loadable sections. */
+ unsigned int loadable_section_count;
+
+ /* Array of loadable sections. */
+ struct loadable_section *loadable_sections;
};
struct arange
static bfd_uint64_t
read_address (struct comp_unit *unit, bfd_byte *buf)
{
- switch (unit->addr_size)
+ int signed_vma = get_elf_backend_data (unit->abfd)->sign_extend_vma;
+
+ if (signed_vma)
{
- case 8:
- return bfd_get_64 (unit->abfd, buf);
- case 4:
- return bfd_get_32 (unit->abfd, buf);
- case 2:
- return bfd_get_16 (unit->abfd, buf);
- default:
- abort ();
+ switch (unit->addr_size)
+ {
+ case 8:
+ return bfd_get_signed_64 (unit->abfd, buf);
+ case 4:
+ return bfd_get_signed_32 (unit->abfd, buf);
+ case 2:
+ return bfd_get_signed_16 (unit->abfd, buf);
+ default:
+ abort ();
+ }
+ }
+ else
+ {
+ switch (unit->addr_size)
+ {
+ case 8:
+ return bfd_get_64 (unit->abfd, buf);
+ case 4:
+ return bfd_get_32 (unit->abfd, buf);
+ case 2:
+ return bfd_get_16 (unit->abfd, buf);
+ default:
+ abort ();
+ }
}
}
amt *= sizeof (struct attr_abbrev);
tmp = bfd_realloc (cur_abbrev->attrs, amt);
if (tmp == NULL)
- {
- size_t i;
-
- for (i = 0; i < ABBREV_HASH_SIZE; i++)
- {
- struct abbrev_info *abbrev = abbrevs[i];
-
- while (abbrev)
- {
- free (abbrev->attrs);
- abbrev = abbrev->next;
- }
- }
- return NULL;
- }
+ {
+ size_t i;
+
+ for (i = 0; i < ABBREV_HASH_SIZE; i++)
+ {
+ struct abbrev_info *abbrev = abbrevs[i];
+
+ while (abbrev)
+ {
+ free (abbrev->attrs);
+ abbrev = abbrev->next;
+ }
+ }
+ return NULL;
+ }
cur_abbrev->attrs = tmp;
}
for the next compile unit) or if the end of the abbreviation
table is reached. */
if ((unsigned int) (abbrev_ptr - stash->dwarf_abbrev_buffer)
- >= stash->dwarf_abbrev_size)
+ >= stash->dwarf_abbrev_size)
break;
abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
char *file; /* Source location file name */
int line; /* Source location line number */
int tag;
- int nesting_level;
char *name;
struct arange arange;
asection *sec; /* Where the symbol is defined */
int line;
int tag;
char *name;
+ bfd_vma addr;
/* Where the symbol is defined */
asection *sec;
/* Is this a stack variable? */
unsigned int stack: 1;
};
+/* Return TRUE if NEW_LINE should sort after LINE. */
+
+static inline bfd_boolean
+new_line_sorts_after (struct line_info *new_line, struct line_info *line)
+{
+ return (new_line->address > line->address
+ || (new_line->address == line->address
+ && new_line->end_sequence < line->end_sequence));
+}
+
+
/* Adds a new entry to the line_info list in the line_info_table, ensuring
that the list is sorted. Note that the line_info list is sorted from
highest to lowest VMA (with possible duplicates); that is,
bfd_size_type amt = sizeof (struct line_info);
struct line_info* info = bfd_alloc (table->abfd, amt);
+ /* Set member data of 'info'. */
+ info->address = address;
+ info->line = line;
+ info->column = column;
+ info->end_sequence = end_sequence;
+
+ if (filename && filename[0])
+ {
+ info->filename = bfd_alloc (table->abfd, strlen (filename) + 1);
+ if (info->filename)
+ strcpy (info->filename, filename);
+ }
+ else
+ info->filename = NULL;
+
/* Find the correct location for 'info'. Normally we will receive
new line_info data 1) in order and 2) with increasing VMAs.
However some compilers break the rules (cf. decode_line_info) and
Note: we may receive duplicate entries from 'decode_line_info'. */
- while (1)
- if (!table->last_line
- || address >= table->last_line->address)
- {
- /* Normal case: add 'info' to the beginning of the list */
- info->prev_line = table->last_line;
- table->last_line = info;
-
- /* lcl_head: initialize to head a *possible* sequence at the end. */
- if (!table->lcl_head)
- table->lcl_head = info;
- break;
- }
- else if (!table->lcl_head->prev_line
- && table->lcl_head->address > address)
- {
- /* Abnormal but easy: lcl_head is 1) at the *end* of the line
- list and 2) the head of 'info'. */
- info->prev_line = NULL;
- table->lcl_head->prev_line = info;
- break;
- }
- else if (table->lcl_head->prev_line
- && table->lcl_head->address > address
- && address >= table->lcl_head->prev_line->address)
- {
- /* Abnormal but easy: lcl_head is 1) in the *middle* of the line
- list and 2) the head of 'info'. */
- info->prev_line = table->lcl_head->prev_line;
- table->lcl_head->prev_line = info;
- break;
- }
- else
- {
- /* Abnormal and hard: Neither 'last_line' nor 'lcl_head' are valid
- heads for 'info'. Reset 'lcl_head' and repeat. */
- struct line_info* li2 = table->last_line; /* always non-NULL */
- struct line_info* li1 = li2->prev_line;
-
- while (li1)
- {
- if (li2->address > address && address >= li1->address)
- break;
-
- li2 = li1; /* always non-NULL */
- li1 = li1->prev_line;
- }
- table->lcl_head = li2;
- }
-
- /* Set member data of 'info'. */
- info->address = address;
- info->line = line;
- info->column = column;
- info->end_sequence = end_sequence;
+ if (!table->last_line
+ || new_line_sorts_after (info, table->last_line))
+ {
+ /* Normal case: add 'info' to the beginning of the list */
+ info->prev_line = table->last_line;
+ table->last_line = info;
- if (filename && filename[0])
+ /* lcl_head: initialize to head a *possible* sequence at the end. */
+ if (!table->lcl_head)
+ table->lcl_head = info;
+ }
+ else if (!new_line_sorts_after (info, table->lcl_head)
+ && (!table->lcl_head->prev_line
+ || new_line_sorts_after (info, table->lcl_head->prev_line)))
{
- info->filename = bfd_alloc (table->abfd, strlen (filename) + 1);
- if (info->filename)
- strcpy (info->filename, filename);
+ /* Abnormal but easy: lcl_head is the head of 'info'. */
+ info->prev_line = table->lcl_head->prev_line;
+ table->lcl_head->prev_line = info;
}
else
- info->filename = NULL;
+ {
+ /* Abnormal and hard: Neither 'last_line' nor 'lcl_head' are valid
+ heads for 'info'. Reset 'lcl_head'. */
+ struct line_info* li2 = table->last_line; /* always non-NULL */
+ struct line_info* li1 = li2->prev_line;
+
+ while (li1)
+ {
+ if (!new_line_sorts_after (info, li2)
+ && new_line_sorts_after (info, li1))
+ break;
+
+ li2 = li1; /* always non-NULL */
+ li1 = li1->prev_line;
+ }
+ table->lcl_head = li2;
+ info->prev_line = table->lcl_head->prev_line;
+ table->lcl_head->prev_line = info;
+ }
}
/* Extract a fully qualified filename from a line info table.
if (file - 1 >= table->num_files)
{
- (*_bfd_error_handler)
- (_("Dwarf Error: mangled line number section (bad file number)."));
+ /* FILE == 0 means unknown. */
+ if (file)
+ (*_bfd_error_handler)
+ (_("Dwarf Error: mangled line number section (bad file number)."));
return strdup ("<unknown>");
}
unsigned int line = 1;
unsigned int column = 0;
int is_stmt = lh.default_is_stmt;
- int basic_block = 0;
int end_sequence = 0;
/* eraxxon@alumni.rice.edu: Against the DWARF2 specs, some
compilers generate address sequences that are wildly out of
order using DW_LNE_set_address (e.g. Intel C++ 6.0 compiler
for ia64-Linux). Thus, to determine the low and high
address, we must compare on every DW_LNS_copy, etc. */
- bfd_vma low_pc = 0;
+ bfd_vma low_pc = (bfd_vma) -1;
bfd_vma high_pc = 0;
- bfd_boolean low_pc_set = FALSE;
/* Decode the table. */
while (! end_sequence)
line += lh.line_base + (adj_opcode % lh.line_range);
/* Append row to matrix using current values. */
add_line_info (table, address, filename, line, column, 0);
- basic_block = 1;
- if (!low_pc_set || address < low_pc)
- {
- low_pc_set = TRUE;
- low_pc = address;
- }
+ if (address < low_pc)
+ low_pc = address;
if (address > high_pc)
high_pc = address;
}
end_sequence = 1;
add_line_info (table, address, filename, line, column,
end_sequence);
- if (!low_pc_set || address < low_pc)
- {
- low_pc_set = TRUE;
- low_pc = address;
- }
+ if (address < low_pc)
+ low_pc = address;
if (address > high_pc)
high_pc = address;
arange_add (unit->abfd, &unit->arange, low_pc, high_pc);
amt *= sizeof (struct fileinfo);
tmp = bfd_realloc (table->files, amt);
if (tmp == NULL)
- {
+ {
free (table->files);
free (table->dirs);
free (filename);
return NULL;
- }
+ }
table->files = tmp;
}
table->files[table->num_files].name = cur_file;
break;
case DW_LNS_copy:
add_line_info (table, address, filename, line, column, 0);
- basic_block = 0;
- if (!low_pc_set || address < low_pc)
- {
- low_pc_set = TRUE;
- low_pc = address;
- }
+ if (address < low_pc)
+ low_pc = address;
if (address > high_pc)
high_pc = address;
break;
is_stmt = (!is_stmt);
break;
case DW_LNS_set_basic_block:
- basic_block = 1;
break;
case DW_LNS_const_add_pc:
address += lh.minimum_instruction_length
*linenumber_ptr = each_line->line;
}
}
+ else
+ {
+ *filename_ptr = each_line->filename;
+ *linenumber_ptr = each_line->line;
+ }
}
if (addr_match && !each_line->end_sequence)
if (best_fit)
{
- struct funcinfo* curr_func = best_fit;
-
*functionname_ptr = best_fit->name;
*function_ptr = best_fit;
-
- /* If we found a match and it is a function that was inlined,
- traverse the function list looking for the function at the
- next higher scope and save a pointer to it for future use.
- Note that because of the way the DWARF info is generated, and
- the way we build the function list, the first function at the
- next higher level is the one we want. */
-
- for (each_func = best_fit -> prev_func;
- each_func && (curr_func->tag == DW_TAG_inlined_subroutine);
- each_func = each_func->prev_func)
- {
- if (each_func->nesting_level < curr_func->nesting_level)
- {
- curr_func->caller_func = each_func;
- curr_func = each_func;
- }
- }
return TRUE;
}
else
if ((!each_func->sec || each_func->sec == sec)
&& addr >= arange->low
&& addr < arange->high
+ && each_func->name
&& strcmp (name, each_func->name) == 0
&& (!best_fit
|| ((arange->high - arange->low)
static bfd_boolean
lookup_symbol_in_variable_table (struct comp_unit *unit,
asymbol *sym,
+ bfd_vma addr,
const char **filename_ptr,
unsigned int *linenumber_ptr)
{
for (each = unit->variable_table; each; each = each->prev_var)
if (each->stack == 0
+ && each->file != NULL
+ && each->name != NULL
+ && each->addr == addr
&& (!each->sec || each->sec == sec)
&& strcmp (name, each->name) == 0)
break;
}
else
{
- for (i = 0; i < abbrev->num_attrs && !name; ++i)
+ for (i = 0; i < abbrev->num_attrs; ++i)
{
info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr);
switch (attr.name)
{
case DW_AT_name:
- name = attr.u.str;
+ /* Prefer DW_AT_MIPS_linkage_name over DW_AT_name. */
+ if (name == NULL)
+ name = attr.u.str;
break;
case DW_AT_specification:
name = find_abstract_instance_name (unit, attr.u.val);
break;
+ case DW_AT_MIPS_linkage_name:
+ name = attr.u.str;
+ break;
default:
break;
}
return;
}
ranges_ptr = unit->stash->dwarf_ranges_buffer + offset;
-
+
for (;;)
{
bfd_vma low_pc;
bfd_vma high_pc;
- if (unit->offset_size == 4)
+ if (unit->addr_size == 4)
{
low_pc = read_4_bytes (unit->abfd, ranges_ptr);
ranges_ptr += 4;
if (low_pc == -1UL && high_pc != -1UL)
base_address = high_pc;
else
- arange_add (unit->abfd, arange, base_address + low_pc, base_address + high_pc);
+ arange_add (unit->abfd, arange, base_address + low_pc, base_address + high_pc);
}
}
bfd *abfd = unit->abfd;
bfd_byte *info_ptr = unit->first_child_die_ptr;
int nesting_level = 1;
+ struct funcinfo **nested_funcs;
+ int nested_funcs_size;
+
+ /* Maintain a stack of in-scope functions and inlined functions, which we
+ can use to set the caller_func field. */
+ nested_funcs_size = 32;
+ nested_funcs = bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *));
+ if (nested_funcs == NULL)
+ return FALSE;
+ nested_funcs[nesting_level] = 0;
while (nesting_level)
{
(*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."),
abbrev_number);
bfd_set_error (bfd_error_bad_value);
+ free (nested_funcs);
return FALSE;
}
bfd_size_type amt = sizeof (struct funcinfo);
func = bfd_zalloc (abfd, amt);
func->tag = abbrev->tag;
- func->nesting_level = nesting_level;
func->prev_func = unit->function_table;
unit->function_table = func;
+
+ if (func->tag == DW_TAG_inlined_subroutine)
+ for (i = nesting_level - 1; i >= 1; i--)
+ if (nested_funcs[i])
+ {
+ func->caller_func = nested_funcs[i];
+ break;
+ }
+ nested_funcs[nesting_level] = func;
}
else
{
var->prev_var = unit->variable_table;
unit->variable_table = var;
}
+
+ /* No inline function in scope at this nesting level. */
+ nested_funcs[nesting_level] = 0;
}
for (i = 0; i < abbrev->num_attrs; ++i)
break;
case DW_AT_location:
- if (var->stack)
+ switch (attr.form)
{
- switch (attr.form)
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ if (*attr.u.blk->data == DW_OP_addr)
{
- case DW_FORM_block:
- case DW_FORM_block1:
- case DW_FORM_block2:
- case DW_FORM_block4:
- if (*attr.u.blk->data == DW_OP_addr)
- var->stack = 0;
- break;
-
- default:
- break;
+ var->stack = 0;
+
+ /* Verify that DW_OP_addr is the only opcode in the
+ location, in which case the block size will be 1
+ plus the address size. */
+ /* ??? For TLS variables, gcc can emit
+ DW_OP_addr <addr> DW_OP_GNU_push_tls_address
+ which we don't handle here yet. */
+ if (attr.u.blk->size == unit->addr_size + 1U)
+ var->addr = bfd_get (unit->addr_size * 8,
+ unit->abfd,
+ attr.u.blk->data + 1);
}
+ break;
+
+ default:
+ break;
}
break;
}
if (abbrev->has_children)
- nesting_level++;
+ {
+ nesting_level++;
+
+ if (nesting_level >= nested_funcs_size)
+ {
+ struct funcinfo **tmp;
+
+ nested_funcs_size *= 2;
+ tmp = bfd_realloc (nested_funcs,
+ (nested_funcs_size
+ * sizeof (struct funcinfo *)));
+ if (tmp == NULL)
+ {
+ free (nested_funcs);
+ return FALSE;
+ }
+ nested_funcs = tmp;
+ }
+ nested_funcs[nesting_level] = 0;
+ }
}
+ free (nested_funcs);
return TRUE;
}
return unit;
}
-/* Return TRUE if UNIT contains the address given by ADDR. */
+/* Return TRUE if UNIT may contain the address given by ADDR. When
+ there are functions written entirely with inline asm statements, the
+ range info in the compilation unit header may not be correct. We
+ need to consult the line info table to see if a compilation unit
+ really contains the given address. */
static bfd_boolean
comp_unit_contains_address (struct comp_unit *unit, bfd_vma addr)
filename_ptr,
linenumber_ptr);
else
- return lookup_symbol_in_variable_table (unit, sym, filename_ptr,
+ return lookup_symbol_in_variable_table (unit, sym, addr,
+ filename_ptr,
linenumber_ptr);
}
return NULL;
}
+/* Unset vmas for loadable sections in STASH. */
+
+static void
+unset_sections (struct dwarf2_debug *stash)
+{
+ unsigned int i;
+ struct loadable_section *p;
+
+ i = stash->loadable_section_count;
+ p = stash->loadable_sections;
+ for (; i > 0; i--, p++)
+ p->section->vma = 0;
+}
+
+/* Set unique vmas for loadable sections in ABFD and save vmas in
+ STASH for unset_sections. */
+
+static bfd_boolean
+place_sections (bfd *abfd, struct dwarf2_debug *stash)
+{
+ struct loadable_section *p;
+ unsigned int i;
+
+ if (stash->loadable_section_count != 0)
+ {
+ i = stash->loadable_section_count;
+ p = stash->loadable_sections;
+ for (; i > 0; i--, p++)
+ p->section->vma = p->adj_vma;
+ }
+ else
+ {
+ asection *sect;
+ bfd_vma last_vma = 0;
+ bfd_size_type amt;
+ struct loadable_section *p;
+
+ i = 0;
+ for (sect = abfd->sections; sect != NULL; sect = sect->next)
+ {
+ bfd_size_type sz;
+
+ if (sect->vma != 0 || (sect->flags & SEC_LOAD) == 0)
+ continue;
+
+ sz = sect->rawsize ? sect->rawsize : sect->size;
+ if (sz == 0)
+ continue;
+
+ i++;
+ }
+
+ amt = i * sizeof (struct loadable_section);
+ p = (struct loadable_section *) bfd_zalloc (abfd, amt);
+ if (! p)
+ return FALSE;
+
+ stash->loadable_sections = p;
+ stash->loadable_section_count = i;
+
+ for (sect = abfd->sections; sect != NULL; sect = sect->next)
+ {
+ bfd_size_type sz;
+
+ if (sect->vma != 0 || (sect->flags & SEC_LOAD) == 0)
+ continue;
+
+ sz = sect->rawsize ? sect->rawsize : sect->size;
+ if (sz == 0)
+ continue;
+
+ p->section = sect;
+ if (last_vma != 0)
+ {
+ /* Align the new address to the current section
+ alignment. */
+ last_vma = ((last_vma
+ + ~((bfd_vma) -1 << sect->alignment_power))
+ & ((bfd_vma) -1 << sect->alignment_power));
+ sect->vma = last_vma;
+ }
+ p->adj_vma = sect->vma;
+ last_vma += sect->vma + sz;
+
+ p++;
+ }
+ }
+
+ return TRUE;
+}
+
/* The DWARF2 version of find_nearest_line. Return TRUE if the line
is found without error. ADDR_SIZE is the number of bytes in the
initial .debug_info length field and in the abbreviation offset.
struct comp_unit* each;
+ bfd_vma found = FALSE;
+
stash = *pinfo;
+
+ if (! stash)
+ {
+ bfd_size_type amt = sizeof (struct dwarf2_debug);
+
+ stash = bfd_zalloc (abfd, amt);
+ if (! stash)
+ return FALSE;
+ }
+
+ /* In a relocatable file, 2 functions may have the same address.
+ We change the section vma so that they won't overlap. */
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
+ {
+ if (! place_sections (abfd, stash))
+ return FALSE;
+ }
+
addr = offset;
if (section->output_section)
addr += section->output_section->vma + section->output_offset;
addr_size = 4;
BFD_ASSERT (addr_size == 4 || addr_size == 8);
- if (! stash)
+ if (! *pinfo)
{
bfd_size_type total_size;
asection *msec;
- bfd_size_type amt = sizeof (struct dwarf2_debug);
-
- stash = bfd_zalloc (abfd, amt);
- if (! stash)
- return FALSE;
*pinfo = stash;
/* No dwarf2 info. Note that at this point the stash
has been allocated, but contains zeros, this lets
future calls to this function fail quicker. */
- return FALSE;
+ goto done;
/* There can be more than one DWARF2 info section in a BFD these days.
Read them all in and produce one large stash. We do this in two
stash->info_ptr = bfd_alloc (abfd, total_size);
if (stash->info_ptr == NULL)
- return FALSE;
+ goto done;
stash->info_ptr_end = stash->info_ptr;
/* A null info_ptr indicates that there is no dwarf2 info
(or that an error occured while setting up the stash). */
if (! stash->info_ptr)
- return FALSE;
+ goto done;
stash->inliner_chain = NULL;
/* Check the previously read comp. units first. */
for (each = stash->all_comp_units; each; each = each->next_unit)
- if (comp_unit_contains_address (each, addr))
- return comp_unit_find_nearest_line (each, addr, filename_ptr,
- functionname_ptr, linenumber_ptr,
- stash);
+ if (comp_unit_contains_address (each, addr)
+ && comp_unit_find_nearest_line (each, addr, filename_ptr,
+ functionname_ptr,
+ linenumber_ptr, stash))
+ {
+ found = TRUE;
+ goto done;
+ }
/* Read each remaining comp. units checking each as they are read. */
while (stash->info_ptr < stash->info_ptr_end)
{
bfd_vma length;
- bfd_boolean found;
unsigned int offset_size = addr_size;
bfd_byte *info_ptr_unit = stash->info_ptr;
unit->high == 0), we need to consult the line info
table to see if a compilation unit contains the given
address. */
- if (each->arange.high > 0)
- {
- if (comp_unit_contains_address (each, addr))
- return comp_unit_find_nearest_line (each, addr,
- filename_ptr,
- functionname_ptr,
- linenumber_ptr,
- stash);
- }
- else
+ if ((each->arange.high == 0
+ || comp_unit_contains_address (each, addr))
+ && comp_unit_find_nearest_line (each, addr,
+ filename_ptr,
+ functionname_ptr,
+ linenumber_ptr,
+ stash))
{
- found = comp_unit_find_nearest_line (each, addr,
- filename_ptr,
- functionname_ptr,
- linenumber_ptr,
- stash);
- if (found)
- return TRUE;
+ found = TRUE;
+ goto done;
}
}
}
}
- return FALSE;
+done:
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
+ unset_sections (stash);
+
+ return found;
}
/* The DWARF2 version of find_line. Return TRUE if the line is found
asection *section;
- bfd_boolean found;
+ bfd_boolean found = FALSE;
section = bfd_get_section (symbol);
+ stash = *pinfo;
+
+ if (! stash)
+ {
+ bfd_size_type amt = sizeof (struct dwarf2_debug);
+
+ stash = bfd_zalloc (abfd, amt);
+ if (! stash)
+ return FALSE;
+ }
+
+ /* In a relocatable file, 2 functions may have the same address.
+ We change the section vma so that they won't overlap. */
+ if (!stash && (abfd->flags & (EXEC_P | DYNAMIC)) == 0)
+ {
+ if (! place_sections (abfd, stash))
+ return FALSE;
+ }
+
addr = symbol->value;
if (section->output_section)
addr += section->output_section->vma + section->output_offset;
addr += section->vma;
*filename_ptr = NULL;
- stash = *pinfo;
*filename_ptr = NULL;
*linenumber_ptr = 0;
- if (! stash)
+ if (! *pinfo)
{
bfd_size_type total_size;
asection *msec;
- bfd_size_type amt = sizeof (struct dwarf2_debug);
-
- stash = bfd_zalloc (abfd, amt);
- if (! stash)
- return FALSE;
*pinfo = stash;
/* No dwarf2 info. Note that at this point the stash
has been allocated, but contains zeros, this lets
future calls to this function fail quicker. */
- return FALSE;
+ goto done;
/* There can be more than one DWARF2 info section in a BFD these days.
Read them all in and produce one large stash. We do this in two
stash->info_ptr = bfd_alloc (abfd, total_size);
if (stash->info_ptr == NULL)
- return FALSE;
+ goto done;
stash->info_ptr_end = stash->info_ptr;
/* A null info_ptr indicates that there is no dwarf2 info
(or that an error occured while setting up the stash). */
if (! stash->info_ptr)
- return FALSE;
+ goto done;
stash->inliner_chain = NULL;
found = comp_unit_find_line (each, symbol, addr, filename_ptr,
linenumber_ptr, stash);
if (found)
- return found;
+ goto done;
}
/* The DWARF2 spec says that the initial length field, and the
linenumber_ptr,
stash));
if (found)
- return TRUE;
+ goto done;
}
}
}
- return FALSE;
+done:
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
+ unset_sections (stash);
+
+ return found;
}
bfd_boolean
size_t i;
for (i = 0; i < ABBREV_HASH_SIZE; i++)
- {
- struct abbrev_info *abbrev = abbrevs[i];
+ {
+ struct abbrev_info *abbrev = abbrevs[i];
- while (abbrev)
- {
- free (abbrev->attrs);
- abbrev = abbrev->next;
- }
- }
+ while (abbrev)
+ {
+ free (abbrev->attrs);
+ abbrev = abbrev->next;
+ }
+ }
if (each->line_table)
- {
- free (each->line_table->dirs);
- free (each->line_table->files);
- }
+ {
+ free (each->line_table->dirs);
+ free (each->line_table->files);
+ }
}
free (stash->dwarf_abbrev_buffer);