* simple.c (bfd_simple_get_relocated_section_contents): Add

parameter symbol_table.  Optionally use it instead of the symbol
	table from the bfd.  Save and restore output offsets and output
	sections  around bfd_get_relocated_section_contents.  Fix a memory
	leak.
	(simple_save_output_info, simple_restore_output_info): New
	functions.
	* bfd-in2.h: Regenerate.
	* dwarf2.c (read_abbrevs): Use
	bfd_simple_get_relocated_section_contents instead of
	bfd_get_section_contents.
	(decode_line_info): Likewise.
	(_bfd_dwarf2_find_nearest_line): Likewise.  Don't call
	find_rela_addend.
	(find_rela_addend): Remove.
	* elfxx-ia64.c (elfNN_ia64_reloc): Weaken sanity check for
	debugging sections.
	(elfNN_ia64_hash_table_create): Create the hash table with malloc,
	not bfd_zalloc.
This commit is contained in:
Daniel Jacobowitz 2003-04-01 00:12:12 +00:00
parent b985b5ac74
commit 6e84a90684
5 changed files with 130 additions and 116 deletions

View File

@ -1,3 +1,26 @@
2003-03-31 Andreas Schwab <schwab@suse.de>
Daniel Jacobowitz <drow@mvista.com>
* simple.c (bfd_simple_get_relocated_section_contents): Add
parameter symbol_table. Optionally use it instead of the symbol
table from the bfd. Save and restore output offsets and output
sections around bfd_get_relocated_section_contents. Fix a memory
leak.
(simple_save_output_info, simple_restore_output_info): New
functions.
* bfd-in2.h: Regenerate.
* dwarf2.c (read_abbrevs): Use
bfd_simple_get_relocated_section_contents instead of
bfd_get_section_contents.
(decode_line_info): Likewise.
(_bfd_dwarf2_find_nearest_line): Likewise. Don't call
find_rela_addend.
(find_rela_addend): Remove.
* elfxx-ia64.c (elfNN_ia64_reloc): Weaken sanity check for
debugging sections.
(elfNN_ia64_hash_table_create): Create the hash table with malloc,
not bfd_zalloc.
2003-03-31 David Heine <dlheine@suif.stanford.edu>
* aoutx.h (aout_link_hash_table_create): Use bfd_malloc instead of

View File

@ -4385,7 +4385,7 @@ bfd_link_split_section PARAMS ((bfd *abfd, asection *sec));
/* Extracted from simple.c. */
bfd_byte *
bfd_simple_get_relocated_section_contents PARAMS ((bfd *abfd, asection *sec, bfd_byte *outbuf));
bfd_simple_get_relocated_section_contents PARAMS ((bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table));
#ifdef __cplusplus
}

View File

@ -245,8 +245,6 @@ static bfd_boolean lookup_address_in_line_info_table
static bfd_boolean lookup_address_in_function_table
PARAMS ((struct funcinfo *, bfd_vma, struct funcinfo **, const char **));
static bfd_boolean scan_unit_for_functions PARAMS ((struct comp_unit *));
static bfd_vma find_rela_addend
PARAMS ((bfd *, asection *, bfd_size_type, asymbol**));
static struct comp_unit *parse_comp_unit
PARAMS ((bfd *, struct dwarf2_debug *, bfd_vma, unsigned int));
static bfd_boolean comp_unit_contains_address
@ -546,13 +544,11 @@ read_abbrevs (abfd, offset, stash)
}
stash->dwarf_abbrev_size = msec->_raw_size;
stash->dwarf_abbrev_buffer = (char*) bfd_alloc (abfd, msec->_raw_size);
stash->dwarf_abbrev_buffer
= bfd_simple_get_relocated_section_contents (abfd, msec, NULL,
stash->syms);
if (! stash->dwarf_abbrev_buffer)
return 0;
if (! bfd_get_section_contents (abfd, msec, stash->dwarf_abbrev_buffer,
(bfd_vma) 0, msec->_raw_size))
return 0;
}
if (offset >= stash->dwarf_abbrev_size)
@ -1023,21 +1019,15 @@ decode_line_info (unit, stash)
}
stash->dwarf_line_size = msec->_raw_size;
stash->dwarf_line_buffer = (char *) bfd_alloc (abfd, msec->_raw_size);
stash->dwarf_line_buffer
= bfd_simple_get_relocated_section_contents (abfd, msec, NULL,
stash->syms);
if (! stash->dwarf_line_buffer)
return 0;
if (! bfd_get_section_contents (abfd, msec, stash->dwarf_line_buffer,
(bfd_vma) 0, msec->_raw_size))
return 0;
/* FIXME: We ought to apply the relocs against this section before
we process it... */
}
/* Since we are using un-relocated data, it is possible to get a bad value
for the line_offset. Validate it here so that we won't get a segfault
below. */
/* It is possible to get a bad value for the line_offset. Validate
it here so that we won't get a segfault below. */
if (unit->line_offset >= stash->dwarf_line_size)
{
(*_bfd_error_handler) (_("Dwarf Error: Line offset (%lu) greater than or equal to .debug_line size (%lu)."),
@ -1529,60 +1519,6 @@ scan_unit_for_functions (unit)
return TRUE;
}
/* Look for a RELA relocation to be applied on OFFSET of section SEC,
and return the addend if such a relocation is found. Since this is
only used to find relocations referring to the .debug_abbrev
section, we make sure the relocation refers to this section, but
this is not strictly necessary, and it can probably be safely
removed if needed. However, it is important to note that this
function only returns the addend, it doesn't serve the purpose of
applying a generic relocation.
If no suitable relocation is found, or if it is not a real RELA
relocation, this function returns 0. */
static bfd_vma
find_rela_addend (abfd, sec, offset, syms)
bfd* abfd;
asection* sec;
bfd_size_type offset;
asymbol** syms;
{
long reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
arelent **relocs = NULL;
long reloc_count, relc;
if (reloc_size <= 0)
return 0;
relocs = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
if (relocs == NULL)
return 0;
reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, syms);
if (reloc_count <= 0)
{
free (relocs);
return 0;
}
for (relc = 0; relc < reloc_count; relc++)
if (relocs[relc]->address == offset
&& (*relocs[relc]->sym_ptr_ptr)->flags & BSF_SECTION_SYM
&& strcmp ((*relocs[relc]->sym_ptr_ptr)->name,
".debug_abbrev") == 0)
{
bfd_vma addend = (relocs[relc]->howto->partial_inplace
? 0 : relocs[relc]->addend);
free (relocs);
return addend;
}
free (relocs);
return 0;
}
/* Parse a DWARF2 compilation unit starting at INFO_PTR. This
includes the compilation unit header that proceeds the DIE's, but
does not include the length field that preceeds each compilation
@ -1610,7 +1546,6 @@ parse_comp_unit (abfd, stash, unit_length, offset_size)
char *info_ptr = stash->info_ptr;
char *end_ptr = info_ptr + unit_length;
bfd_size_type amt;
bfd_size_type off;
version = read_2_bytes (abfd, info_ptr);
info_ptr += 2;
@ -1619,12 +1554,6 @@ parse_comp_unit (abfd, stash, unit_length, offset_size)
abbrev_offset = read_4_bytes (abfd, info_ptr);
else
abbrev_offset = read_8_bytes (abfd, info_ptr);
/* The abbrev offset is generally a relocation pointing to
.debug_abbrev+offset. On RELA targets, we have to find the
relocation and extract the addend to obtain the actual
abbrev_offset, so do it here. */
off = info_ptr - stash->sec_info_ptr;
abbrev_offset += find_rela_addend (abfd, stash->sec, off, stash->syms);
info_ptr += offset_size;
addr_size = read_1_byte (abfd, info_ptr);
info_ptr += 1;
@ -1947,8 +1876,8 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
start = stash->info_ptr_end - stash->info_ptr;
if (! bfd_get_section_contents (abfd, msec, stash->info_ptr + start,
(bfd_vma) 0, size))
if ((bfd_simple_get_relocated_section_contents
(abfd, msec, stash->info_ptr + start, symbols)) == NULL)
continue;
stash->info_ptr_end = stash->info_ptr + start + size;
@ -1961,21 +1890,6 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
stash->syms = symbols;
}
/* FIXME: There is a problem with the contents of the
.debug_info section. The 'low' and 'high' addresses of the
comp_units are computed by relocs against symbols in the
.text segment. We need these addresses in order to determine
the nearest line number, and so we have to resolve the
relocs. There is a similar problem when the .debug_line
section is processed as well (e.g., there may be relocs
against the operand of the DW_LNE_set_address operator).
Unfortunately getting hold of the reloc information is hard...
For now, this means that disassembling object files (as
opposed to fully executables) does not always work as well as
we would like. */
/* 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)
@ -2042,10 +1956,10 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
{
if (comp_unit_contains_address (each, addr))
return comp_unit_find_nearest_line (each, addr,
filename_ptr,
functionname_ptr,
linenumber_ptr,
stash);
filename_ptr,
functionname_ptr,
linenumber_ptr,
stash);
}
else
{

View File

@ -357,6 +357,10 @@ elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
reloc->address += input_section->output_offset;
return bfd_reloc_ok;
}
if (input_section->flags & SEC_DEBUGGING)
return bfd_reloc_continue;
*error_message = "Unsupported call to elfNN_ia64_reloc";
return bfd_reloc_notsupported;
}
@ -1788,19 +1792,24 @@ elfNN_ia64_hash_table_create (abfd)
{
struct elfNN_ia64_link_hash_table *ret;
ret = bfd_zalloc (abfd, (bfd_size_type) sizeof (*ret));
ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
if (!ret)
return 0;
if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
elfNN_ia64_new_elf_hash_entry))
{
bfd_release (abfd, ret);
free (ret);
return 0;
}
if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
elfNN_ia64_new_loc_hash_entry))
return 0;
{
free (ret);
return 0;
}
return &ret->root.root;
}

View File

@ -42,8 +42,14 @@ static bfd_boolean simple_dummy_reloc_dangerous
static bfd_boolean simple_dummy_unattached_reloc
PARAMS ((struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma));
static void simple_save_output_info
PARAMS ((bfd *, asection *, PTR));
static void simple_restore_output_info
PARAMS ((bfd *, asection *, PTR));
bfd_byte * bfd_simple_get_relocated_section_contents
PARAMS ((bfd *, asection *, bfd_byte *));
PARAMS ((bfd *, asection *, bfd_byte *, asymbol **));
static bfd_boolean
simple_dummy_warning (link_info, warning, symbol, abfd, section, address)
@ -105,17 +111,48 @@ simple_dummy_unattached_reloc (link_info, name, abfd, section, address)
return TRUE;
}
struct saved_output_info
{
bfd_vma offset;
asection *section;
};
static void
simple_save_output_info (abfd, section, ptr)
bfd *abfd ATTRIBUTE_UNUSED;
asection *section;
PTR ptr;
{
struct saved_output_info *output_info = (struct saved_output_info *) ptr;
output_info[section->index].offset = section->output_offset;
output_info[section->index].section = section->output_section;
section->output_offset = 0;
section->output_section = section;
}
static void
simple_restore_output_info (abfd, section, ptr)
bfd *abfd ATTRIBUTE_UNUSED;
asection *section;
PTR ptr;
{
struct saved_output_info *output_info = (struct saved_output_info *) ptr;
section->output_offset = output_info[section->index].offset;
section->output_section = output_info[section->index].section;
}
/*
FUNCTION
bfd_simple_relocate_secton
SYNOPSIS
bfd_byte *bfd_simple_get_relocated_section_contents (bfd *abfd, asection *sec, bfd_byte *outbuf);
bfd_byte *bfd_simple_get_relocated_section_contents (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
DESCRIPTION
Returns the relocated contents of section @var{sec}. Only symbols
from @var{abfd} and the output offsets assigned to sections in
@var{abfd} are used. The result will be stored at @var{outbuf}
Returns the relocated contents of section @var{sec}. The symbols in
@var{symbol_table} will be used, or the symbols from @var{abfd} if
@var{symbol_table} is NULL. The output offsets for all sections will
be temporarily reset to 0. The result will be stored at @var{outbuf}
or allocated with @code{bfd_malloc} if @var{outbuf} is @code{NULL}.
Generally all sections in @var{abfd} should have their
@ -126,17 +163,18 @@ DESCRIPTION
*/
bfd_byte *
bfd_simple_get_relocated_section_contents (abfd, sec, outbuf)
bfd_simple_get_relocated_section_contents (abfd, sec, outbuf, symbol_table)
bfd *abfd;
asection *sec;
bfd_byte *outbuf;
asymbol **symbol_table;
{
struct bfd_link_info link_info;
struct bfd_link_order link_order;
struct bfd_link_callbacks callbacks;
bfd_byte *contents, *data;
int storage_needed;
asymbol **symbol_table;
PTR saved_offsets;
if (! (sec->flags & SEC_RELOC))
{
@ -183,11 +221,36 @@ bfd_simple_get_relocated_section_contents (abfd, sec, outbuf)
return NULL;
outbuf = data;
}
bfd_link_add_symbols (abfd, &link_info);
storage_needed = bfd_get_symtab_upper_bound (abfd);
symbol_table = (asymbol **) bfd_malloc (storage_needed);
bfd_canonicalize_symtab (abfd, symbol_table);
/* The sections in ABFD may already have output sections and offsets set.
Because this function is primarily for debug sections, and GCC uses the
knowledge that debug sections will generally have VMA 0 when emiting
relocations between DWARF-2 sections (which are supposed to be
section-relative offsets anyway), we need to reset the output offsets
to zero. We also need to arrange for section->output_section->vma plus
section->output_offset to equal section->vma, which we do by setting
section->output_section to point back to section. Save the original
output offset and output section to restore later. */
saved_offsets = malloc (sizeof (struct saved_output_info)
* abfd->section_count);
if (saved_offsets == NULL)
{
if (data)
free (data);
return NULL;
}
bfd_map_over_sections (abfd, simple_save_output_info, saved_offsets);
if (symbol_table == NULL)
{
bfd_link_add_symbols (abfd, &link_info);
storage_needed = bfd_get_symtab_upper_bound (abfd);
symbol_table = (asymbol **) bfd_malloc (storage_needed);
bfd_canonicalize_symtab (abfd, symbol_table);
}
else
storage_needed = 0;
contents = bfd_get_relocated_section_contents (abfd,
&link_info,
@ -198,6 +261,12 @@ bfd_simple_get_relocated_section_contents (abfd, sec, outbuf)
if (contents == NULL && data != NULL)
free (data);
if (storage_needed != 0)
free (symbol_table);
bfd_map_over_sections (abfd, simple_restore_output_info, saved_offsets);
free (saved_offsets);
/* Foul hack to prevent bfd_section_size aborts. This flag only controls
that macro (and the related size macros), selecting between _raw_size
and _cooked_size. Debug sections won't change size while we're only
@ -208,6 +277,5 @@ bfd_simple_get_relocated_section_contents (abfd, sec, outbuf)
bfd_link_hash_table_free (abfd, link_info.hash);
free (symbol_table);
return contents;
}