/* BFD back-end for PowerPC Microsoft Portable Executable files.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
Original version pieced together by Kim Knuttila (krk@cygnus.com)
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* Current State:
- objdump works
static struct bfd_hash_entry *ppc_coff_link_hash_newfunc
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
const char *));
-static bfd_boolean ppc_coff_link_hash_table_init
- PARAMS ((struct ppc_coff_link_hash_table *, bfd *,
- struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
- struct bfd_hash_table *,
- const char *)));
static struct bfd_link_hash_table *ppc_coff_link_hash_table_create
PARAMS ((bfd *));
static bfd_boolean coff_ppc_relocate_section
/* Initialize a PE linker hash table. */
static bfd_boolean
-ppc_coff_link_hash_table_init (table, abfd, newfunc)
- struct ppc_coff_link_hash_table *table;
- bfd *abfd;
- struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
- struct bfd_hash_table *,
- const char *));
+ppc_coff_link_hash_table_init (struct ppc_coff_link_hash_table *table,
+ bfd *abfd,
+ struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int entsize)
{
- return _bfd_coff_link_hash_table_init (&table->root, abfd, newfunc);
+ return _bfd_coff_link_hash_table_init (&table->root, abfd, newfunc, entsize);
}
/* Create a PE linker hash table. */
ret = (struct ppc_coff_link_hash_table *) bfd_malloc (amt);
if (ret == NULL)
return NULL;
- if (! ppc_coff_link_hash_table_init (ret, abfd,
- ppc_coff_link_hash_newfunc))
+ if (!ppc_coff_link_hash_table_init (ret, abfd,
+ ppc_coff_link_hash_newfunc,
+ sizeof (struct ppc_coff_link_hash_entry)))
{
free (ret);
return (struct bfd_link_hash_table *) NULL;
asection *section,
bfd *output_bfd,
char **error));
-#if 0
-static bfd_reloc_status_type ppc_reflo_reloc PARAMS ((bfd *abfd,
- arelent *reloc,
- asymbol *symbol,
- PTR data,
- asection *section,
- bfd *output_bfd,
- char **error));
-#endif
static bfd_reloc_status_type ppc_pair_reloc PARAMS ((bfd *abfd,
arelent *reloc,
asymbol *symbol,
bfd *output_bfd,
char **error));
-#if 0
-static bfd_reloc_status_type ppc_addr32nb_reloc PARAMS ((bfd *abfd,
- arelent *reloc,
- asymbol *symbol,
- PTR data,
- asection *section,
- bfd *output_bfd,
- char **error));
-#endif
static bfd_reloc_status_type ppc_section_reloc PARAMS ((bfd *abfd,
arelent *reloc,
asymbol *symbol,
&& (howto->type != IMAGE_REL_PPC_TOCREL16_DEFN) ;
}
-#if 0
-
-/* This function is in charge of performing all the ppc PE relocations
- Don't yet know if we want to do this this particular way ... (krk). */
-/* FIXME: (it is not yet enabled). */
-
-static bfd_reloc_status_type
-pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
- error_message)
- bfd *abfd;
- arelent *reloc_entry;
- asymbol *symbol_in;
- PTR data;
- asection *input_section;
- bfd *output_bfd;
- char **error_message;
-{
- /* The consth relocation comes in two parts, we have to remember
- the state between calls, in these variables. */
- static bfd_boolean part1_consth_active = FALSE;
- static unsigned long part1_consth_value;
-
- unsigned long sym_value;
- unsigned short r_type;
- unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/
-
- r_type = reloc_entry->howto->type;
-
- if (output_bfd)
- {
- /* Partial linking - do nothing. */
- reloc_entry->address += input_section->output_offset;
- return bfd_reloc_ok;
- }
-
- if (symbol_in != NULL
- && bfd_is_und_section (symbol_in->section))
- {
- /* Keep the state machine happy in case we're called again. */
- if (r_type == IMAGE_REL_PPC_REFHI)
- {
- part1_consth_active = TRUE;
- part1_consth_value = 0;
- }
- return(bfd_reloc_undefined);
- }
-
- if ((part1_consth_active) && (r_type != IMAGE_REL_PPC_PAIR))
- {
- part1_consth_active = FALSE;
- *error_message = (char *) _("Missing PAIR");
- return(bfd_reloc_dangerous);
- }
-
- sym_value = get_symbol_value(symbol_in);
-
- return(bfd_reloc_ok);
-}
-
-#endif /* 0 */
-
/* The reloc processing routine for the optimized COFF linker. */
static bfd_boolean
{
default:
(*_bfd_error_handler)
- (_("%s: unsupported relocation type 0x%02x"),
- bfd_archive_filename (input_bfd), r_type);
+ (_("%B: unsupported relocation type 0x%02x"), input_bfd, r_type);
bfd_set_error (bfd_error_bad_value);
return FALSE;
case IMAGE_REL_PPC_TOCREL16:
if ((bfd_vma) our_toc_offset >= 65535)
{
(*_bfd_error_handler)
- (_("%s: Relocation for %s of %lx exceeds Toc size limit"),
- bfd_archive_filename (input_bfd), name,
+ (_("%B: Relocation for %s of %lx exceeds Toc size limit"),
+ input_bfd, name,
(unsigned long) our_toc_offset);
bfd_set_error (bfd_error_bad_value);
return FALSE;
/* FIXME: this test is conservative. */
if ((r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN
- && (bfd_vma) our_toc_offset > toc_section->_raw_size)
+ && (bfd_vma) our_toc_offset > toc_section->size)
{
(*_bfd_error_handler)
- (_("%s: Relocation exceeds allocated TOC (%lx)"),
- bfd_archive_filename (input_bfd),
- (unsigned long) toc_section->_raw_size);
+ (_("%B: Relocation exceeds allocated TOC (%lx)"),
+ input_bfd, (unsigned long) toc_section->size);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
else
my_name = h->root.root.root.string;
- fprintf (stderr,
- _("Warning: unsupported reloc %s <file %s, section %s>\n"),
- howto->name,
- bfd_archive_filename(input_bfd),
- input_section->name);
-
- fprintf (stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n",
- rel->r_symndx, my_name, (long) rel->r_vaddr,
- (unsigned long) rel->r_vaddr);
+ (*_bfd_error_handler)
+ (_("Warning: unsupported reloc %s <file %B, section %A>\n"
+ "sym %ld (%s), r_vaddr %ld (%lx)"),
+ input_bfd, input_section, howto->name,
+ rel->r_symndx, my_name, (long) rel->r_vaddr,
+ (unsigned long) rel->r_vaddr);
}
break;
case IMAGE_REL_PPC_IMGLUE:
my_name = h->root.root.root.string;
(*_bfd_error_handler)
- (_("%s: Out of order IMGLUE reloc for %s"),
- bfd_archive_filename (input_bfd), my_name);
+ (_("%B: Out of order IMGLUE reloc for %s"), input_bfd, my_name);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
if (symndx == -1)
name = "*ABS*";
else if (h != NULL)
- name = h->root.root.root.string;
+ name = NULL;
else if (sym == NULL)
name = "*unknown*";
else if (sym->_n._n_n._n_zeroes == 0
}
if (! ((*info->callbacks->reloc_overflow)
- (info, name, howto->name,
+ (info, (h ? &h->root.root : NULL), name, howto->name,
(bfd_vma) 0, input_bfd,
input_section, rel->r_vaddr - input_section->vma)))
return FALSE;
foo = (bfd_byte *) bfd_alloc (bfd_of_toc_owner, amt);
memset(foo, test_char, (size_t) global_toc_size);
- s->_raw_size = s->_cooked_size = global_toc_size;
+ s->size = global_toc_size;
s->contents = foo;
return TRUE;
return bfd_reloc_undefined;
}
-#if 0
-
-static bfd_reloc_status_type
-ppc_reflo_reloc (abfd, reloc_entry, symbol, data,
- input_section, output_bfd, error_message)
- bfd *abfd;
- arelent *reloc_entry;
- asymbol *symbol;
- PTR data;
- asection *input_section;
- bfd *output_bfd;
- char **error_message;
-{
- UN_IMPL("REFLO");
- DUMP_RELOC("REFLO",reloc_entry);
-
- if (output_bfd == (bfd *) NULL)
- return bfd_reloc_continue;
-
- return bfd_reloc_undefined;
-}
-
-#endif
-
static bfd_reloc_status_type
ppc_pair_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message)
return bfd_reloc_ok;
}
-#if 0
-
-/* ADDR32NB : 32 bit address relative to the virtual origin.
- (On the alpha, this is always a linker generated thunk)
- (i.e. 32bit addr relative to the image base). */
-
-static bfd_reloc_status_type
-ppc_addr32nb_reloc (abfd, reloc_entry, symbol, data,
- input_section, output_bfd, error_message)
- bfd *abfd;
- arelent *reloc_entry;
- asymbol *symbol;
- PTR data;
- asection *input_section;
- bfd *output_bfd;
- char **error_message;
-{
- UN_IMPL("ADDR32NB");
- DUMP_RELOC("ADDR32NB",reloc_entry);
-
- return bfd_reloc_ok;
-}
-
-#endif
-
static bfd_reloc_status_type
ppc_secrel_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message)
#define coff_bfd_final_link ppc_bfd_coff_final_link
#ifndef COFF_IMAGE_WITH_PE
-/* FIXME: This no longer works. */
-#if 0
-#define coff_swap_sym_in_hook ppc_coff_swap_sym_in_hook
-#endif
#endif
#define SELECT_RELOC(internal, howto) {internal.r_type=howto->type;}
#include "coffcode.h"
\f
-#ifndef COFF_IMAGE_WITH_PE
-/* FIXME: This no longer works. */
-#if 0
-/* FIXME:
- What we're trying to do here is allocate a toc section (early), and attach
- it to the last bfd to be processed. This avoids the problem of having a toc
- written out before all files have been processed. This code allocates
- a toc section for every file, and records the last one seen. There are
- at least two problems with this approach:
- 1. We allocate whole bunches of toc sections that are ignored, but at
- at least we will not allocate a toc if no .toc is present.
- 2. It's not clear to me that being the last bfd read necessarily means
- that you are the last bfd closed.
- 3. Doing it on a "swap in" hook depends on when the "swap in" is called,
- and how often, etc. It's not clear to me that there isn't a hole here. */
-static void ppc_coff_swap_sym_in_hook PARAMS ((bfd *, PTR, PTR));
-
-static void
-ppc_coff_swap_sym_in_hook (abfd, ext1, in1)
- bfd *abfd;
- PTR ext1 ATTRIBUTE_UNUSED;
- PTR in1;
-{
- struct internal_syment * in = (struct internal_syment *)in1;
-
- if (bfd_of_toc_owner != 0) /* We already have a toc, so go home. */
- return;
-
- if (strcmp (in->_n._n_name, ".toc") == 0)
- {
- flagword flags;
- register asection *s;
-
- s = bfd_get_section_by_name (abfd, TOC_SECTION_NAME);
- if (s != NULL)
- return;
-
- flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ;
-
- s = bfd_make_section (abfd, TOC_SECTION_NAME);
-
- if (s == NULL
- || !bfd_set_section_flags (abfd, s, flags)
- || !bfd_set_section_alignment (abfd, s, 2))
- /* FIXME: set appropriate bfd error. */
- abort ();
-
- /* Save the bfd for later allocation. */
- bfd_of_toc_owner = abfd;
- }
-
- return;
-}
-#endif
-#endif
-
#ifndef COFF_IMAGE_WITH_PE
static bfd_boolean ppc_do_last PARAMS ((bfd *));
o->reloc_count = 0;
o->lineno_count = 0;
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
if (p->type == bfd_indirect_link_order)
{
if (info->relocatable)
o->reloc_count += sec->reloc_count;
- if (sec->_raw_size > max_contents_size)
- max_contents_size = sec->_raw_size;
+ if (sec->rawsize > max_contents_size)
+ max_contents_size = sec->rawsize;
+ if (sec->size > max_contents_size)
+ max_contents_size = sec->size;
if (sec->lineno_count > max_lineno_count)
max_lineno_count = sec->lineno_count;
if (sec->reloc_count > max_reloc_count)
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
if (p->type == bfd_indirect_link_order
&& (bfd_get_flavour (p->u.indirect.section->owner)
}
/* If we have optimized stabs strings, output them. */
- if (coff_hash_table (info)->stab_info != NULL)
+ if (coff_hash_table (info)->stab_info.stabstr != NULL)
{
if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info))
return FALSE;