/* simple.c -- BFD simple client routines
- Copyright 2002
+ Copyright 2002, 2003
Free Software Foundation, Inc.
Contributed by MontaVista Software, Inc.
#include "libbfd.h"
#include "bfdlink.h"
-static boolean simple_dummy_warning
- PARAMS ((struct bfd_link_info * ATTRIBUTE_UNUSED,
- const char * ATTRIBUTE_UNUSED, const char * ATTRIBUTE_UNUSED,
- bfd * ATTRIBUTE_UNUSED, asection * ATTRIBUTE_UNUSED,
- bfd_vma ATTRIBUTE_UNUSED));
-
-static boolean simple_dummy_undefined_symbol
- PARAMS ((struct bfd_link_info * ATTRIBUTE_UNUSED,
- const char * ATTRIBUTE_UNUSED, bfd * ATTRIBUTE_UNUSED,
- asection * ATTRIBUTE_UNUSED, bfd_vma ATTRIBUTE_UNUSED,
- boolean ATTRIBUTE_UNUSED));
-
-static boolean simple_dummy_reloc_overflow
- PARAMS ((struct bfd_link_info * ATTRIBUTE_UNUSED,
- const char * ATTRIBUTE_UNUSED, const char * ATTRIBUTE_UNUSED,
- bfd_vma ATTRIBUTE_UNUSED, bfd * ATTRIBUTE_UNUSED,
- asection * ATTRIBUTE_UNUSED, bfd_vma ATTRIBUTE_UNUSED));
-
-static boolean simple_dummy_reloc_dangerous
- PARAMS ((struct bfd_link_info * ATTRIBUTE_UNUSED,
- const char * ATTRIBUTE_UNUSED, bfd * ATTRIBUTE_UNUSED,
- asection * ATTRIBUTE_UNUSED, bfd_vma ATTRIBUTE_UNUSED));
-
-static boolean simple_dummy_unattached_reloc
- PARAMS ((struct bfd_link_info * ATTRIBUTE_UNUSED,
- const char * ATTRIBUTE_UNUSED, bfd * ATTRIBUTE_UNUSED,
- asection * ATTRIBUTE_UNUSED, bfd_vma ATTRIBUTE_UNUSED));
+static bfd_boolean simple_dummy_warning
+ PARAMS ((struct bfd_link_info *, const char *, const char *, bfd *,
+ asection *, bfd_vma));
+
+static bfd_boolean simple_dummy_undefined_symbol
+ PARAMS ((struct bfd_link_info *, const char *, bfd *, asection *,
+ bfd_vma, bfd_boolean));
+
+static bfd_boolean simple_dummy_reloc_overflow
+ PARAMS ((struct bfd_link_info *, const char *, const char *, bfd_vma,
+ bfd *, asection *, bfd_vma));
+
+static bfd_boolean simple_dummy_reloc_dangerous
+ PARAMS ((struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma));
+
+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 boolean
+static bfd_boolean
simple_dummy_warning (link_info, warning, symbol, abfd, section, address)
- struct bfd_link_info *link_info;
- const char *warning;
- const char *symbol;
- bfd *abfd;
- asection *section;
- bfd_vma address;
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED;
+ const char *warning ATTRIBUTE_UNUSED;
+ const char *symbol ATTRIBUTE_UNUSED;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *section ATTRIBUTE_UNUSED;
+ bfd_vma address ATTRIBUTE_UNUSED;
{
- return true;
+ return TRUE;
}
-static boolean
+static bfd_boolean
simple_dummy_undefined_symbol (link_info, name, abfd, section, address, fatal)
- struct bfd_link_info *link_info;
- const char *name;
- bfd *abfd;
- asection *section;
- bfd_vma address;
- boolean fatal;
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED;
+ const char *name ATTRIBUTE_UNUSED;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *section ATTRIBUTE_UNUSED;
+ bfd_vma address ATTRIBUTE_UNUSED;
+ bfd_boolean fatal ATTRIBUTE_UNUSED;
{
- return true;
+ return TRUE;
}
-static boolean
+static bfd_boolean
simple_dummy_reloc_overflow (link_info, name, reloc_name, addend, abfd,
section, address)
- struct bfd_link_info *link_info;
- const char *name;
- const char *reloc_name;
- bfd_vma addend;
- bfd *abfd;
- asection *section;
- bfd_vma address;
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED;
+ const char *name ATTRIBUTE_UNUSED;
+ const char *reloc_name ATTRIBUTE_UNUSED;
+ bfd_vma addend ATTRIBUTE_UNUSED;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *section ATTRIBUTE_UNUSED;
+ bfd_vma address ATTRIBUTE_UNUSED;
{
- return true;
+ return TRUE;
}
-static boolean
+static bfd_boolean
simple_dummy_reloc_dangerous (link_info, message, abfd, section, address)
- struct bfd_link_info *link_info;
- const char *message;
- bfd *abfd;
- asection *section;
- bfd_vma address;
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED;
+ const char *message ATTRIBUTE_UNUSED;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *section ATTRIBUTE_UNUSED;
+ bfd_vma address ATTRIBUTE_UNUSED;
{
- return true;
+ return TRUE;
}
-static boolean
+static bfd_boolean
simple_dummy_unattached_reloc (link_info, name, abfd, section, address)
- struct bfd_link_info *link_info;
- const char *name;
- bfd *abfd;
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED;
+ const char *name ATTRIBUTE_UNUSED;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *section ATTRIBUTE_UNUSED;
+ bfd_vma address ATTRIBUTE_UNUSED;
+{
+ 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;
- bfd_vma address;
+ PTR ptr;
{
- return true;
+ 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;
}
/*
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
*/
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, number_of_symbols;
- asymbol **symbol_table;
+ int storage_needed;
+ PTR saved_offsets;
+
+ if (! (sec->flags & SEC_RELOC))
+ {
+ bfd_size_type size = bfd_section_size (abfd, sec);
+
+ if (outbuf == NULL)
+ contents = bfd_malloc (size);
+ else
+ contents = outbuf;
+
+ if (contents)
+ bfd_get_section_contents (abfd, sec, contents, 0, size);
+
+ return contents;
+ }
/* In order to use bfd_get_relocated_section_contents, we need
to forge some data structures that it expects. */
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);
- number_of_symbols = 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,
if (contents == NULL && data != NULL)
free (data);
+#if 0
+ /* NOTE: cagney/2003-04-05: This free, which was introduced on
+ 2003-03-31 to stop a memory leak, caused a memory corruption
+ between GDB and BFD. The problem, which is stabs specific, can
+ be identified by a bunch of failures in relocate.exp vis:
+
+ gdb.base/relocate.exp: get address of static_bar
+
+ Details of the problem can be found on the binutils@ mailing
+ list, see the discussion thread: "gdb.mi/mi-cli.exp failures". */
+ if (storage_needed != 0)
+ free (symbol_table);
+#endif
+
+ 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