summaryrefslogtreecommitdiff
path: root/bfd/coff-ppc.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/coff-ppc.c')
-rw-r--r--bfd/coff-ppc.c602
1 files changed, 264 insertions, 338 deletions
diff --git a/bfd/coff-ppc.c b/bfd/coff-ppc.c
index f0c82a6dfa..067f2b6587 100644
--- a/bfd/coff-ppc.c
+++ b/bfd/coff-ppc.c
@@ -1,6 +1,6 @@
/* BFD back-end for PowerPC Microsoft Portable Executable files.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002
+ 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Original version pieced together by Kim Knuttila (krk@cygnus.com)
@@ -9,30 +9,29 @@
coff files, in particular, those for the rs/6000, alpha, mips, and
intel backends, and the PE work for the arm.
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-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. */
+ 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. */
/* Current State:
- objdump works
- relocs generated by gas
- ld will link files, but they do not run.
- dlltool will not produce correct output in some .reloc cases, and will
- not produce the right glue code for dll function calls.
-*/
+ not produce the right glue code for dll function calls. */
#include "bfd.h"
#include "sysdep.h"
@@ -58,15 +57,15 @@ extern bfd_boolean ppc_bfd_coff_final_link
PARAMS ((bfd *, struct bfd_link_info *));
extern void dump_toc PARAMS ((PTR));
-/* The toc is a set of bfd_vma fields. We use the fact that valid */
-/* addresses are even (i.e. the bit representing "1" is off) to allow */
-/* us to encode a little extra information in the field */
-/* - Unallocated addresses are intialized to 1. */
-/* - Allocated addresses are even numbers. */
-/* The first time we actually write a reference to the toc in the bfd, */
-/* we want to record that fact in a fixup file (if it is asked for), so */
-/* we keep track of whether or not an address has been written by marking */
-/* the low order bit with a "1" upon writing */
+/* The toc is a set of bfd_vma fields. We use the fact that valid
+ addresses are even (i.e. the bit representing "1" is off) to allow
+ us to encode a little extra information in the field
+ - Unallocated addresses are initialized to 1.
+ - Allocated addresses are even numbers.
+ The first time we actually write a reference to the toc in the bfd,
+ we want to record that fact in a fixup file (if it is asked for), so
+ we keep track of whether or not an address has been written by marking
+ the low order bit with a "1" upon writing. */
#define SET_UNALLOCATED(x) ((x) = 1)
#define IS_UNALLOCATED(x) ((x) == 1)
@@ -75,10 +74,10 @@ extern void dump_toc PARAMS ((PTR));
#define MARK_AS_WRITTEN(x) ((x) |= 1)
#define MAKE_ADDR_AGAIN(x) ((x) &= ~1)
-/* Turn on this check if you suspect something amiss in the hash tables */
+/* Turn on this check if you suspect something amiss in the hash tables. */
#ifdef DEBUG_HASH
-/* Need a 7 char string for an eye catcher */
+/* Need a 7 char string for an eye catcher. */
#define EYE "krkjunk"
#define HASH_CHECK_DCL char eye_catcher[8];
@@ -101,17 +100,17 @@ extern void dump_toc PARAMS ((PTR));
#endif
/* In order not to add an int to every hash table item for every coff
- linker, we define our own hash table, derived from the coff one */
+ linker, we define our own hash table, derived from the coff one. */
/* PE linker hash table entries. */
struct ppc_coff_link_hash_entry
{
- struct coff_link_hash_entry root; /* First entry, as required */
+ struct coff_link_hash_entry root; /* First entry, as required. */
/* As we wonder around the relocs, we'll keep the assigned toc_offset
- here */
- bfd_vma toc_offset; /* Our addition, as required */
+ here. */
+ bfd_vma toc_offset; /* Our addition, as required. */
int symbol_is_glue;
unsigned long int glue_insn;
@@ -122,7 +121,7 @@ struct ppc_coff_link_hash_entry
struct ppc_coff_link_hash_table
{
- struct coff_link_hash_table root; /* First entry, as required */
+ struct coff_link_hash_table root; /* First entry, as required. */
};
static struct bfd_hash_entry *ppc_coff_link_hash_newfunc
@@ -172,11 +171,11 @@ ppc_coff_link_hash_newfunc (entry, table, string)
if (ret)
{
/* Initialize the local fields. */
- SET_UNALLOCATED(ret->toc_offset);
+ SET_UNALLOCATED (ret->toc_offset);
ret->symbol_is_glue = 0;
ret->glue_insn = 0;
- HASH_CHECK_INIT(ret);
+ HASH_CHECK_INIT (ret);
}
return (struct bfd_hash_entry *) ret;
@@ -216,13 +215,13 @@ ppc_coff_link_hash_table_create (abfd)
return &ret->root.root;
}
-/* Now, tailor coffcode.h to use our hash stuff */
+/* Now, tailor coffcode.h to use our hash stuff. */
#define coff_bfd_link_hash_table_create ppc_coff_link_hash_table_create
-/* The nt loader points the toc register to &toc + 32768, in order to */
-/* use the complete range of a 16-bit displacement. We have to adjust */
-/* for this when we fix up loads displaced off the toc reg. */
+/* The nt loader points the toc register to &toc + 32768, in order to
+ use the complete range of a 16-bit displacement. We have to adjust
+ for this when we fix up loads displaced off the toc reg. */
#define TOC_LOAD_ADJUSTMENT (-32768)
#define TOC_SECTION_NAME ".private.toc"
@@ -234,7 +233,7 @@ ppc_coff_link_hash_table_create (abfd)
from smaller values. Start with zero, widen, *then* decrement. */
#define MINUS_ONE (((bfd_vma)0) - 1)
-/* these should definitely go in a header file somewhere... */
+/* These should definitely go in a header file somewhere... */
/* NOP */
#define IMAGE_REL_PPC_ABSOLUTE 0x0000
@@ -284,31 +283,31 @@ ppc_coff_link_hash_table_create (abfd)
/* va of containing section (limited to 16 bits) */
#define IMAGE_REL_PPC_SECREL16 0x000F
-/* stuff to handle immediate data when the number of bits in the */
-/* data is greater than the number of bits in the immediate field */
-/* We need to do (usually) 32 bit arithmetic on 16 bit chunks */
+/* Stuff to handle immediate data when the number of bits in the
+ data is greater than the number of bits in the immediate field
+ We need to do (usually) 32 bit arithmetic on 16 bit chunks. */
#define IMAGE_REL_PPC_REFHI 0x0010
#define IMAGE_REL_PPC_REFLO 0x0011
#define IMAGE_REL_PPC_PAIR 0x0012
-/* This is essentially the same as tocrel16, with TOCDEFN assumed */
+/* This is essentially the same as tocrel16, with TOCDEFN assumed. */
#define IMAGE_REL_PPC_TOCREL16_DEFN 0x0013
-/* Flag bits in IMAGE_RELOCATION.TYPE */
+/* Flag bits in IMAGE_RELOCATION.TYPE. */
-/* subtract reloc value rather than adding it */
+/* Subtract reloc value rather than adding it. */
#define IMAGE_REL_PPC_NEG 0x0100
-/* fix branch prediction bit to predict branch taken */
+/* Fix branch prediction bit to predict branch taken. */
#define IMAGE_REL_PPC_BRTAKEN 0x0200
-/* fix branch prediction bit to predict branch not taken */
+/* Fix branch prediction bit to predict branch not taken. */
#define IMAGE_REL_PPC_BRNTAKEN 0x0400
-/* toc slot defined in file (or, data in toc) */
+/* TOC slot defined in file (or, data in toc). */
#define IMAGE_REL_PPC_TOCDEFN 0x0800
-/* masks to isolate above values in IMAGE_RELOCATION.Type */
+/* Masks to isolate above values in IMAGE_RELOCATION.Type. */
#define IMAGE_REL_PPC_TYPEMASK 0x00FF
#define IMAGE_REL_PPC_FLAGMASK 0x0F00
@@ -317,7 +316,7 @@ ppc_coff_link_hash_table_create (abfd)
#define EXTRACT_JUNK(x) \
((x) & ~(IMAGE_REL_PPC_TYPEMASK | IMAGE_REL_PPC_FLAGMASK))
-/* static helper functions to make relocation work */
+/* Static helper functions to make relocation work. */
/* (Work In Progress) */
static bfd_reloc_status_type ppc_refhi_reloc PARAMS ((bfd *abfd,
@@ -389,41 +388,36 @@ static bfd_boolean in_reloc_p PARAMS((bfd *abfd, reloc_howto_type *howto));
/* FIXME: It'll take a while to get through all of these. I only need a few to
get us started, so those I'll make sure work. Those marked FIXME are either
- completely unverified or have a specific unknown marked in the comment */
-
-/*---------------------------------------------------------------------------*/
-/* */
-/* Relocation entries for Windows/NT on PowerPC. */
-/* */
-/* From the document "" we find the following listed as used relocs: */
-/* */
-/* ABSOLUTE : The noop */
-/* ADDR[64|32|16] : fields that hold addresses in data fields or the */
-/* 16 bit displacement field on a load/store. */
-/* ADDR[24|14] : fields that hold addresses in branch and cond */
-/* branches. These represent [26|16] bit addresses. */
-/* The low order 2 bits are preserved. */
-/* REL[24|14] : branches relative to the Instruction Address */
-/* register. These represent [26|16] bit addresses, */
-/* as before. The instruction field will be zero, and */
-/* the address of the SYM will be inserted at link time. */
-/* TOCREL16 : 16 bit displacement field referring to a slot in */
-/* toc. */
-/* TOCREL14 : 16 bit displacement field, similar to REL14 or ADDR14. */
-/* 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) */
-/* SECREL : The value is relative to the start of the section */
-/* containing the symbol. */
-/* SECTION : access to the header containing the item. Supports the */
-/* codeview debugger. */
-/* */
-/* In particular, note that the document does not indicate that the */
-/* relocations listed in the header file are used. */
-/* */
-/* */
-/* */
-/*---------------------------------------------------------------------------*/
+ completely unverified or have a specific unknown marked in the comment. */
+
+/* Relocation entries for Windows/NT on PowerPC.
+
+ From the document "" we find the following listed as used relocs:
+
+ ABSOLUTE : The noop
+ ADDR[64|32|16] : fields that hold addresses in data fields or the
+ 16 bit displacement field on a load/store.
+ ADDR[24|14] : fields that hold addresses in branch and cond
+ branches. These represent [26|16] bit addresses.
+ The low order 2 bits are preserved.
+ REL[24|14] : branches relative to the Instruction Address
+ register. These represent [26|16] bit addresses,
+ as before. The instruction field will be zero, and
+ the address of the SYM will be inserted at link time.
+ TOCREL16 : 16 bit displacement field referring to a slot in
+ toc.
+ TOCREL14 : 16 bit displacement field, similar to REL14 or ADDR14.
+ 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)
+ SECREL : The value is relative to the start of the section
+ containing the symbol.
+ SECTION : access to the header containing the item. Supports the
+ codeview debugger.
+
+ In particular, note that the document does not indicate that the
+ relocations listed in the header file are used. */
+
static reloc_howto_type ppc_coff_howto_table[] =
{
@@ -767,7 +761,7 @@ static reloc_howto_type ppc_coff_howto_table[] =
};
-/* Some really cheezy macros that can be turned on to test stderr :-) */
+/* Some really cheezy macros that can be turned on to test stderr :-) */
#ifdef DEBUG_RELOC
#define UN_IMPL(x) \
@@ -792,16 +786,14 @@ static reloc_howto_type ppc_coff_howto_table[] =
#define n_name _n._n_name
#define n_zeroes _n._n_n._n_zeroes
-#define n_offset _n._n_n._n_offset
-
-*/
+#define n_offset _n._n_n._n_offset */
-#define DUMP_RELOC2(n,r) \
-{ \
- fprintf (stderr,"%s sym %d, r_vaddr %d %s\n", \
- n, r->r_symndx, r->r_vaddr,\
+#define DUMP_RELOC2(n,r) \
+{ \
+ fprintf (stderr,"%s sym %d, r_vaddr %d %s\n", \
+ n, r->r_symndx, r->r_vaddr, \
(((r->r_type) & IMAGE_REL_PPC_TOCDEFN) == 0) \
- ?" ":" TOCDEFN" ); \
+ ?" ":" TOCDEFN" ); \
}
#else
@@ -810,14 +802,13 @@ static reloc_howto_type ppc_coff_howto_table[] =
#define DUMP_RELOC2(n,r)
#endif
-/* toc construction and management routines */
+/* TOC construction and management routines. */
/* This file is compiled twice, and these variables are defined in one
of the compilations. FIXME: This is confusing and weird. Also,
BFD should not use global variables. */
-extern bfd* bfd_of_toc_owner;
+extern bfd * bfd_of_toc_owner;
extern long int global_toc_size;
-
extern long int import_table_size;
extern long int first_thunk_address;
extern long int thunk_size;
@@ -858,7 +849,7 @@ record_toc (toc_section, our_toc_offset, cat, name)
enum ref_category cat;
const char *name;
{
- /* add this entry to our toc addr-offset-name list */
+ /* Add this entry to our toc addr-offset-name list. */
bfd_size_type amt = sizeof (struct list_ele);
struct list_ele *t = (struct list_ele *) bfd_malloc (amt);
@@ -889,7 +880,7 @@ static bfd_boolean ppc_record_toc_entry
static void ppc_mark_symbol_as_glue
PARAMS ((bfd *, int, struct internal_reloc *));
-/* record a toc offset against a symbol */
+/* Record a toc offset against a symbol. */
static bfd_boolean
ppc_record_toc_entry(abfd, info, sec, sym, toc_kind)
bfd *abfd;
@@ -914,16 +905,19 @@ ppc_record_toc_entry(abfd, info, sec, sym, toc_kind)
if (h == 0)
{
local_syms = obj_coff_local_toc_table(abfd);
+
if (local_syms == 0)
{
unsigned int i;
bfd_size_type amt;
+
/* allocate a table */
amt = (bfd_size_type) obj_raw_syment_count (abfd) * sizeof (int);
local_syms = (int *) bfd_zalloc (abfd, amt);
if (local_syms == 0)
return FALSE;
obj_coff_local_toc_table (abfd) = local_syms;
+
for (i = 0; i < obj_raw_syment_count (abfd); ++i)
{
SET_UNALLOCATED (local_syms[i]);
@@ -935,7 +929,7 @@ ppc_record_toc_entry(abfd, info, sec, sym, toc_kind)
local_syms[sym] = global_toc_size;
global_toc_size += 4;
- /* The size must fit in a 16bit displacment */
+ /* The size must fit in a 16bit displacment. */
if (global_toc_size > 65535)
{
(*_bfd_error_handler) (_("TOC overflow"));
@@ -948,14 +942,14 @@ ppc_record_toc_entry(abfd, info, sec, sym, toc_kind)
{
name = h->root.root.root.string;
- /* check to see if there's a toc slot allocated. If not, do it
- here. It will be used in relocate_section */
+ /* Check to see if there's a toc slot allocated. If not, do it
+ here. It will be used in relocate_section. */
if (IS_UNALLOCATED(h->toc_offset))
{
h->toc_offset = global_toc_size;
global_toc_size += 4;
- /* The size must fit in a 16bit displacment */
+ /* The size must fit in a 16bit displacment. */
if (global_toc_size >= 65535)
{
(*_bfd_error_handler) (_("TOC overflow"));
@@ -968,7 +962,7 @@ ppc_record_toc_entry(abfd, info, sec, sym, toc_kind)
return TRUE;
}
-/* record a toc offset against a symbol */
+/* Record a toc offset against a symbol. */
static void
ppc_mark_symbol_as_glue(abfd, sym, rel)
bfd *abfd;
@@ -1013,9 +1007,9 @@ static bfd_boolean in_reloc_p(abfd, howto)
#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) */
+/* 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,
@@ -1028,8 +1022,8 @@ pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
bfd *output_bfd;
char **error_message;
{
- /* the consth relocation comes in two parts, we have to remember
- the state between calls, in these variables */
+ /* 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;
@@ -1041,7 +1035,7 @@ pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
if (output_bfd)
{
- /* Partial linking - do nothing */
+ /* Partial linking - do nothing. */
reloc_entry->address += input_section->output_offset;
return bfd_reloc_ok;
}
@@ -1049,7 +1043,7 @@ pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
if (symbol_in != NULL
&& bfd_is_und_section (symbol_in->section))
{
- /* Keep the state machine happy in case we're called again */
+ /* Keep the state machine happy in case we're called again. */
if (r_type == IMAGE_REL_PPC_REFHI)
{
part1_consth_active = TRUE;
@@ -1151,7 +1145,7 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
sec = NULL;
val = 0;
- /* FIXME: PAIR unsupported in the following code */
+ /* FIXME: PAIR unsupported in the following code. */
if (h == NULL)
{
if (symndx == -1)
@@ -1189,7 +1183,7 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
rstat = bfd_reloc_ok;
- /* Each case must do its own relocation, setting rstat appropriately */
+ /* Each case must do its own relocation, setting rstat appropriately. */
switch (r_type)
{
default:
@@ -1217,16 +1211,15 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
}
}
- /*
- * Amazing bit tricks present. As we may have seen earlier, we
- * use the 1 bit to tell us whether or not a toc offset has been
- * allocated. Now that they've all been allocated, we will use
- * the 1 bit to tell us if we've written this particular toc
- * entry out.
- */
+ /* Amazing bit tricks present. As we may have seen earlier, we
+ use the 1 bit to tell us whether or not a toc offset has been
+ allocated. Now that they've all been allocated, we will use
+ the 1 bit to tell us if we've written this particular toc
+ entry out. */
fixit = FALSE;
if (h == 0)
- { /* it is a file local symbol */
+ {
+ /* It is a file local symbol. */
int *local_toc_table;
const char *name;
@@ -1238,15 +1231,14 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
if (IS_WRITTEN(our_toc_offset))
{
- /* if it has been written out, it is marked with the
+ /* If it has been written out, it is marked with the
1 bit. Fix up our offset, but do not write it out
- again.
- */
+ again. */
MAKE_ADDR_AGAIN(our_toc_offset);
}
else
{
- /* write out the toc entry */
+ /* Write out the toc entry. */
record_toc (toc_section, our_toc_offset, priv,
strdup (name));
@@ -1277,13 +1269,12 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
Import Address Table is mapped immediately following
the toc, some trippy library code trying for speed on
dll linkage, takes advantage of that and considers
- the IAT to be part of the toc, thus saving a load.
- */
+ the IAT to be part of the toc, thus saving a load. */
our_toc_offset = val - (toc_section->output_section->vma
+ toc_section->output_offset);
- /* The size must still fit in a 16bit displacment */
+ /* The size must still fit in a 16bit displacment. */
if ((bfd_vma) our_toc_offset >= 65535)
{
(*_bfd_error_handler)
@@ -1297,12 +1288,11 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
record_toc (toc_section, our_toc_offset, pub,
strdup (name));
}
- else if (IS_WRITTEN(our_toc_offset))
+ else if (IS_WRITTEN (our_toc_offset))
{
- /* if it has been written out, it is marked with the
+ /* If it has been written out, it is marked with the
1 bit. Fix up our offset, but do not write it out
- again.
- */
+ again. */
MAKE_ADDR_AGAIN(our_toc_offset);
}
else
@@ -1310,13 +1300,13 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
record_toc(toc_section, our_toc_offset, pub,
strdup (name));
- /* write out the toc entry */
+ /* Write out the toc entry. */
bfd_put_32 (output_bfd, val,
toc_section->contents + our_toc_offset);
MARK_AS_WRITTEN(h->toc_offset);
- /* The tricky part is that this is the address that */
- /* needs a .reloc entry for it */
+ /* The tricky part is that this is the address that
+ needs a .reloc entry for it. */
fixit = TRUE;
}
}
@@ -1324,22 +1314,21 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
if (fixit && info->base_file)
{
/* So if this is non pcrelative, and is referenced
- to a section or a common symbol, then it needs a reloc */
+ to a section or a common symbol, then it needs a reloc. */
- /* relocation to a symbol in a section which
+ /* Relocation to a symbol in a section which
isn't absolute - we output the address here
- to a file */
-
+ to a file. */
bfd_vma addr = (toc_section->output_section->vma
+ toc_section->output_offset + our_toc_offset);
- if (coff_data(output_bfd)->pe)
+ if (coff_data (output_bfd)->pe)
addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
fwrite (&addr, 1,4, (FILE *) info->base_file);
}
- /* FIXME: this test is conservative */
+ /* 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)
{
@@ -1351,21 +1340,21 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
return FALSE;
}
- /* Now we know the relocation for this toc reference */
+ /* Now we know the relocation for this toc reference. */
relocation = our_toc_offset + TOC_LOAD_ADJUSTMENT;
rstat = _bfd_relocate_contents (howto, input_bfd, relocation, loc);
}
break;
case IMAGE_REL_PPC_IFGLUE:
{
- /* To solve this, we need to know whether or not the symbol */
- /* appearing on the call instruction is a glue function or not. */
- /* A glue function must announce itself via a IMGLUE reloc, and */
- /* the reloc contains the required toc restore instruction */
-
+ /* To solve this, we need to know whether or not the symbol
+ appearing on the call instruction is a glue function or not.
+ A glue function must announce itself via a IMGLUE reloc, and
+ the reloc contains the required toc restore instruction. */
bfd_vma x;
const char *my_name;
- DUMP_RELOC2(howto->name, rel);
+
+ DUMP_RELOC2 (howto->name, rel);
if (h != 0)
{
@@ -1379,25 +1368,24 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
}
break;
case IMAGE_REL_PPC_SECREL:
- /* Unimplemented: codeview debugging information */
+ /* Unimplemented: codeview debugging information. */
/* For fast access to the header of the section
containing the item. */
break;
case IMAGE_REL_PPC_SECTION:
- /* Unimplemented: codeview debugging information */
+ /* Unimplemented: codeview debugging information. */
/* Is used to indicate that the value should be relative
to the beginning of the section that contains the
- symbol */
+ symbol. */
break;
case IMAGE_REL_PPC_ABSOLUTE:
{
const char *my_name;
+
if (h == 0)
- my_name = (syms+symndx)->_n._n_name;
+ my_name = (syms+symndx)->_n._n_name;
else
- {
- my_name = h->root.root.root.string;
- }
+ my_name = h->root.root.root.string;
fprintf (stderr,
_("Warning: unsupported reloc %s <file %s, section %s>\n"),
@@ -1413,8 +1401,9 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
case IMAGE_REL_PPC_IMGLUE:
{
/* There is nothing to do now. This reloc was noted in the first
- pass over the relocs, and the glue instruction extracted */
+ pass over the relocs, and the glue instruction extracted. */
const char *my_name;
+
if (h->symbol_is_glue == 1)
break;
my_name = h->root.root.root.string;
@@ -1429,13 +1418,15 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
case IMAGE_REL_PPC_ADDR32NB:
{
const char *name = 0;
- DUMP_RELOC2(howto->name, rel);
+
+ DUMP_RELOC2 (howto->name, rel);
if (strncmp(".idata$2",input_section->name,8) == 0 && first_thunk_address == 0)
{
- /* set magic values */
+ /* Set magic values. */
int idata5offset;
struct coff_link_hash_entry *myh;
+
myh = coff_link_hash_lookup (coff_hash_table (info),
"__idata5_magic__",
FALSE, FALSE, TRUE);
@@ -1457,7 +1448,8 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
}
if (h == 0)
- { /* it is a file local symbol */
+ {
+ /* It is a file local symbol. */
sym = syms + symndx;
name = sym->_n._n_name;
}
@@ -1466,11 +1458,11 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
char *target = 0;
name = h->root.root.root.string;
- if (strcmp(".idata$2", name) == 0)
+ if (strcmp (".idata$2", name) == 0)
target = "__idata2_magic__";
- else if (strcmp(".idata$4", name) == 0)
+ else if (strcmp (".idata$4", name) == 0)
target = "__idata4_magic__";
- else if (strcmp(".idata$5", name) == 0)
+ else if (strcmp (".idata$5", name) == 0)
target = "__idata5_magic__";
if (target != 0)
@@ -1514,10 +1506,10 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
}
rstat = _bfd_relocate_contents (howto,
- input_bfd,
- val -
- pe_data(output_bfd)->pe_opthdr.ImageBase,
- loc);
+ input_bfd,
+ val -
+ pe_data (output_bfd)->pe_opthdr.ImageBase,
+ loc);
}
break;
@@ -1542,24 +1534,23 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
break;
}
- if ( info->base_file )
+ if (info->base_file)
{
/* So if this is non pcrelative, and is referenced
- to a section or a common symbol, then it needs a reloc */
- if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
+ to a section or a common symbol, then it needs a reloc. */
+ if (sym && pe_data(output_bfd)->in_reloc_p (output_bfd, howto))
{
- /* relocation to a symbol in a section which
+ /* Relocation to a symbol in a section which
isn't absolute - we output the address here
- to a file */
+ to a file. */
bfd_vma addr = rel->r_vaddr
- input_section->vma
+ input_section->output_offset
+ input_section->output_section->vma;
- if (coff_data(output_bfd)->pe)
- {
- addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
- }
+ if (coff_data (output_bfd)->pe)
+ addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
+
fwrite (&addr, 1,4, (FILE *) info->base_file);
}
}
@@ -1595,12 +1586,9 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
(info, name, howto->name,
(bfd_vma) 0, input_bfd,
input_section, rel->r_vaddr - input_section->vma)))
- {
- return FALSE;
- }
+ return FALSE;
}
}
-
}
return TRUE;
@@ -1686,21 +1674,17 @@ ppc_allocate_toc_section (info)
bfd_size_type amt;
static char test_char = '1';
- if ( global_toc_size == 0 ) /* FIXME: does this get me in trouble? */
+ if ( global_toc_size == 0 ) /* FIXME: does this get me in trouble? */
return TRUE;
if (bfd_of_toc_owner == 0)
- {
- /* No toc owner? Something is very wrong. */
- abort ();
- }
+ /* No toc owner? Something is very wrong. */
+ abort ();
s = bfd_get_section_by_name ( bfd_of_toc_owner , TOC_SECTION_NAME);
if (s == NULL)
- {
- /* No toc section? Something is very wrong. */
- abort ();
- }
+ /* No toc section? Something is very wrong. */
+ abort ();
amt = global_toc_size;
foo = (bfd_byte *) bfd_alloc (bfd_of_toc_owner, amt);
@@ -1720,58 +1704,55 @@ ppc_process_before_allocation (abfd, info)
asection *sec;
struct internal_reloc *i, *rel;
- /* here we have a bfd that is to be included on the link. We have a hook
+ /* Here we have a bfd that is to be included on the link. We have a hook
to do reloc rummaging, before section sizes are nailed down. */
+ _bfd_coff_get_external_symbols (abfd);
- _bfd_coff_get_external_symbols(abfd);
-
- /* rummage around all the relocs and map the toc */
+ /* Rummage around all the relocs and map the toc. */
sec = abfd->sections;
if (sec == 0)
- {
- return TRUE;
- }
+ return TRUE;
for (; sec != 0; sec = sec->next)
- {
- if (sec->reloc_count == 0)
- continue;
+ {
+ if (sec->reloc_count == 0)
+ continue;
- /* load the relocs */
- /* FIXME: there may be a storage leak here */
- i=_bfd_coff_read_internal_relocs(abfd,sec,1,0,0,0);
+ /* load the relocs */
+ /* FIXME: there may be a storage leak here */
+ i=_bfd_coff_read_internal_relocs(abfd,sec,1,0,0,0);
- if (i == 0)
- abort ();
+ if (i == 0)
+ abort ();
- for (rel=i;rel<i+sec->reloc_count;++rel)
- {
- unsigned short r_type = EXTRACT_TYPE (rel->r_type);
- unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
- bfd_boolean ok = TRUE;
+ for (rel = i; rel < i + sec->reloc_count; ++rel)
+ {
+ unsigned short r_type = EXTRACT_TYPE (rel->r_type);
+ unsigned short r_flags = EXTRACT_FLAGS (rel->r_type);
+ bfd_boolean ok = TRUE;
- DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
+ DUMP_RELOC2 (ppc_coff_howto_table[r_type].name, rel);
- switch(r_type)
- {
- case IMAGE_REL_PPC_TOCREL16:
- /* if TOCDEFN is on, ignore as someone else has allocated the
- toc entry */
- if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN )
- ok = ppc_record_toc_entry(abfd, info, sec,
- rel->r_symndx, default_toc);
- if (!ok)
- return FALSE;
- break;
- case IMAGE_REL_PPC_IMGLUE:
- ppc_mark_symbol_as_glue(abfd, rel->r_symndx, rel);
- break;
- default:
- break;
- }
- }
- }
+ switch(r_type)
+ {
+ case IMAGE_REL_PPC_TOCREL16:
+ /* If TOCDEFN is on, ignore as someone else has allocated the
+ toc entry. */
+ if ((r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN)
+ ok = ppc_record_toc_entry(abfd, info, sec,
+ rel->r_symndx, default_toc);
+ if (!ok)
+ return FALSE;
+ break;
+ case IMAGE_REL_PPC_IMGLUE:
+ ppc_mark_symbol_as_glue (abfd, rel->r_symndx, rel);
+ break;
+ default:
+ break;
+ }
+ }
+ }
return TRUE;
}
@@ -1779,13 +1760,8 @@ ppc_process_before_allocation (abfd, info)
#endif
static bfd_reloc_status_type
-ppc_refhi_reloc (abfd,
- reloc_entry,
- symbol,
- data,
- input_section,
- output_bfd,
- error_message)
+ppc_refhi_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
bfd *abfd ATTRIBUTE_UNUSED;
arelent *reloc_entry ATTRIBUTE_UNUSED;
asymbol *symbol ATTRIBUTE_UNUSED;
@@ -1806,13 +1782,8 @@ ppc_refhi_reloc (abfd,
#if 0
static bfd_reloc_status_type
-ppc_reflo_reloc (abfd,
- reloc_entry,
- symbol,
- data,
- input_section,
- output_bfd,
- error_message)
+ppc_reflo_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol;
@@ -1833,13 +1804,8 @@ ppc_reflo_reloc (abfd,
#endif
static bfd_reloc_status_type
-ppc_pair_reloc (abfd,
- reloc_entry,
- symbol,
- data,
- input_section,
- output_bfd,
- error_message)
+ppc_pair_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
bfd *abfd ATTRIBUTE_UNUSED;
arelent *reloc_entry ATTRIBUTE_UNUSED;
asymbol *symbol ATTRIBUTE_UNUSED;
@@ -1858,13 +1824,8 @@ ppc_pair_reloc (abfd,
}
static bfd_reloc_status_type
-ppc_toc16_reloc (abfd,
- reloc_entry,
- symbol,
- data,
- input_section,
- output_bfd,
- error_message)
+ppc_toc16_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
bfd *abfd ATTRIBUTE_UNUSED;
arelent *reloc_entry ATTRIBUTE_UNUSED;
asymbol *symbol ATTRIBUTE_UNUSED;
@@ -1873,33 +1834,24 @@ ppc_toc16_reloc (abfd,
bfd *output_bfd;
char **error_message ATTRIBUTE_UNUSED;
{
- UN_IMPL("TOCREL16");
- DUMP_RELOC("TOCREL16",reloc_entry);
+ UN_IMPL ("TOCREL16");
+ DUMP_RELOC ("TOCREL16",reloc_entry);
if (output_bfd == (bfd *) NULL)
- {
- return bfd_reloc_continue;
- }
+ return bfd_reloc_continue;
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) */
-/* */
-/* */
+/* 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)
+ppc_addr32nb_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol;
@@ -1917,13 +1869,8 @@ ppc_addr32nb_reloc (abfd,
#endif
static bfd_reloc_status_type
-ppc_secrel_reloc (abfd,
- reloc_entry,
- symbol,
- data,
- input_section,
- output_bfd,
- error_message)
+ppc_secrel_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
bfd *abfd ATTRIBUTE_UNUSED;
arelent *reloc_entry ATTRIBUTE_UNUSED;
asymbol *symbol ATTRIBUTE_UNUSED;
@@ -1942,13 +1889,8 @@ ppc_secrel_reloc (abfd,
}
static bfd_reloc_status_type
-ppc_section_reloc (abfd,
- reloc_entry,
- symbol,
- data,
- input_section,
- output_bfd,
- error_message)
+ppc_section_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
bfd *abfd ATTRIBUTE_UNUSED;
arelent *reloc_entry ATTRIBUTE_UNUSED;
asymbol *symbol ATTRIBUTE_UNUSED;
@@ -1967,13 +1909,8 @@ ppc_section_reloc (abfd,
}
static bfd_reloc_status_type
-ppc_imglue_reloc (abfd,
- reloc_entry,
- symbol,
- data,
- input_section,
- output_bfd,
- error_message)
+ppc_imglue_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
bfd *abfd ATTRIBUTE_UNUSED;
arelent *reloc_entry ATTRIBUTE_UNUSED;
asymbol *symbol ATTRIBUTE_UNUSED;
@@ -1996,17 +1933,14 @@ ppc_imglue_reloc (abfd,
/* FIXME: There is a possiblity that when we read in a reloc from a file,
that there are some bits encoded in the upper portion of the
- type field. Not yet implemented.
-*/
-static void ppc_coff_rtype2howto PARAMS ((arelent *relent,
- struct internal_reloc *internal));
+ type field. Not yet implemented. */
+static void ppc_coff_rtype2howto PARAMS ((arelent *, struct internal_reloc *));
static void
ppc_coff_rtype2howto (relent, internal)
arelent *relent;
struct internal_reloc *internal;
{
-
/* We can encode one of three things in the type field, aside from the
type:
1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
@@ -2015,19 +1949,18 @@ ppc_coff_rtype2howto (relent, internal)
the branch is expected to be taken or not.
3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
For now, we just strip this stuff to find the type, and ignore it other
- than that.
- */
+ than that. */
reloc_howto_type *howto;
unsigned short r_type = EXTRACT_TYPE (internal->r_type);
unsigned short r_flags = EXTRACT_FLAGS(internal->r_type);
unsigned short junk = EXTRACT_JUNK (internal->r_type);
- /* the masking process only slices off the bottom byte for r_type. */
+ /* The masking process only slices off the bottom byte for r_type. */
if ( r_type > MAX_RELOC_INDEX )
abort ();
- /* check for absolute crap */
- if ( junk != 0 )
+ /* Check for absolute crap. */
+ if (junk != 0)
abort ();
switch(r_type)
@@ -2040,15 +1973,15 @@ ppc_coff_rtype2howto (relent, internal)
case IMAGE_REL_PPC_ADDR32NB:
case IMAGE_REL_PPC_SECTION:
case IMAGE_REL_PPC_SECREL:
- DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
+ DUMP_RELOC2 (ppc_coff_howto_table[r_type].name, internal);
howto = ppc_coff_howto_table + r_type;
break;
case IMAGE_REL_PPC_IMGLUE:
- DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
+ DUMP_RELOC2 (ppc_coff_howto_table[r_type].name, internal);
howto = ppc_coff_howto_table + r_type;
break;
case IMAGE_REL_PPC_TOCREL16:
- DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
+ DUMP_RELOC2 (ppc_coff_howto_table[r_type].name, internal);
if (r_flags & IMAGE_REL_PPC_TOCDEFN)
howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN;
else
@@ -2064,7 +1997,6 @@ ppc_coff_rtype2howto (relent, internal)
}
relent->howto = howto;
-
}
static reloc_howto_type *
@@ -2086,19 +2018,18 @@ coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
the branch is expected to be taken or not.
3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
For now, we just strip this stuff to find the type, and ignore it other
- than that.
- */
+ than that. */
- unsigned short r_type = EXTRACT_TYPE (rel->r_type);
- unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
- unsigned short junk = EXTRACT_JUNK (rel->r_type);
+ unsigned short r_type = EXTRACT_TYPE (rel->r_type);
+ unsigned short r_flags = EXTRACT_FLAGS (rel->r_type);
+ unsigned short junk = EXTRACT_JUNK (rel->r_type);
- /* the masking process only slices off the bottom byte for r_type. */
- if ( r_type > MAX_RELOC_INDEX )
+ /* The masking process only slices off the bottom byte for r_type. */
+ if (r_type > MAX_RELOC_INDEX)
abort ();
- /* check for absolute crap */
- if ( junk != 0 )
+ /* Check for absolute crap. */
+ if (junk != 0)
abort ();
switch(r_type)
@@ -2141,7 +2072,7 @@ coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
return howto;
}
-/* a cheesy little macro to make the code a little more readable */
+/* A cheesy little macro to make the code a little more readable. */
#define HOW2MAP(bfd_rtype,ppc_rtype) \
case bfd_rtype: return &ppc_coff_howto_table[ppc_rtype]
@@ -2167,7 +2098,6 @@ ppc_coff_reloc_type_lookup (abfd, code)
default:
return NULL;
}
- /*NOTREACHED*/
}
#undef HOW2MAP
@@ -2229,8 +2159,7 @@ ppc_coff_reloc_type_lookup (abfd, code)
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.
-*/
+ 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
@@ -2239,21 +2168,19 @@ ppc_coff_swap_sym_in_hook (abfd, ext1, in1)
PTR ext1 ATTRIBUTE_UNUSED;
PTR in1;
{
- struct internal_syment *in = (struct internal_syment *)in1;
+ struct internal_syment * in = (struct internal_syment *)in1;
- if (bfd_of_toc_owner != 0) /* we already have a toc, so go home */
+ if (bfd_of_toc_owner != 0) /* We already have a toc, so go home. */
return;
- if (strcmp(in->_n._n_name, ".toc") == 0)
+ if (strcmp (in->_n._n_name, ".toc") == 0)
{
flagword flags;
register asection *s;
- s = bfd_get_section_by_name ( abfd , TOC_SECTION_NAME);
+ s = bfd_get_section_by_name (abfd, TOC_SECTION_NAME);
if (s != NULL)
- {
- return;
- }
+ return;
flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ;
@@ -2262,12 +2189,10 @@ ppc_coff_swap_sym_in_hook (abfd, ext1, in1)
if (s == NULL
|| !bfd_set_section_flags (abfd, s, flags)
|| !bfd_set_section_alignment (abfd, s, 2))
- {
- /* FIXME: set appropriate bfd error */
- abort ();
- }
+ /* FIXME: set appropriate bfd error. */
+ abort ();
- /* save the bfd for later allocation */
+ /* Save the bfd for later allocation. */
bfd_of_toc_owner = abfd;
}
@@ -2297,7 +2222,7 @@ ppc_get_last()
return bfd_of_toc_owner;
}
-/* this piece of machinery exists only to guarantee that the bfd that holds
+/* This piece of machinery exists only to guarantee that the bfd that holds
the toc section is written last.
This does depend on bfd_make_section attaching a new section to the
@@ -2306,8 +2231,7 @@ ppc_get_last()
This is otherwise intended to be functionally the same as
cofflink.c:_bfd_coff_final_link(). It is specifically different only
where the POWERPC_LE_PE macro modifies the code. It is left in as a
- precise form of comment. krk@cygnus.com
-*/
+ precise form of comment. krk@cygnus.com */
/* Do the final link step. */
@@ -2382,9 +2306,9 @@ ppc_bfd_coff_final_link (abfd, info)
{
o->reloc_count = 0;
o->lineno_count = 0;
+
for (p = o->link_order_head; p != NULL; p = p->next)
{
-
if (p->type == bfd_indirect_link_order)
{
asection *sec;
@@ -2437,8 +2361,10 @@ ppc_bfd_coff_final_link (abfd, info)
amt = abfd->section_count + 1;
amt *= sizeof (struct coff_link_section_info);
finfo.section_info = (struct coff_link_section_info *) bfd_malloc (amt);
+
if (finfo.section_info == NULL)
goto error_return;
+
for (i = 0; i <= abfd->section_count; i++)
{
finfo.section_info[i].relocs = NULL;
@@ -2451,6 +2377,7 @@ ppc_bfd_coff_final_link (abfd, info)
line_filepos = rel_filepos;
linesz = bfd_coff_linesz (abfd);
max_output_reloc_count = 0;
+
for (o = abfd->sections; o != NULL; o = o->next)
{
if (o->lineno_count == 0)
@@ -2605,7 +2532,6 @@ ppc_bfd_coff_final_link (abfd, info)
#endif
/* Free up the buffers used by _bfd_coff_link_input_bfd. */
-
coff_debug_merge_hash_table_free (&finfo.debug_merge);
debug_merge_allocated = FALSE;