aboutsummaryrefslogtreecommitdiff
path: root/bfd/simple.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2003-04-01 00:12:12 +0000
committerDaniel Jacobowitz <drow@false.org>2003-04-01 00:12:12 +0000
commit6e84a9068469403a0a2280e705cf3cef334afd45 (patch)
treef71a70747f666cf46df1c09d7ef131c4e6d0e1c3 /bfd/simple.c
parentb985b5ac74bb321d4bad1ee829dcb7e0b41a2da6 (diff)
downloadfsf-binutils-gdb-6e84a9068469403a0a2280e705cf3cef334afd45.zip
fsf-binutils-gdb-6e84a9068469403a0a2280e705cf3cef334afd45.tar.gz
fsf-binutils-gdb-6e84a9068469403a0a2280e705cf3cef334afd45.tar.bz2
* 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.
Diffstat (limited to 'bfd/simple.c')
-rw-r--r--bfd/simple.c92
1 files changed, 80 insertions, 12 deletions
diff --git a/bfd/simple.c b/bfd/simple.c
index 30f9be0..a91d118 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;
}