summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog23
-rw-r--r--bfd/bfd-in2.h2
-rw-r--r--bfd/dwarf2.c114
-rw-r--r--bfd/elfxx-ia64.c15
-rw-r--r--bfd/simple.c92
5 files changed, 130 insertions, 116 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 13f14d49354..007d400a5d9 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 8960f66df34..51e2a2197a6 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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
}
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index 521bb716bc4..0bc94b64135 100644
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -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
{
diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c
index c42305717c6..3c8ec9e45ce 100644
--- a/bfd/elfxx-ia64.c
+++ b/bfd/elfxx-ia64.c
@@ -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;
}
diff --git a/bfd/simple.c b/bfd/simple.c
index 30f9be0d22b..a91d118e40d 100644
--- a/bfd/simple.c
+++ b/bfd/simple.c
@@ -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;
}