This lot mainly cleans up `comparison between signed and unsigned' gcc
[deliverable/binutils-gdb.git] / bfd / reloc.c
index 487be0e767f6b80064918196cd7f28819e220df0..856994b6b4fdb29c9c6cf8e536237e28b5b50df4 100644 (file)
@@ -1,5 +1,6 @@
 /* BFD support for handling relocation entries.
-   Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+   Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+   Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -16,7 +17,7 @@ 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /*
 SECTION
@@ -41,6 +42,10 @@ SECTION
 @end menu
 
 */
+
+/* DO compile in the reloc_code name table from libbfd.h.  */
+#define _BFD_MAKE_TABLE_bfd_reloc_code_real
+
 #include "bfd.h"
 #include "sysdep.h"
 #include "bfdlink.h"
@@ -101,7 +106,7 @@ CODE_FRAGMENT
 .  bfd_vma addend;
 .
 .       {* Pointer to how to perform the required relocation *}
-.  const struct reloc_howto_struct *howto;
+.  reloc_howto_type *howto;
 .
 .} arelent;
 
@@ -134,7 +139,7 @@ DESCRIPTION
         type which modifies the bottom two bytes of a four byte word
         would not touch the first byte pointed to in a big endian
         world.
-       
+
        o <<addend>>
 
        The <<addend>> is a value provided by the back end to be added (!)
@@ -282,11 +287,9 @@ SUBSUBSECTION
 CODE_FRAGMENT
 .struct symbol_cache_entry;            {* Forward declaration *}
 .
-.typedef unsigned char bfd_byte;
-.
 .struct reloc_howto_struct
 .{
-.       {*  The type field has mainly a documetary use - the back end can
+.       {*  The type field has mainly a documentary use - the back end can
 .           do what it wants with it, though normally the back end's
 .           external idea of what a reloc number is stored
 .           in this field. For example, a PC relative word relocation
@@ -334,17 +337,6 @@ CODE_FRAGMENT
 .                                            bfd *output_bfd,
 .                                            char **error_message));
 .
-.
-.       {* If this field is non null, then the supplied function is
-.          called rather than the normal function. This is similar
-.         to special_function (previous), but takes different arguments,
-.          and is used for the new linking code. *}
-.  bfd_reloc_status_type (*special_function1)
-.                          PARAMS((const reloc_howto_type *howto,
-.                                  bfd *input_bfd,
-.                                  bfd_vma relocation,
-.                                  bfd_byte *location));
-.
 .       {* The textual name of the relocation type. *}
 .  char *name;
 .
@@ -376,7 +368,6 @@ CODE_FRAGMENT
 .  boolean pcrel_offset;
 .
 .};
-.typedef struct reloc_howto_struct reloc_howto_type;
 
 */
 
@@ -389,9 +380,7 @@ DESCRIPTION
 
 
 .#define HOWTO(C, R,S,B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
-.  {(unsigned)C,R,S,B, P, BI, O,SF, 0,NAME,INPLACE,MASKSRC,MASKDST,PC}
-.#define HOWTO2(C, R,S,B, P, BI, O, SF, SF1,NAME, INPLACE, MASKSRC, MASKDST, PC) \
-.  {(unsigned)C,R,S,B, P, BI, O,SF, SF1,NAME,INPLACE,MASKSRC,MASKDST,PC}
+.  {(unsigned)C,R,S,B, P, BI, O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
 
 DESCRIPTION
        And will be replaced with the totally magic way. But for the
@@ -400,6 +389,14 @@ DESCRIPTION
 
 .#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,complain_overflow_dont,FUNCTION, NAME,false,0,0,IN)
 .
+
+DESCRIPTION
+       This is used to fill in an empty howto entry in an array.
+
+.#define EMPTY_HOWTO(C) \
+.  HOWTO((C),0,0,0,false,0,complain_overflow_dont,NULL,NULL,false,0,0,false)
+.
+
 DESCRIPTION
        Helper routine to turn a symbol into a relocation value.
 
@@ -422,16 +419,16 @@ FUNCTION
        bfd_get_reloc_size
 
 SYNOPSIS
-       int bfd_get_reloc_size (const reloc_howto_type *);
+       unsigned int bfd_get_reloc_size (reloc_howto_type *);
 
 DESCRIPTION
        For a reloc_howto_type that operates on a fixed number of bytes,
        this returns the number of bytes operated on.
  */
 
-int
+unsigned int
 bfd_get_reloc_size (howto)
-     const reloc_howto_type *howto;
+     reloc_howto_type *howto;
 {
   switch (howto->size)
     {
@@ -440,6 +437,7 @@ bfd_get_reloc_size (howto)
     case 2: return 4;
     case 3: return 0;
     case 4: return 8;
+    case 8: return 16;
     case -2: return 4;
     default: abort ();
     }
@@ -460,7 +458,94 @@ DESCRIPTION
 
 */
 
+/* N_ONES produces N one bits, without overflowing machine arithmetic.  */
+#define N_ONES(n) (((((bfd_vma) 1 << ((n) - 1)) - 1) << 1) | 1)
 
+/*
+FUNCTION
+       bfd_check_overflow
+
+SYNOPSIS
+       bfd_reloc_status_type
+               bfd_check_overflow
+                       (enum complain_overflow how,
+                        unsigned int bitsize,
+                        unsigned int rightshift,
+                        unsigned int addrsize,
+                        bfd_vma relocation);
+
+DESCRIPTION
+       Perform overflow checking on @var{relocation} which has
+       @var{bitsize} significant bits and will be shifted right by
+       @var{rightshift} bits, on a machine with addresses containing
+       @var{addrsize} significant bits.  The result is either of
+       @code{bfd_reloc_ok} or @code{bfd_reloc_overflow}.
+
+*/
+
+bfd_reloc_status_type
+bfd_check_overflow (how, bitsize, rightshift, addrsize, relocation)
+     enum complain_overflow how;
+     unsigned int bitsize;
+     unsigned int rightshift;
+     unsigned int addrsize;
+     bfd_vma relocation;
+{
+  bfd_vma fieldmask, addrmask, signmask, ss, a;
+  bfd_reloc_status_type flag = bfd_reloc_ok;
+
+  a = relocation;
+
+  /* Note: BITSIZE should always be <= ADDRSIZE, but in case it's not,
+     we'll be permissive: extra bits in the field mask will
+     automatically extend the address mask for purposes of the
+     overflow check.  */
+  fieldmask = N_ONES (bitsize);
+  addrmask = N_ONES (addrsize) | fieldmask;
+
+  switch (how)
+    {
+    case complain_overflow_dont:
+      break;
+
+    case complain_overflow_signed:
+      /* If any sign bits are set, all sign bits must be set.  That
+         is, A must be a valid negative address after shifting.  */
+      a = (a & addrmask) >> rightshift;
+      signmask = ~ (fieldmask >> 1);
+      ss = a & signmask;
+      if (ss != 0 && ss != ((addrmask >> rightshift) & signmask))
+       flag = bfd_reloc_overflow;
+      break;
+
+    case complain_overflow_unsigned:
+      /* We have an overflow if the address does not fit in the field.  */
+      a = (a & addrmask) >> rightshift;
+      if ((a & ~ fieldmask) != 0)
+       flag = bfd_reloc_overflow;
+      break;
+
+    case complain_overflow_bitfield:
+      /* Bitfields are sometimes signed, sometimes unsigned.  We
+         overflow if the value has some, but not all, bits set outside
+         the field, or if it has any bits set outside the field but
+         the sign bit is not set.  */
+      a >>= rightshift;
+      if ((a & ~ fieldmask) != 0)
+       {
+         signmask = (fieldmask >> 1) + 1;
+         ss = (signmask << rightshift) - 1;
+         if ((ss | relocation) != ~ (bfd_vma) 0)
+           flag = bfd_reloc_overflow;
+       }
+      break;
+
+    default:
+      abort ();
+    }
+
+  return flag;
+}
 
 /*
 FUNCTION
@@ -507,9 +592,9 @@ bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd,
 {
   bfd_vma relocation;
   bfd_reloc_status_type flag = bfd_reloc_ok;
-  bfd_size_type addr = reloc_entry->address;
+  bfd_size_type octets = reloc_entry->address * bfd_octets_per_byte (abfd);
   bfd_vma output_base = 0;
-  const reloc_howto_type *howto = reloc_entry->howto;
+  reloc_howto_type *howto = reloc_entry->howto;
   asection *reloc_target_output_section;
   asymbol *symbol;
 
@@ -543,7 +628,8 @@ bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd,
     }
 
   /* Is the address of the relocation really within the section?  */
-  if (reloc_entry->address > input_section->_cooked_size)
+  if (reloc_entry->address > input_section->_cooked_size /
+      bfd_octets_per_byte (abfd))
     return bfd_reloc_outofrange;
 
   /* Work out which section the relocation is targetted at and the
@@ -633,6 +719,7 @@ bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd,
          /* WTF?? */
          if (abfd->xvec->flavour == bfd_target_coff_flavour
              && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0
+             && strcmp (abfd->xvec->name, "xcoff-powermac") != 0
              && strcmp (abfd->xvec->name, "coff-Intel-little") != 0
              && strcmp (abfd->xvec->name, "coff-Intel-big") != 0)
            {
@@ -728,80 +815,404 @@ space consuming.  For each target:
      machine word.
      FIXME: We should also do overflow checking on the result after
      adding in the value contained in the object file.  */
-  if (howto->complain_on_overflow != complain_overflow_dont)
+  if (howto->complain_on_overflow != complain_overflow_dont
+      && flag == bfd_reloc_ok)
+    flag = bfd_check_overflow (howto->complain_on_overflow,
+                              howto->bitsize,
+                              howto->rightshift,
+                              bfd_arch_bits_per_address (abfd),
+                              relocation);
+
+  /*
+    Either we are relocating all the way, or we don't want to apply
+    the relocation to the reloc entry (probably because there isn't
+    any room in the output format to describe addends to relocs)
+    */
+
+  /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
+     (OSF version 1.3, compiler version 3.11).  It miscompiles the
+     following program:
+
+     struct str
+     {
+       unsigned int i0;
+     } s = { 0 };
+
+     int
+     main ()
+     {
+       unsigned long x;
+
+       x = 0x100000000;
+       x <<= (unsigned long) s.i0;
+       if (x == 0)
+        printf ("failed\n");
+       else
+        printf ("succeeded (%lx)\n", x);
+     }
+     */
+
+  relocation >>= (bfd_vma) howto->rightshift;
+
+  /* Shift everything up to where it's going to be used */
+
+  relocation <<= (bfd_vma) howto->bitpos;
+
+  /* Wait for the day when all have the mask in them */
+
+  /* What we do:
+     i instruction to be left alone
+     o offset within instruction
+     r relocation offset to apply
+     S src mask
+     D dst mask
+     N ~dst mask
+     A part 1
+     B part 2
+     R result
+
+     Do this:
+     i i i i i o o o o o        from bfd_get<size>
+     and           S S S S S    to get the size offset we want
+     +   r r r r r r r r r r  to get the final value to place
+     and           D D D D D  to chop to right size
+     -----------------------
+     A A A A A
+     And this:
+     ...   i i i i i o o o o o  from bfd_get<size>
+     and   N N N N N            get instruction
+     -----------------------
+     ...   B B B B B
+
+     And then:
+     B B B B B
+     or              A A A A A
+     -----------------------
+     R R R R R R R R R R        put into bfd_put<size>
+     */
+
+#define DOIT(x) \
+  x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))
+
+  switch (howto->size)
+    {
+    case 0:
+      {
+       char x = bfd_get_8 (abfd, (char *) data + octets);
+       DOIT (x);
+       bfd_put_8 (abfd, x, (unsigned char *) data + octets);
+      }
+      break;
+
+    case 1:
+      {
+       short x = bfd_get_16 (abfd, (bfd_byte *) data + octets);
+       DOIT (x);
+       bfd_put_16 (abfd, x, (unsigned char *) data + octets);
+      }
+      break;
+    case 2:
+      {
+       long x = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+       DOIT (x);
+       bfd_put_32 (abfd, x, (bfd_byte *) data + octets);
+      }
+      break;
+    case -2:
+      {
+       long x = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+       relocation = -relocation;
+       DOIT (x);
+       bfd_put_32 (abfd, x, (bfd_byte *) data + octets);
+      }
+      break;
+
+    case -1:
+      {
+       long x = bfd_get_16 (abfd, (bfd_byte *) data + octets);
+       relocation = -relocation;
+       DOIT (x);
+       bfd_put_16 (abfd, x, (bfd_byte *) data + octets);
+      }
+      break;
+
+    case 3:
+      /* Do nothing */
+      break;
+
+    case 4:
+#ifdef BFD64
+      {
+       bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + octets);
+       DOIT (x);
+       bfd_put_64 (abfd, x, (bfd_byte *) data + octets);
+      }
+#else
+      abort ();
+#endif
+      break;
+    default:
+      return bfd_reloc_other;
+    }
+
+  return flag;
+}
+
+/*
+FUNCTION
+       bfd_install_relocation
+
+SYNOPSIS
+       bfd_reloc_status_type
+                bfd_install_relocation
+                        (bfd *abfd,
+                         arelent *reloc_entry,
+                         PTR data, bfd_vma data_start,
+                         asection *input_section,
+                        char **error_message);
+
+DESCRIPTION
+       This looks remarkably like <<bfd_perform_relocation>>, except it
+       does not expect that the section contents have been filled in.
+       I.e., it's suitable for use when creating, rather than applying
+       a relocation.
+
+       For now, this function should be considered reserved for the
+       assembler.
+
+*/
+
+
+bfd_reloc_status_type
+bfd_install_relocation (abfd, reloc_entry, data_start, data_start_offset,
+                       input_section, error_message)
+     bfd *abfd;
+     arelent *reloc_entry;
+     PTR data_start;
+     bfd_vma data_start_offset;
+     asection *input_section;
+     char **error_message;
+{
+  bfd_vma relocation;
+  bfd_reloc_status_type flag = bfd_reloc_ok;
+  bfd_size_type octets = reloc_entry->address * bfd_octets_per_byte (abfd);
+  bfd_vma output_base = 0;
+  reloc_howto_type *howto = reloc_entry->howto;
+  asection *reloc_target_output_section;
+  asymbol *symbol;
+  bfd_byte *data;
+
+  symbol = *(reloc_entry->sym_ptr_ptr);
+  if (bfd_is_abs_section (symbol->section))
     {
-      bfd_vma check;
+      reloc_entry->address += input_section->output_offset;
+      return bfd_reloc_ok;
+    }
 
-      /* Get the value that will be used for the relocation, but
-        starting at bit position zero.  */
-      if (howto->rightshift > howto->bitpos)
-       check = relocation >> (howto->rightshift - howto->bitpos);
+  /* If there is a function supplied to handle this relocation type,
+     call it.  It'll return `bfd_reloc_continue' if further processing
+     can be done.  */
+  if (howto->special_function)
+    {
+      bfd_reloc_status_type cont;
+  
+      /* XXX - The special_function calls haven't been fixed up to deal
+        with creating new relocations and section contents.  */
+      cont = howto->special_function (abfd, reloc_entry, symbol,
+                                     /* XXX - Non-portable! */
+                                     ((bfd_byte *) data_start
+                                      - data_start_offset),
+                                     input_section, abfd, error_message);
+      if (cont != bfd_reloc_continue)
+       return cont;
+    }
+
+  /* Is the address of the relocation really within the section?  */
+  if (reloc_entry->address > input_section->_cooked_size)
+    return bfd_reloc_outofrange;
+
+  /* Work out which section the relocation is targetted at and the
+     initial relocation command value.  */
+
+  /* Get symbol value.  (Common symbols are special.)  */
+  if (bfd_is_com_section (symbol->section))
+    relocation = 0;
+  else
+    relocation = symbol->value;
+
+  reloc_target_output_section = symbol->section->output_section;
+
+  /* Convert input-section-relative symbol value to absolute.  */
+  if (howto->partial_inplace == false)
+    output_base = 0;
+  else
+    output_base = reloc_target_output_section->vma;
+
+  relocation += output_base + symbol->section->output_offset;
+
+  /* Add in supplied addend.  */
+  relocation += reloc_entry->addend;
+
+  /* Here the variable relocation holds the final address of the
+     symbol we are relocating against, plus any addend.  */
+
+  if (howto->pc_relative == true)
+    {
+      /* This is a PC relative relocation.  We want to set RELOCATION
+        to the distance between the address of the symbol and the
+        location.  RELOCATION is already the address of the symbol.
+
+        We start by subtracting the address of the section containing
+        the location.
+
+        If pcrel_offset is set, we must further subtract the position
+        of the location within the section.  Some targets arrange for
+        the addend to be the negative of the position of the location
+        within the section; for example, i386-aout does this.  For
+        i386-aout, pcrel_offset is false.  Some other targets do not
+        include the position of the location; for example, m88kbcs,
+        or ELF.  For those targets, pcrel_offset is true.
+
+        If we are producing relocateable output, then we must ensure
+        that this reloc will be correctly computed when the final
+        relocation is done.  If pcrel_offset is false we want to wind
+        up with the negative of the location within the section,
+        which means we must adjust the existing addend by the change
+        in the location within the section.  If pcrel_offset is true
+        we do not want to adjust the existing addend at all.
+
+        FIXME: This seems logical to me, but for the case of
+        producing relocateable output it is not what the code
+        actually does.  I don't want to change it, because it seems
+        far too likely that something will break.  */
+
+      relocation -=
+       input_section->output_section->vma + input_section->output_offset;
+
+      if (howto->pcrel_offset == true && howto->partial_inplace == true)
+       relocation -= reloc_entry->address;
+    }
+
+  if (howto->partial_inplace == false)
+    {
+      /* This is a partial relocation, and we want to apply the relocation
+        to the reloc entry rather than the raw data. Modify the reloc
+        inplace to reflect what we now know.  */
+      reloc_entry->addend = relocation;
+      reloc_entry->address += input_section->output_offset;
+      return flag;
+    }
+  else
+    {
+      /* This is a partial relocation, but inplace, so modify the
+        reloc record a bit.
+
+        If we've relocated with a symbol with a section, change
+        into a ref to the section belonging to the symbol.  */
+
+      reloc_entry->address += input_section->output_offset;
+
+      /* WTF?? */
+      if (abfd->xvec->flavour == bfd_target_coff_flavour
+         && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0
+         && strcmp (abfd->xvec->name, "xcoff-powermac") != 0
+         && strcmp (abfd->xvec->name, "coff-Intel-little") != 0
+         && strcmp (abfd->xvec->name, "coff-Intel-big") != 0)
+       {
+#if 1
+/* For m68k-coff, the addend was being subtracted twice during
+   relocation with -r.  Removing the line below this comment
+   fixes that problem; see PR 2953.
+
+However, Ian wrote the following, regarding removing the line below,
+which explains why it is still enabled:  --djm
+
+If you put a patch like that into BFD you need to check all the COFF
+linkers.  I am fairly certain that patch will break coff-i386 (e.g.,
+SCO); see coff_i386_reloc in coff-i386.c where I worked around the
+problem in a different way.  There may very well be a reason that the
+code works as it does.
+
+Hmmm.  The first obvious point is that bfd_install_relocation should
+not have any tests that depend upon the flavour.  It's seem like
+entirely the wrong place for such a thing.  The second obvious point
+is that the current code ignores the reloc addend when producing
+relocateable output for COFF.  That's peculiar.  In fact, I really
+have no idea what the point of the line you want to remove is.
+
+A typical COFF reloc subtracts the old value of the symbol and adds in
+the new value to the location in the object file (if it's a pc
+relative reloc it adds the difference between the symbol value and the
+location).  When relocating we need to preserve that property.
+
+BFD handles this by setting the addend to the negative of the old
+value of the symbol.  Unfortunately it handles common symbols in a
+non-standard way (it doesn't subtract the old value) but that's a
+different story (we can't change it without losing backward
+compatibility with old object files) (coff-i386 does subtract the old
+value, to be compatible with existing coff-i386 targets, like SCO).
+
+So everything works fine when not producing relocateable output.  When
+we are producing relocateable output, logically we should do exactly
+what we do when not producing relocateable output.  Therefore, your
+patch is correct.  In fact, it should probably always just set
+reloc_entry->addend to 0 for all cases, since it is, in fact, going to
+add the value into the object file.  This won't hurt the COFF code,
+which doesn't use the addend; I'm not sure what it will do to other
+formats (the thing to check for would be whether any formats both use
+the addend and set partial_inplace).
+
+When I wanted to make coff-i386 produce relocateable output, I ran
+into the problem that you are running into: I wanted to remove that
+line.  Rather than risk it, I made the coff-i386 relocs use a special
+function; it's coff_i386_reloc in coff-i386.c.  The function
+specifically adds the addend field into the object file, knowing that
+bfd_install_relocation is not going to.  If you remove that line, then
+coff-i386.c will wind up adding the addend field in twice.  It's
+trivial to fix; it just needs to be done.
+
+The problem with removing the line is just that it may break some
+working code.  With BFD it's hard to be sure of anything.  The right
+way to deal with this is simply to build and test at least all the
+supported COFF targets.  It should be straightforward if time and disk
+space consuming.  For each target:
+    1) build the linker
+    2) generate some executable, and link it using -r (I would
+       probably use paranoia.o and link against newlib/libc.a, which
+       for all the supported targets would be available in
+       /usr/cygnus/progressive/H-host/target/lib/libc.a).
+    3) make the change to reloc.c
+    4) rebuild the linker
+    5) repeat step 2
+    6) if the resulting object files are the same, you have at least
+       made it no worse
+    7) if they are different you have to figure out which version is
+       right
+*/
+         relocation -= reloc_entry->addend;
+#endif
+         reloc_entry->addend = 0;
+       }
       else
-       check = relocation << (howto->bitpos - howto->rightshift);
-      switch (howto->complain_on_overflow)
        {
-       case complain_overflow_signed:
-         {
-           /* Assumes two's complement.  */
-           bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
-           bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
-
-           /* The above right shift is incorrect for a signed value.
-              Fix it up by forcing on the upper bits.  */
-           if (howto->rightshift > howto->bitpos
-               && (bfd_signed_vma) relocation < 0)
-             check |= ((bfd_vma) - 1
-                       & ~((bfd_vma) - 1
-                           >> (howto->rightshift - howto->bitpos)));
-           if ((bfd_signed_vma) check > reloc_signed_max
-               || (bfd_signed_vma) check < reloc_signed_min)
-             flag = bfd_reloc_overflow;
-         }
-         break;
-       case complain_overflow_unsigned:
-         {
-           /* Assumes two's complement.  This expression avoids
-              overflow if howto->bitsize is the number of bits in
-              bfd_vma.  */
-           bfd_vma reloc_unsigned_max =
-           (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
-
-           if ((bfd_vma) check > reloc_unsigned_max)
-             flag = bfd_reloc_overflow;
-         }
-         break;
-       case complain_overflow_bitfield:
-         {
-           /* Assumes two's complement.  This expression avoids
-              overflow if howto->bitsize is the number of bits in
-              bfd_vma.  */
-           bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
-
-           if (((bfd_vma) check & ~reloc_bits) != 0
-               && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
-             {
-               /* The above right shift is incorrect for a signed
-                  value.  See if turning on the upper bits fixes the
-                  overflow.  */
-               if (howto->rightshift > howto->bitpos
-                   && (bfd_signed_vma) relocation < 0)
-                 {
-                   check |= ((bfd_vma) - 1
-                             & ~((bfd_vma) - 1
-                                 >> (howto->rightshift - howto->bitpos)));
-                   if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
-                     flag = bfd_reloc_overflow;
-                 }
-               else
-                 flag = bfd_reloc_overflow;
-             }
-         }
-         break;
-       default:
-         abort ();
+         reloc_entry->addend = relocation;
        }
     }
 
+  /* FIXME: This overflow checking is incomplete, because the value
+     might have overflowed before we get here.  For a correct check we
+     need to compute the value in a size larger than bitsize, but we
+     can't reasonably do that for a reloc the same size as a host
+     machine word.
+     FIXME: We should also do overflow checking on the result after
+     adding in the value contained in the object file.  */
+  if (howto->complain_on_overflow != complain_overflow_dont)
+    flag = bfd_check_overflow (howto->complain_on_overflow,
+                              howto->bitsize,
+                              howto->rightshift,
+                              bfd_arch_bits_per_address (abfd),
+                              relocation);
+
   /*
     Either we are relocating all the way, or we don't want to apply
     the relocation to the reloc entry (probably because there isn't
@@ -873,38 +1284,38 @@ space consuming.  For each target:
 #define DOIT(x) \
   x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))
 
+  data = (bfd_byte *) data_start + (octets - data_start_offset);
+
   switch (howto->size)
     {
     case 0:
       {
-       char x = bfd_get_8 (abfd, (char *) data + addr);
+       char x = bfd_get_8 (abfd, (char *) data);
        DOIT (x);
-       bfd_put_8 (abfd, x, (unsigned char *) data + addr);
+       bfd_put_8 (abfd, x, (unsigned char *) data);
       }
       break;
 
     case 1:
-      if (relocation)
-       {
-         short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
-         DOIT (x);
-         bfd_put_16 (abfd, x, (unsigned char *) data + addr);
-       }
+      {
+       short x = bfd_get_16 (abfd, (bfd_byte *) data);
+       DOIT (x);
+       bfd_put_16 (abfd, x, (unsigned char *) data);
+      }
       break;
     case 2:
-      if (relocation)
-       {
-         long x = bfd_get_32 (abfd, (bfd_byte *) data + addr);
-         DOIT (x);
-         bfd_put_32 (abfd, x, (bfd_byte *) data + addr);
-       }
+      {
+       long x = bfd_get_32 (abfd, (bfd_byte *) data);
+       DOIT (x);
+       bfd_put_32 (abfd, x, (bfd_byte *) data);
+      }
       break;
     case -2:
       {
-       long x = bfd_get_32 (abfd, (bfd_byte *) data + addr);
+       long x = bfd_get_32 (abfd, (bfd_byte *) data);
        relocation = -relocation;
        DOIT (x);
-       bfd_put_32 (abfd, x, (bfd_byte *) data + addr);
+       bfd_put_32 (abfd, x, (bfd_byte *) data);
       }
       break;
 
@@ -913,16 +1324,11 @@ space consuming.  For each target:
       break;
 
     case 4:
-#ifdef BFD64
-      if (relocation)
-       {
-         bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + addr);
-         DOIT (x);
-         bfd_put_64 (abfd, x, (bfd_byte *) data + addr);
-       }
-#else
-      abort ();
-#endif
+      {
+       bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data);
+       DOIT (x);
+       bfd_put_64 (abfd, x, (bfd_byte *) data);
+      }
       break;
     default:
       return bfd_reloc_other;
@@ -937,8 +1343,9 @@ space consuming.  For each target:
    bfd_perform_relocation is so hacked up it is easier to write a new
    function than to try to deal with it.
 
-   This routine does a final relocation.  It should not be used when
-   generating relocateable output.
+   This routine does a final relocation.  Whether it is useful for a
+   relocateable link depends upon how the object format defines
+   relocations.
 
    FIXME: This routine ignores any special_function in the HOWTO,
    since the existing special_function values have been written for
@@ -955,7 +1362,7 @@ space consuming.  For each target:
 bfd_reloc_status_type
 _bfd_final_link_relocate (howto, input_bfd, input_section, contents, address,
                          value, addend)
-     const reloc_howto_type *howto;
+     reloc_howto_type *howto;
      bfd *input_bfd;
      asection *input_section;
      bfd_byte *contents;
@@ -966,7 +1373,7 @@ _bfd_final_link_relocate (howto, input_bfd, input_section, contents, address,
   bfd_vma relocation;
 
   /* Sanity check the address.  */
-  if (address > input_section->_cooked_size)
+  if (address > input_section->_raw_size)
     return bfd_reloc_outofrange;
 
   /* This function assumes that we are dealing with a basic relocation
@@ -993,13 +1400,6 @@ _bfd_final_link_relocate (howto, input_bfd, input_section, contents, address,
        relocation -= address;
     }
 
-  if(howto->special_function1) {
-      bfd_reloc_status_type cont;
-      cont = (*howto->special_function1)(howto, input_bfd, relocation,
-                                      contents + address);
-      if (cont != bfd_reloc_continue)
-       return cont;
-    }
   return _bfd_relocate_contents (howto, input_bfd, relocation,
                                 contents + address);
 }
@@ -1008,14 +1408,16 @@ _bfd_final_link_relocate (howto, input_bfd, input_section, contents, address,
 
 bfd_reloc_status_type
 _bfd_relocate_contents (howto, input_bfd, relocation, location)
-     const reloc_howto_type *howto;
+     reloc_howto_type *howto;
      bfd *input_bfd;
      bfd_vma relocation;
      bfd_byte *location;
 {
   int size;
-  bfd_vma x;
+  bfd_vma x = 0;
   boolean overflow;
+  unsigned int rightshift = howto->rightshift;
+  unsigned int bitpos = howto->bitpos;
 
   /* If the size is negative, negate RELOCATION.  This isn't very
      general.  */
@@ -1054,114 +1456,148 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
   overflow = false;
   if (howto->complain_on_overflow != complain_overflow_dont)
     {
-      bfd_vma check;
-      bfd_signed_vma signed_check;
-      bfd_vma add;
-      bfd_signed_vma signed_add;
+      bfd_vma addrmask, fieldmask, signmask, ss;
+      bfd_vma a, b, sum;
+
+      /* Get the values to be added together.  For signed and unsigned
+         relocations, we assume that all values should be truncated to
+         the size of an address.  For bitfields, all the bits matter.
+         See also bfd_check_overflow.  */
+      fieldmask = N_ONES (howto->bitsize);
+      addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
+      a = relocation;
+      b = x & howto->src_mask;
 
-      if (howto->rightshift == 0)
-       {
-         check = relocation;
-         signed_check = (bfd_signed_vma) relocation;
-       }
-      else
+      switch (howto->complain_on_overflow)
        {
-         /* Drop unwanted bits from the value we are relocating to.  */
-         check = relocation >> howto->rightshift;
+       case complain_overflow_signed:
+         a = (a & addrmask) >> rightshift;
+
+         /* If any sign bits are set, all sign bits must be set.
+            That is, A must be a valid negative address after
+            shifting.  */
+         signmask = ~ (fieldmask >> 1);
+         ss = a & signmask;
+         if (ss != 0 && ss != ((addrmask >> rightshift) & signmask))
+           overflow = true;
+
+         /* We only need this next bit of code if the sign bit of B
+             is below the sign bit of A.  This would only happen if
+             SRC_MASK had fewer bits than BITSIZE.  Note that if
+             SRC_MASK has more bits than BITSIZE, we can get into
+             trouble; we would need to verify that B is in range, as
+             we do for A above.  */
+         signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
+         if ((b & signmask) != 0)
+           {
+             /* Set all the bits above the sign bit.  */
+             b -= signmask <<= 1;
+           }
 
-         /* If this is a signed value, the rightshift just dropped
-            leading 1 bits (assuming twos complement).  */
-         if ((bfd_signed_vma) relocation >= 0)
-           signed_check = check;
-         else
-           signed_check = (check
-                           | ((bfd_vma) - 1
-                              & ~((bfd_vma) - 1 >> howto->rightshift)));
-       }
+         b = (b & addrmask) >> bitpos;
 
-      /* Get the value from the object file.  */
-      add = x & howto->src_mask;
-
-      /* Get the value from the object file with an appropriate sign.
-        The expression involving howto->src_mask isolates the upper
-        bit of src_mask.  If that bit is set in the value we are
-        adding, it is negative, and we subtract out that number times
-        two.  If src_mask includes the highest possible bit, then we
-        can not get the upper bit, but that does not matter since
-        signed_add needs no adjustment to become negative in that
-        case.  */
-      signed_add = add;
-      if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
-       signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
-
-      /* Add the value from the object file, shifted so that it is a
-        straight number.  */
-      if (howto->bitpos == 0)
-       {
-         check += add;
-         signed_check += signed_add;
-       }
-      else
-       {
-         check += add >> howto->bitpos;
+         /* Now we can do the addition.  */
+         sum = a + b;
 
-         /* For the signed case we use ADD, rather than SIGNED_ADD,
-            to avoid warnings from SVR4 cc.  This is OK since we
-            explictly handle the sign bits.  */
-         if (signed_add >= 0)
-           signed_check += add >> howto->bitpos;
-         else
-           signed_check += ((add >> howto->bitpos)
-                            | ((bfd_vma) - 1
-                               & ~((bfd_vma) - 1 >> howto->bitpos)));
-       }
+         /* See if the result has the correct sign.  Bits above the
+             sign bit are junk now; ignore them.  If the sum is
+             positive, make sure we did not have all negative inputs;
+             if the sum is negative, make sure we did not have all
+             positive inputs.  The test below looks only at the sign
+             bits, and it really just
+                SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM)
+            */
+         signmask = (fieldmask >> 1) + 1;
+         if (((~ (a ^ b)) & (a ^ sum)) & signmask)
+           overflow = true;
 
-      switch (howto->complain_on_overflow)
-       {
-       case complain_overflow_signed:
-         {
-           /* Assumes two's complement.  */
-           bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
-           bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
-
-           if (signed_check > reloc_signed_max
-               || signed_check < reloc_signed_min)
-             overflow = true;
-         }
          break;
+
        case complain_overflow_unsigned:
-         {
-           /* Assumes two's complement.  This expression avoids
-              overflow if howto->bitsize is the number of bits in
-              bfd_vma.  */
-           bfd_vma reloc_unsigned_max =
-           (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
-
-           if (check > reloc_unsigned_max)
-             overflow = true;
-         }
+         /* Checking for an unsigned overflow is relatively easy:
+             trim the addresses and add, and trim the result as well.
+             Overflow is normally indicated when the result does not
+             fit in the field.  However, we also need to consider the
+             case when, e.g., fieldmask is 0x7fffffff or smaller, an
+             input is 0x80000000, and bfd_vma is only 32 bits; then we
+             will get sum == 0, but there is an overflow, since the
+             inputs did not fit in the field.  Instead of doing a
+             separate test, we can check for this by or-ing in the
+             operands when testing for the sum overflowing its final
+             field.  */
+         a = (a & addrmask) >> rightshift;
+         b = (b & addrmask) >> bitpos;
+         sum = (a + b) & addrmask;
+         if ((a | b | sum) & ~ fieldmask)
+           overflow = true;
+
          break;
+
        case complain_overflow_bitfield:
-         {
-           /* Assumes two's complement.  This expression avoids
-              overflow if howto->bitsize is the number of bits in
-              bfd_vma.  */
-           bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
-
-           if ((check & ~reloc_bits) != 0
-               && (((bfd_vma) signed_check & ~reloc_bits)
-                   != (-1 & ~reloc_bits)))
-             overflow = true;
-         }
+         /* Much like unsigned, except no trimming with addrmask.  In
+             addition, the sum overflows if there is a carry out of
+             the bfd_vma, i.e., the sum is less than either input
+             operand.  */
+         a >>= rightshift;
+         b >>= bitpos;
+
+         /* Bitfields are sometimes used for signed numbers; for
+             example, a 13-bit field sometimes represents values in
+             0..8191 and sometimes represents values in -4096..4095.
+             If the field is signed and a is -4095 (0x1001) and b is
+             -1 (0x1fff), the sum is -4096 (0x1000), but (0x1001 +
+             0x1fff is 0x3000).  It's not clear how to handle this
+             everywhere, since there is not way to know how many bits
+             are significant in the relocation, but the original code
+             assumed that it was fully sign extended, and we will keep
+             that assumption.  */
+         signmask = (fieldmask >> 1) + 1;
+
+         if ((a & ~ fieldmask) != 0)
+           {
+             /* Some bits out of the field are set.  This might not
+                 be a problem: if this is a signed bitfield, it is OK
+                 iff all the high bits are set, including the sign
+                 bit.  We'll try setting all but the most significant
+                 bit in the original relocation value: if this is all
+                 ones, we are OK, assuming a signed bitfield.  */
+             ss = (signmask << rightshift) - 1;
+             if ((ss | relocation) != ~ (bfd_vma) 0)
+               overflow = true;
+             a &= fieldmask;
+           }
+
+         /* We just assume (b & ~ fieldmask) == 0.  */
+
+         /* We explicitly permit wrap around if this relocation
+            covers the high bit of an address.  The Linux kernel
+            relies on it, and it is the only way to write assembler
+            code which can run when loaded at a location 0x80000000
+            away from the location at which it is linked.  */
+         if (howto->bitsize + rightshift
+             == bfd_arch_bits_per_address (input_bfd))
+           break;
+
+         sum = a + b;
+         if (sum < a || (sum & ~ fieldmask) != 0)
+           {
+             /* There was a carry out, or the field overflow.  Test
+                 for signed operands again.  Here is the overflow test
+                 is as for complain_overflow_signed.  */
+             if (((~ (a ^ b)) & (a ^ sum)) & signmask)
+               overflow = true;
+           }
+
          break;
+
        default:
          abort ();
        }
     }
 
   /* Put RELOCATION in the right bits.  */
-  relocation >>= (bfd_vma) howto->rightshift;
-  relocation <<= (bfd_vma) howto->bitpos;
+  relocation >>= (bfd_vma) rightshift;
+  relocation <<= (bfd_vma) bitpos;
 
   /* Add RELOCATION to the right bits of X.  */
   x = ((x & ~howto->dst_mask)
@@ -1222,204 +1658,980 @@ DESCRIPTION
        enumerator value; you can't get a howto pointer from a random set
        of attributes.
 
+SENUM
+   bfd_reloc_code_real
+
+ENUM
+  BFD_RELOC_64
+ENUMX
+  BFD_RELOC_32
+ENUMX
+  BFD_RELOC_26
+ENUMX
+  BFD_RELOC_24
+ENUMX
+  BFD_RELOC_16
+ENUMX
+  BFD_RELOC_14
+ENUMX
+  BFD_RELOC_8
+ENUMDOC
+  Basic absolute relocations of N bits.
+
+ENUM
+  BFD_RELOC_64_PCREL
+ENUMX
+  BFD_RELOC_32_PCREL
+ENUMX
+  BFD_RELOC_24_PCREL
+ENUMX
+  BFD_RELOC_16_PCREL
+ENUMX
+  BFD_RELOC_12_PCREL
+ENUMX
+  BFD_RELOC_8_PCREL
+ENUMDOC
+  PC-relative relocations.  Sometimes these are relative to the address
+of the relocation itself; sometimes they are relative to the start of
+the section containing the relocation.  It depends on the specific target.
+
+The 24-bit relocation is used in some Intel 960 configurations.
+
+ENUM
+  BFD_RELOC_32_GOT_PCREL
+ENUMX
+  BFD_RELOC_16_GOT_PCREL
+ENUMX
+  BFD_RELOC_8_GOT_PCREL
+ENUMX
+  BFD_RELOC_32_GOTOFF
+ENUMX
+  BFD_RELOC_16_GOTOFF
+ENUMX
+  BFD_RELOC_LO16_GOTOFF
+ENUMX
+  BFD_RELOC_HI16_GOTOFF
+ENUMX
+  BFD_RELOC_HI16_S_GOTOFF
+ENUMX
+  BFD_RELOC_8_GOTOFF
+ENUMX
+  BFD_RELOC_32_PLT_PCREL
+ENUMX
+  BFD_RELOC_24_PLT_PCREL
+ENUMX
+  BFD_RELOC_16_PLT_PCREL
+ENUMX
+  BFD_RELOC_8_PLT_PCREL
+ENUMX
+  BFD_RELOC_32_PLTOFF
+ENUMX
+  BFD_RELOC_16_PLTOFF
+ENUMX
+  BFD_RELOC_LO16_PLTOFF
+ENUMX
+  BFD_RELOC_HI16_PLTOFF
+ENUMX
+  BFD_RELOC_HI16_S_PLTOFF
+ENUMX
+  BFD_RELOC_8_PLTOFF
+ENUMDOC
+  For ELF.
+
+ENUM
+  BFD_RELOC_68K_GLOB_DAT
+ENUMX
+  BFD_RELOC_68K_JMP_SLOT
+ENUMX
+  BFD_RELOC_68K_RELATIVE
+ENUMDOC
+  Relocations used by 68K ELF.
+
+ENUM
+  BFD_RELOC_32_BASEREL
+ENUMX
+  BFD_RELOC_16_BASEREL
+ENUMX
+  BFD_RELOC_LO16_BASEREL
+ENUMX
+  BFD_RELOC_HI16_BASEREL
+ENUMX
+  BFD_RELOC_HI16_S_BASEREL
+ENUMX
+  BFD_RELOC_8_BASEREL
+ENUMX
+  BFD_RELOC_RVA
+ENUMDOC
+  Linkage-table relative.
+
+ENUM
+  BFD_RELOC_8_FFnn
+ENUMDOC
+  Absolute 8-bit relocation, but used to form an address like 0xFFnn.
+
+ENUM
+  BFD_RELOC_32_PCREL_S2
+ENUMX
+  BFD_RELOC_16_PCREL_S2
+ENUMX
+  BFD_RELOC_23_PCREL_S2
+ENUMDOC
+  These PC-relative relocations are stored as word displacements --
+i.e., byte displacements shifted right two bits.  The 30-bit word
+displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the
+SPARC.  (SPARC tools generally refer to this as <<WDISP30>>.)  The
+signed 16-bit displacement is used on the MIPS, and the 23-bit
+displacement is used on the Alpha.
+
+ENUM
+  BFD_RELOC_HI22
+ENUMX
+  BFD_RELOC_LO10
+ENUMDOC
+  High 22 bits and low 10 bits of 32-bit value, placed into lower bits of
+the target word.  These are used on the SPARC.
+
+ENUM
+  BFD_RELOC_GPREL16
+ENUMX
+  BFD_RELOC_GPREL32
+ENUMDOC
+  For systems that allocate a Global Pointer register, these are
+displacements off that register.  These relocation types are
+handled specially, because the value the register will have is
+decided relatively late.
+
+
+ENUM
+  BFD_RELOC_I960_CALLJ
+ENUMDOC
+  Reloc types used for i960/b.out.
+
+ENUM
+  BFD_RELOC_NONE
+ENUMX
+  BFD_RELOC_SPARC_WDISP22
+ENUMX
+  BFD_RELOC_SPARC22
+ENUMX
+  BFD_RELOC_SPARC13
+ENUMX
+  BFD_RELOC_SPARC_GOT10
+ENUMX
+  BFD_RELOC_SPARC_GOT13
+ENUMX
+  BFD_RELOC_SPARC_GOT22
+ENUMX
+  BFD_RELOC_SPARC_PC10
+ENUMX
+  BFD_RELOC_SPARC_PC22
+ENUMX
+  BFD_RELOC_SPARC_WPLT30
+ENUMX
+  BFD_RELOC_SPARC_COPY
+ENUMX
+  BFD_RELOC_SPARC_GLOB_DAT
+ENUMX
+  BFD_RELOC_SPARC_JMP_SLOT
+ENUMX
+  BFD_RELOC_SPARC_RELATIVE
+ENUMX
+  BFD_RELOC_SPARC_UA32
+ENUMDOC
+  SPARC ELF relocations.  There is probably some overlap with other
+  relocation types already defined.
+
+ENUM
+  BFD_RELOC_SPARC_BASE13
+ENUMX
+  BFD_RELOC_SPARC_BASE22
+ENUMDOC
+  I think these are specific to SPARC a.out (e.g., Sun 4).
+
+ENUMEQ
+  BFD_RELOC_SPARC_64
+  BFD_RELOC_64
+ENUMX
+  BFD_RELOC_SPARC_10
+ENUMX
+  BFD_RELOC_SPARC_11
+ENUMX
+  BFD_RELOC_SPARC_OLO10
+ENUMX
+  BFD_RELOC_SPARC_HH22
+ENUMX
+  BFD_RELOC_SPARC_HM10
+ENUMX
+  BFD_RELOC_SPARC_LM22
+ENUMX
+  BFD_RELOC_SPARC_PC_HH22
+ENUMX
+  BFD_RELOC_SPARC_PC_HM10
+ENUMX
+  BFD_RELOC_SPARC_PC_LM22
+ENUMX
+  BFD_RELOC_SPARC_WDISP16
+ENUMX
+  BFD_RELOC_SPARC_WDISP19
+ENUMX
+  BFD_RELOC_SPARC_7
+ENUMX
+  BFD_RELOC_SPARC_6
+ENUMX
+  BFD_RELOC_SPARC_5
+ENUMEQX
+  BFD_RELOC_SPARC_DISP64
+  BFD_RELOC_64_PCREL
+ENUMX
+  BFD_RELOC_SPARC_PLT64
+ENUMX
+  BFD_RELOC_SPARC_HIX22
+ENUMX
+  BFD_RELOC_SPARC_LOX10
+ENUMX
+  BFD_RELOC_SPARC_H44
+ENUMX
+  BFD_RELOC_SPARC_M44
+ENUMX
+  BFD_RELOC_SPARC_L44
+ENUMX
+  BFD_RELOC_SPARC_REGISTER
+ENUMDOC
+  SPARC64 relocations
+
+ENUM
+  BFD_RELOC_SPARC_REV32
+ENUMDOC
+  SPARC little endian relocation
+
+ENUM
+  BFD_RELOC_ALPHA_GPDISP_HI16
+ENUMDOC
+  Alpha ECOFF and ELF relocations.  Some of these treat the symbol or
+     "addend" in some special way.
+  For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when
+     writing; when reading, it will be the absolute section symbol.  The
+     addend is the displacement in bytes of the "lda" instruction from
+     the "ldah" instruction (which is at the address of this reloc).
+ENUM
+  BFD_RELOC_ALPHA_GPDISP_LO16
+ENUMDOC
+  For GPDISP_LO16 ("ignore") relocations, the symbol is handled as
+     with GPDISP_HI16 relocs.  The addend is ignored when writing the
+     relocations out, and is filled in with the file's GP value on
+     reading, for convenience.
+
+ENUM
+  BFD_RELOC_ALPHA_GPDISP
+ENUMDOC
+  The ELF GPDISP relocation is exactly the same as the GPDISP_HI16
+     relocation except that there is no accompanying GPDISP_LO16
+     relocation.
+
+ENUM
+  BFD_RELOC_ALPHA_LITERAL
+ENUMX
+  BFD_RELOC_ALPHA_ELF_LITERAL
+ENUMX
+  BFD_RELOC_ALPHA_LITUSE
+ENUMDOC
+  The Alpha LITERAL/LITUSE relocs are produced by a symbol reference;
+     the assembler turns it into a LDQ instruction to load the address of
+     the symbol, and then fills in a register in the real instruction.
+
+     The LITERAL reloc, at the LDQ instruction, refers to the .lita
+     section symbol.  The addend is ignored when writing, but is filled
+     in with the file's GP value on reading, for convenience, as with the
+     GPDISP_LO16 reloc.
+
+     The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16.
+     It should refer to the symbol to be referenced, as with 16_GOTOFF,
+     but it generates output not based on the position within the .got
+     section, but relative to the GP value chosen for the file during the
+     final link stage.
+
+     The LITUSE reloc, on the instruction using the loaded address, gives
+     information to the linker that it might be able to use to optimize
+     away some literal section references.  The symbol is ignored (read
+     as the absolute section symbol), and the "addend" indicates the type
+     of instruction using the register:
+              1 - "memory" fmt insn
+              2 - byte-manipulation (byte offset reg)
+              3 - jsr (target of branch)
+
+     The GNU linker currently doesn't do any of this optimizing.
+
+ENUM
+  BFD_RELOC_ALPHA_USER_LITERAL
+ENUMX
+  BFD_RELOC_ALPHA_USER_LITUSE_BASE
+ENUMX
+  BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
+ENUMX
+  BFD_RELOC_ALPHA_USER_LITUSE_JSR
+ENUMX
+  BFD_RELOC_ALPHA_USER_GPDISP
+ENUMX
+  BFD_RELOC_ALPHA_USER_GPRELHIGH
+ENUMX
+  BFD_RELOC_ALPHA_USER_GPRELLOW
+ENUMDOC
+  The BFD_RELOC_ALPHA_USER_* relocations are used by the assembler to
+     process the explicit !<reloc>!sequence relocations, and are mapped
+     into the normal relocations at the end of processing.
+
+ENUM
+  BFD_RELOC_ALPHA_HINT
+ENUMDOC
+  The HINT relocation indicates a value that should be filled into the
+     "hint" field of a jmp/jsr/ret instruction, for possible branch-
+     prediction logic which may be provided on some processors.
+
+ENUM
+  BFD_RELOC_ALPHA_LINKAGE
+ENUMDOC
+  The LINKAGE relocation outputs a linkage pair in the object file,
+     which is filled by the linker.
+
+ENUM
+  BFD_RELOC_ALPHA_CODEADDR
+ENUMDOC
+  The CODEADDR relocation outputs a STO_CA in the object file,
+     which is filled by the linker.
+
+ENUM
+  BFD_RELOC_MIPS_JMP
+ENUMDOC
+  Bits 27..2 of the relocation address shifted right 2 bits;
+     simple reloc otherwise.
+
+ENUM
+  BFD_RELOC_MIPS16_JMP
+ENUMDOC
+  The MIPS16 jump instruction.
+
+ENUM
+  BFD_RELOC_MIPS16_GPREL
+ENUMDOC
+  MIPS16 GP relative reloc.
+
+ENUM
+  BFD_RELOC_HI16
+ENUMDOC
+  High 16 bits of 32-bit value; simple reloc.
+ENUM
+  BFD_RELOC_HI16_S
+ENUMDOC
+  High 16 bits of 32-bit value but the low 16 bits will be sign
+     extended and added to form the final result.  If the low 16
+     bits form a negative number, we need to add one to the high value
+     to compensate for the borrow when the low bits are added.
+ENUM
+  BFD_RELOC_LO16
+ENUMDOC
+  Low 16 bits.
+ENUM
+  BFD_RELOC_PCREL_HI16_S
+ENUMDOC
+  Like BFD_RELOC_HI16_S, but PC relative.
+ENUM
+  BFD_RELOC_PCREL_LO16
+ENUMDOC
+  Like BFD_RELOC_LO16, but PC relative.
+
+ENUMEQ
+  BFD_RELOC_MIPS_GPREL
+  BFD_RELOC_GPREL16
+ENUMDOC
+  Relocation relative to the global pointer.
+
+ENUM
+  BFD_RELOC_MIPS_LITERAL
+ENUMDOC
+  Relocation against a MIPS literal section.
+
+ENUM
+  BFD_RELOC_MIPS_GOT16
+ENUMX
+  BFD_RELOC_MIPS_CALL16
+ENUMEQX
+  BFD_RELOC_MIPS_GPREL32
+  BFD_RELOC_GPREL32
+ENUMX
+  BFD_RELOC_MIPS_GOT_HI16
+ENUMX
+  BFD_RELOC_MIPS_GOT_LO16
+ENUMX
+  BFD_RELOC_MIPS_CALL_HI16
+ENUMX
+  BFD_RELOC_MIPS_CALL_LO16
+ENUMX
+  BFD_RELOC_MIPS_SUB
+ENUMX
+  BFD_RELOC_MIPS_GOT_PAGE
+ENUMX
+  BFD_RELOC_MIPS_GOT_OFST
+ENUMX
+  BFD_RELOC_MIPS_GOT_DISP
+COMMENT
+ENUMDOC
+  MIPS ELF relocations.
+
+COMMENT
+
+ENUM
+  BFD_RELOC_386_GOT32
+ENUMX
+  BFD_RELOC_386_PLT32
+ENUMX
+  BFD_RELOC_386_COPY
+ENUMX
+  BFD_RELOC_386_GLOB_DAT
+ENUMX
+  BFD_RELOC_386_JUMP_SLOT
+ENUMX
+  BFD_RELOC_386_RELATIVE
+ENUMX
+  BFD_RELOC_386_GOTOFF
+ENUMX
+  BFD_RELOC_386_GOTPC
+ENUMDOC
+  i386/elf relocations
+
+ENUM
+  BFD_RELOC_NS32K_IMM_8
+ENUMX
+  BFD_RELOC_NS32K_IMM_16
+ENUMX
+  BFD_RELOC_NS32K_IMM_32
+ENUMX
+  BFD_RELOC_NS32K_IMM_8_PCREL
+ENUMX
+  BFD_RELOC_NS32K_IMM_16_PCREL
+ENUMX
+  BFD_RELOC_NS32K_IMM_32_PCREL
+ENUMX
+  BFD_RELOC_NS32K_DISP_8
+ENUMX
+  BFD_RELOC_NS32K_DISP_16
+ENUMX
+  BFD_RELOC_NS32K_DISP_32
+ENUMX
+  BFD_RELOC_NS32K_DISP_8_PCREL
+ENUMX
+  BFD_RELOC_NS32K_DISP_16_PCREL
+ENUMX
+  BFD_RELOC_NS32K_DISP_32_PCREL
+ENUMDOC
+  ns32k relocations
+
+ENUM
+  BFD_RELOC_PJ_CODE_HI16
+ENUMX
+  BFD_RELOC_PJ_CODE_LO16
+ENUMX
+  BFD_RELOC_PJ_CODE_DIR16
+ENUMX
+  BFD_RELOC_PJ_CODE_DIR32
+ENUMX
+  BFD_RELOC_PJ_CODE_REL16
+ENUMX
+  BFD_RELOC_PJ_CODE_REL32
+ENUMDOC
+  Picojava relocs.  Not all of these appear in object files.
+  
+ENUM
+  BFD_RELOC_PPC_B26
+ENUMX
+  BFD_RELOC_PPC_BA26
+ENUMX
+  BFD_RELOC_PPC_TOC16
+ENUMX
+  BFD_RELOC_PPC_B16
+ENUMX
+  BFD_RELOC_PPC_B16_BRTAKEN
+ENUMX
+  BFD_RELOC_PPC_B16_BRNTAKEN
+ENUMX
+  BFD_RELOC_PPC_BA16
+ENUMX
+  BFD_RELOC_PPC_BA16_BRTAKEN
+ENUMX
+  BFD_RELOC_PPC_BA16_BRNTAKEN
+ENUMX
+  BFD_RELOC_PPC_COPY
+ENUMX
+  BFD_RELOC_PPC_GLOB_DAT
+ENUMX
+  BFD_RELOC_PPC_JMP_SLOT
+ENUMX
+  BFD_RELOC_PPC_RELATIVE
+ENUMX
+  BFD_RELOC_PPC_LOCAL24PC
+ENUMX
+  BFD_RELOC_PPC_EMB_NADDR32
+ENUMX
+  BFD_RELOC_PPC_EMB_NADDR16
+ENUMX
+  BFD_RELOC_PPC_EMB_NADDR16_LO
+ENUMX
+  BFD_RELOC_PPC_EMB_NADDR16_HI
+ENUMX
+  BFD_RELOC_PPC_EMB_NADDR16_HA
+ENUMX
+  BFD_RELOC_PPC_EMB_SDAI16
+ENUMX
+  BFD_RELOC_PPC_EMB_SDA2I16
+ENUMX
+  BFD_RELOC_PPC_EMB_SDA2REL
+ENUMX
+  BFD_RELOC_PPC_EMB_SDA21
+ENUMX
+  BFD_RELOC_PPC_EMB_MRKREF
+ENUMX
+  BFD_RELOC_PPC_EMB_RELSEC16
+ENUMX
+  BFD_RELOC_PPC_EMB_RELST_LO
+ENUMX
+  BFD_RELOC_PPC_EMB_RELST_HI
+ENUMX
+  BFD_RELOC_PPC_EMB_RELST_HA
+ENUMX
+  BFD_RELOC_PPC_EMB_BIT_FLD
+ENUMX
+  BFD_RELOC_PPC_EMB_RELSDA
+ENUMDOC
+  Power(rs6000) and PowerPC relocations.
+
+ENUM
+  BFD_RELOC_CTOR
+ENUMDOC
+  The type of reloc used to build a contructor table - at the moment
+  probably a 32 bit wide absolute relocation, but the target can choose.
+  It generally does map to one of the other relocation types.
+
+ENUM
+  BFD_RELOC_ARM_PCREL_BRANCH
+ENUMDOC
+  ARM 26 bit pc-relative branch.  The lowest two bits must be zero and are
+  not stored in the instruction.
+ENUM
+  BFD_RELOC_ARM_IMMEDIATE
+ENUMX
+  BFD_RELOC_ARM_ADRL_IMMEDIATE
+ENUMX
+  BFD_RELOC_ARM_OFFSET_IMM
+ENUMX
+  BFD_RELOC_ARM_SHIFT_IMM
+ENUMX
+  BFD_RELOC_ARM_SWI
+ENUMX
+  BFD_RELOC_ARM_MULTI
+ENUMX
+  BFD_RELOC_ARM_CP_OFF_IMM
+ENUMX
+  BFD_RELOC_ARM_ADR_IMM
+ENUMX
+  BFD_RELOC_ARM_LDR_IMM
+ENUMX
+  BFD_RELOC_ARM_LITERAL
+ENUMX
+  BFD_RELOC_ARM_IN_POOL
+ENUMX
+  BFD_RELOC_ARM_OFFSET_IMM8
+ENUMX
+  BFD_RELOC_ARM_HWLITERAL
+ENUMX
+  BFD_RELOC_ARM_THUMB_ADD
+ENUMX
+  BFD_RELOC_ARM_THUMB_IMM
+ENUMX
+  BFD_RELOC_ARM_THUMB_SHIFT
+ENUMX
+  BFD_RELOC_ARM_THUMB_OFFSET
+ENUMX
+  BFD_RELOC_ARM_GOT12
+ENUMX
+  BFD_RELOC_ARM_GOT32
+ENUMX
+  BFD_RELOC_ARM_JUMP_SLOT
+ENUMX
+  BFD_RELOC_ARM_COPY
+ENUMX
+  BFD_RELOC_ARM_GLOB_DAT
+ENUMX
+  BFD_RELOC_ARM_PLT32
+ENUMX
+  BFD_RELOC_ARM_RELATIVE
+ENUMX
+  BFD_RELOC_ARM_GOTOFF
+ENUMX
+  BFD_RELOC_ARM_GOTPC
+ENUMDOC
+  These relocs are only used within the ARM assembler.  They are not
+  (at present) written to any object files.
+
+ENUM
+  BFD_RELOC_SH_PCDISP8BY2
+ENUMX
+  BFD_RELOC_SH_PCDISP12BY2
+ENUMX
+  BFD_RELOC_SH_IMM4
+ENUMX
+  BFD_RELOC_SH_IMM4BY2
+ENUMX
+  BFD_RELOC_SH_IMM4BY4
+ENUMX
+  BFD_RELOC_SH_IMM8
+ENUMX
+  BFD_RELOC_SH_IMM8BY2
+ENUMX
+  BFD_RELOC_SH_IMM8BY4
+ENUMX
+  BFD_RELOC_SH_PCRELIMM8BY2
+ENUMX
+  BFD_RELOC_SH_PCRELIMM8BY4
+ENUMX
+  BFD_RELOC_SH_SWITCH16
+ENUMX
+  BFD_RELOC_SH_SWITCH32
+ENUMX
+  BFD_RELOC_SH_USES
+ENUMX
+  BFD_RELOC_SH_COUNT
+ENUMX
+  BFD_RELOC_SH_ALIGN
+ENUMX
+  BFD_RELOC_SH_CODE
+ENUMX
+  BFD_RELOC_SH_DATA
+ENUMX
+  BFD_RELOC_SH_LABEL
+ENUMDOC
+  Hitachi SH relocs.  Not all of these appear in object files.
+
+ENUM
+  BFD_RELOC_THUMB_PCREL_BRANCH9
+ENUMX
+  BFD_RELOC_THUMB_PCREL_BRANCH12
+ENUMX
+  BFD_RELOC_THUMB_PCREL_BRANCH23
+ENUMDOC
+  Thumb 23-, 12- and 9-bit pc-relative branches.  The lowest bit must
+  be zero and is not stored in the instruction.
+
+ENUM
+  BFD_RELOC_ARC_B22_PCREL
+ENUMDOC
+  Argonaut RISC Core (ARC) relocs.
+  ARC 22 bit pc-relative branch.  The lowest two bits must be zero and are
+  not stored in the instruction.  The high 20 bits are installed in bits 26
+  through 7 of the instruction.
+ENUM
+  BFD_RELOC_ARC_B26
+ENUMDOC
+  ARC 26 bit absolute branch.  The lowest two bits must be zero and are not
+  stored in the instruction.  The high 24 bits are installed in bits 23
+  through 0.
+
+ENUM
+  BFD_RELOC_D10V_10_PCREL_R
+ENUMDOC
+  Mitsubishi D10V relocs.
+  This is a 10-bit reloc with the right 2 bits
+  assumed to be 0.
+ENUM
+  BFD_RELOC_D10V_10_PCREL_L
+ENUMDOC
+  Mitsubishi D10V relocs.
+  This is a 10-bit reloc with the right 2 bits
+  assumed to be 0.  This is the same as the previous reloc
+  except it is in the left container, i.e.,
+  shifted left 15 bits.
+ENUM
+  BFD_RELOC_D10V_18
+ENUMDOC
+  This is an 18-bit reloc with the right 2 bits
+  assumed to be 0.
+ENUM
+  BFD_RELOC_D10V_18_PCREL
+ENUMDOC
+  This is an 18-bit reloc with the right 2 bits
+  assumed to be 0.
+
+ENUM
+  BFD_RELOC_D30V_6
+ENUMDOC
+  Mitsubishi D30V relocs.
+  This is a 6-bit absolute reloc.
+ENUM
+  BFD_RELOC_D30V_9_PCREL
+ENUMDOC
+  This is a 6-bit pc-relative reloc with 
+  the right 3 bits assumed to be 0.  
+ENUM
+  BFD_RELOC_D30V_9_PCREL_R
+ENUMDOC
+  This is a 6-bit pc-relative reloc with 
+  the right 3 bits assumed to be 0. Same
+  as the previous reloc but on the right side
+  of the container.  
+ENUM
+  BFD_RELOC_D30V_15
+ENUMDOC
+  This is a 12-bit absolute reloc with the 
+  right 3 bitsassumed to be 0.  
+ENUM
+  BFD_RELOC_D30V_15_PCREL
+ENUMDOC
+  This is a 12-bit pc-relative reloc with 
+  the right 3 bits assumed to be 0.  
+ENUM
+  BFD_RELOC_D30V_15_PCREL_R
+ENUMDOC
+  This is a 12-bit pc-relative reloc with 
+  the right 3 bits assumed to be 0. Same
+  as the previous reloc but on the right side
+  of the container.  
+ENUM
+  BFD_RELOC_D30V_21
+ENUMDOC
+  This is an 18-bit absolute reloc with 
+  the right 3 bits assumed to be 0.
+ENUM
+  BFD_RELOC_D30V_21_PCREL
+ENUMDOC
+  This is an 18-bit pc-relative reloc with 
+  the right 3 bits assumed to be 0.
+ENUM
+  BFD_RELOC_D30V_21_PCREL_R
+ENUMDOC
+  This is an 18-bit pc-relative reloc with 
+  the right 3 bits assumed to be 0. Same
+  as the previous reloc but on the right side
+  of the container.
+ENUM
+  BFD_RELOC_D30V_32
+ENUMDOC
+  This is a 32-bit absolute reloc.
+ENUM
+  BFD_RELOC_D30V_32_PCREL
+ENUMDOC
+  This is a 32-bit pc-relative reloc.
+
+ENUM
+  BFD_RELOC_M32R_24
+ENUMDOC
+  Mitsubishi M32R relocs.
+  This is a 24 bit absolute address.
+ENUM
+  BFD_RELOC_M32R_10_PCREL
+ENUMDOC
+  This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0.
+ENUM
+  BFD_RELOC_M32R_18_PCREL
+ENUMDOC
+  This is an 18-bit reloc with the right 2 bits assumed to be 0.
+ENUM
+  BFD_RELOC_M32R_26_PCREL
+ENUMDOC
+  This is a 26-bit reloc with the right 2 bits assumed to be 0.
+ENUM
+  BFD_RELOC_M32R_HI16_ULO
+ENUMDOC
+  This is a 16-bit reloc containing the high 16 bits of an address
+  used when the lower 16 bits are treated as unsigned.
+ENUM
+  BFD_RELOC_M32R_HI16_SLO
+ENUMDOC
+  This is a 16-bit reloc containing the high 16 bits of an address
+  used when the lower 16 bits are treated as signed.
+ENUM
+  BFD_RELOC_M32R_LO16
+ENUMDOC
+  This is a 16-bit reloc containing the lower 16 bits of an address.
+ENUM
+  BFD_RELOC_M32R_SDA16
+ENUMDOC
+  This is a 16-bit reloc containing the small data area offset for use in
+  add3, load, and store instructions.
+
+ENUM
+  BFD_RELOC_V850_9_PCREL
+ENUMDOC
+  This is a 9-bit reloc
+ENUM
+  BFD_RELOC_V850_22_PCREL
+ENUMDOC
+  This is a 22-bit reloc
+
+ENUM
+  BFD_RELOC_V850_SDA_16_16_OFFSET
+ENUMDOC
+  This is a 16 bit offset from the short data area pointer.
+ENUM
+  BFD_RELOC_V850_SDA_15_16_OFFSET
+ENUMDOC
+  This is a 16 bit offset (of which only 15 bits are used) from the
+  short data area pointer.
+ENUM
+  BFD_RELOC_V850_ZDA_16_16_OFFSET
+ENUMDOC
+  This is a 16 bit offset from the zero data area pointer.
+ENUM
+  BFD_RELOC_V850_ZDA_15_16_OFFSET
+ENUMDOC
+  This is a 16 bit offset (of which only 15 bits are used) from the
+  zero data area pointer.
+ENUM
+  BFD_RELOC_V850_TDA_6_8_OFFSET
+ENUMDOC
+  This is an 8 bit offset (of which only 6 bits are used) from the
+  tiny data area pointer.
+ENUM
+  BFD_RELOC_V850_TDA_7_8_OFFSET
+ENUMDOC
+  This is an 8bit offset (of which only 7 bits are used) from the tiny
+  data area pointer.
+ENUM
+  BFD_RELOC_V850_TDA_7_7_OFFSET
+ENUMDOC
+  This is a 7 bit offset from the tiny data area pointer.
+ENUM
+  BFD_RELOC_V850_TDA_16_16_OFFSET
+ENUMDOC
+  This is a 16 bit offset from the tiny data area pointer.
+COMMENT
+ENUM
+  BFD_RELOC_V850_TDA_4_5_OFFSET
+ENUMDOC
+  This is a 5 bit offset (of which only 4 bits are used) from the tiny
+  data area pointer.
+ENUM
+  BFD_RELOC_V850_TDA_4_4_OFFSET
+ENUMDOC
+  This is a 4 bit offset from the tiny data area pointer.
+ENUM
+  BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET
+ENUMDOC
+  This is a 16 bit offset from the short data area pointer, with the
+  bits placed non-contigously in the instruction.
+ENUM
+  BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET
+ENUMDOC
+  This is a 16 bit offset from the zero data area pointer, with the
+  bits placed non-contigously in the instruction.
+ENUM
+  BFD_RELOC_V850_CALLT_6_7_OFFSET
+ENUMDOC
+  This is a 6 bit offset from the call table base pointer.
+ENUM
+  BFD_RELOC_V850_CALLT_16_16_OFFSET
+ENUMDOC
+  This is a 16 bit offset from the call table base pointer.
+COMMENT
+
+ENUM
+  BFD_RELOC_MN10300_32_PCREL
+ENUMDOC
+  This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the
+  instruction.
+ENUM
+  BFD_RELOC_MN10300_16_PCREL
+ENUMDOC
+  This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the
+  instruction.
+
+ENUM
+  BFD_RELOC_TIC30_LDP
+ENUMDOC
+  This is a 8bit DP reloc for the tms320c30, where the most
+  significant 8 bits of a 24 bit word are placed into the least
+  significant 8 bits of the opcode.
+
+ENUM
+  BFD_RELOC_FR30_48
+ENUMDOC
+  This is a 48 bit reloc for the FR30 that stores 32 bits.
+ENUM
+  BFD_RELOC_FR30_20
+ENUMDOC
+  This is a 32 bit reloc for the FR30 that stores 20 bits split up into
+  two sections.
+ENUM
+  BFD_RELOC_FR30_6_IN_4
+ENUMDOC
+  This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in
+  4 bits.
+ENUM
+  BFD_RELOC_FR30_8_IN_8
+ENUMDOC
+  This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset
+  into 8 bits.
+ENUM
+  BFD_RELOC_FR30_9_IN_8
+ENUMDOC
+  This is a 16 bit reloc for the FR30 that stores a 9 bit short offset
+  into 8 bits.
+ENUM
+  BFD_RELOC_FR30_10_IN_8
+ENUMDOC
+  This is a 16 bit reloc for the FR30 that stores a 10 bit word offset
+  into 8 bits.
+ENUM
+  BFD_RELOC_FR30_9_PCREL
+ENUMDOC
+  This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative
+  short offset into 8 bits.
+ENUM
+  BFD_RELOC_FR30_12_PCREL
+ENUMDOC
+  This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative
+  short offset into 11 bits.
+  
+ENUM
+  BFD_RELOC_MCORE_PCREL_IMM8BY4
+ENUMX
+  BFD_RELOC_MCORE_PCREL_IMM11BY2
+ENUMX
+  BFD_RELOC_MCORE_PCREL_IMM4BY2
+ENUMX
+  BFD_RELOC_MCORE_PCREL_32
+ENUMX
+  BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2
+ENUMX
+  BFD_RELOC_MCORE_RVA
+ENUMDOC
+  Motorola Mcore relocations.
+  
+ENUM
+  BFD_RELOC_VTABLE_INHERIT
+ENUMX
+  BFD_RELOC_VTABLE_ENTRY
+ENUMDOC
+  These two relocations are used by the linker to determine which of 
+  the entries in a C++ virtual function table are actually used.  When
+  the --gc-sections option is given, the linker will zero out the entries
+  that are not used, so that the code for those functions need not be
+  included in the output.
+
+  VTABLE_INHERIT is a zero-space relocation used to describe to the
+  linker the inheritence tree of a C++ virtual function table.  The
+  relocation's symbol should be the parent class' vtable, and the
+  relocation should be located at the child vtable.
+
+  VTABLE_ENTRY is a zero-space relocation that describes the use of a
+  virtual function table entry.  The reloc's symbol should refer to the
+  table of the class mentioned in the code.  Off of that base, an offset
+  describes the entry that is being used.  For Rela hosts, this offset 
+  is stored in the reloc's addend.  For Rel hosts, we are forced to put
+  this offset in the reloc's section offset.
+
+ENDSENUM
+  BFD_RELOC_UNUSED
 CODE_FRAGMENT
 .
-.typedef enum bfd_reloc_code_real
-.{
-.  {* Basic absolute relocations *}
-.  BFD_RELOC_64,
-.  BFD_RELOC_32,
-.  BFD_RELOC_26,
-.  BFD_RELOC_16,
-.  BFD_RELOC_14,
-.  BFD_RELOC_8,
-.
-.  {* PC-relative relocations *}
-.  BFD_RELOC_64_PCREL,
-.  BFD_RELOC_32_PCREL,
-.  BFD_RELOC_24_PCREL,    {* used by i960 *}
-.  BFD_RELOC_16_PCREL,
-.  BFD_RELOC_8_PCREL,
-.
-.  {* Linkage-table relative *}
-.  BFD_RELOC_32_BASEREL,
-.  BFD_RELOC_16_BASEREL,
-.  BFD_RELOC_8_BASEREL,
-.
-.  {* The type of reloc used to build a contructor table - at the moment
-.     probably a 32 bit wide abs address, but the cpu can choose. *}
-.  BFD_RELOC_CTOR,
-.
-.  {* 8 bits wide, but used to form an address like 0xffnn *}
-.  BFD_RELOC_8_FFnn,
-.
-.  {* 32-bit pc-relative, shifted right 2 bits (i.e., 30-bit
-.     word displacement, e.g. for SPARC) *}
-.  BFD_RELOC_32_PCREL_S2,
-.  {* signed 16-bit pc-relative, shifted right 2 bits (e.g. for MIPS) *}
-.  BFD_RELOC_16_PCREL_S2,
-.  {* this is used on the Alpha *}
-.  BFD_RELOC_23_PCREL_S2,
-.
-.  {* High 22 bits of 32-bit value, placed into lower 22 bits of
-.     target word; simple reloc.  *}
-.  BFD_RELOC_HI22,
-.  {* Low 10 bits.  *}
-.  BFD_RELOC_LO10,
-.
-.  {* For systems that allocate a Global Pointer register, these are
-.     displacements off that register.  These relocation types are
-.     handled specially, because the value the register will have is
-.     decided relatively late.  *}
-.  BFD_RELOC_GPREL16,
-.  BFD_RELOC_GPREL32,
-.
-.  {* Reloc types used for i960/b.out.  *}
-.  BFD_RELOC_I960_CALLJ,
-.
-.  {* now for the sparc/elf codes *}
-.  BFD_RELOC_NONE,             {* actually used *}
-.  BFD_RELOC_SPARC_WDISP22,
-.  BFD_RELOC_SPARC22,
-.  BFD_RELOC_SPARC13,
-.  BFD_RELOC_SPARC_GOT10,
-.  BFD_RELOC_SPARC_GOT13,
-.  BFD_RELOC_SPARC_GOT22,
-.  BFD_RELOC_SPARC_PC10,
-.  BFD_RELOC_SPARC_PC22,
-.  BFD_RELOC_SPARC_WPLT30,
-.  BFD_RELOC_SPARC_COPY,
-.  BFD_RELOC_SPARC_GLOB_DAT,
-.  BFD_RELOC_SPARC_JMP_SLOT,
-.  BFD_RELOC_SPARC_RELATIVE,
-.  BFD_RELOC_SPARC_UA32,
-.
-.  {* these are a.out specific? *}
-.  BFD_RELOC_SPARC_BASE13,
-.  BFD_RELOC_SPARC_BASE22,
-.
-.  {* some relocations we're using for sparc v9
-.     -- subject to change *}
-.  BFD_RELOC_SPARC_10,
-.  BFD_RELOC_SPARC_11,
-.#define  BFD_RELOC_SPARC_64 BFD_RELOC_64
-.  BFD_RELOC_SPARC_OLO10,
-.  BFD_RELOC_SPARC_HH22,
-.  BFD_RELOC_SPARC_HM10,
-.  BFD_RELOC_SPARC_LM22,
-.  BFD_RELOC_SPARC_PC_HH22,
-.  BFD_RELOC_SPARC_PC_HM10,
-.  BFD_RELOC_SPARC_PC_LM22,
-.  BFD_RELOC_SPARC_WDISP16,
-.  BFD_RELOC_SPARC_WDISP19,
-.  BFD_RELOC_SPARC_GLOB_JMP,
-.  BFD_RELOC_SPARC_LO7,
-.
-.  {* Alpha ECOFF relocations.  Some of these treat the symbol or "addend"
-.     in some special way.  *}
-.  {* For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when
-.     writing; when reading, it will be the absolute section symbol.  The
-.     addend is the displacement in bytes of the "lda" instruction from
-.     the "ldah" instruction (which is at the address of this reloc).  *}
-.  BFD_RELOC_ALPHA_GPDISP_HI16,
-.  {* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as
-.     with GPDISP_HI16 relocs.  The addend is ignored when writing the
-.     relocations out, and is filled in with the file's GP value on
-.     reading, for convenience.  *}
-.  BFD_RELOC_ALPHA_GPDISP_LO16,
-.
-.  {* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference;
-.     the assembler turns it into a LDQ instruction to load the address of
-.     the symbol, and then fills in a register in the real instruction.
-.
-.     The LITERAL reloc, at the LDQ instruction, refers to the .lita
-.     section symbol.  The addend is ignored when writing, but is filled
-.     in with the file's GP value on reading, for convenience, as with the
-.     GPDISP_LO16 reloc.
-.
-.     The LITUSE reloc, on the instruction using the loaded address, gives
-.     information to the linker that it might be able to use to optimize
-.     away some literal section references.  The symbol is ignored (read
-.     as the absolute section symbol), and the "addend" indicates the type
-.     of instruction using the register:
-.              1 - "memory" fmt insn
-.              2 - byte-manipulation (byte offset reg)
-.              3 - jsr (target of branch)
-.
-.     The GNU linker currently doesn't do any of this optimizing.  *}
-.  BFD_RELOC_ALPHA_LITERAL,
-.  BFD_RELOC_ALPHA_LITUSE,
-.
-.  {* The HINT relocation indicates a value that should be filled into the
-.     "hint" field of a jmp/jsr/ret instruction, for possible branch-
-.     prediction logic which may be provided on some processors.  *}
-.  BFD_RELOC_ALPHA_HINT,
-.
-.  {* Bits 27..2 of the relocation address shifted right 2 bits;
-.     simple reloc otherwise.  *}
-.  BFD_RELOC_MIPS_JMP,
-.
-.  {* High 16 bits of 32-bit value; simple reloc.  *}
-.  BFD_RELOC_HI16,
-.  {* High 16 bits of 32-bit value but the low 16 bits will be sign
-.     extended and added to form the final result.  If the low 16
-.     bits form a negative number, we need to add one to the high value
-.     to compensate for the borrow when the low bits are added.  *}
-.  BFD_RELOC_HI16_S,
-.  {* Low 16 bits.  *}
-.  BFD_RELOC_LO16,
-.  {* Like BFD_RELOC_HI16_S, but PC relative.  *}
-.  BFD_RELOC_PCREL_HI16_S,
-.  {* Like BFD_RELOC_LO16, but PC relative.  *}
-.  BFD_RELOC_PCREL_LO16,
-.
-.  {* relocation relative to the global pointer.  *}
-.#define BFD_RELOC_MIPS_GPREL BFD_RELOC_GPREL16
-.
-.  {* Relocation against a MIPS literal section.  *}
-.  BFD_RELOC_MIPS_LITERAL,
-.
-.  {* MIPS ELF relocations.  *}
-.  BFD_RELOC_MIPS_GOT16,
-.  BFD_RELOC_MIPS_CALL16,
-.#define BFD_RELOC_MIPS_GPREL32 BFD_RELOC_GPREL32
-.
-.  {* i386/elf relocations *}
-.  BFD_RELOC_386_GOT32,
-.  BFD_RELOC_386_PLT32,
-.  BFD_RELOC_386_COPY,
-.  BFD_RELOC_386_GLOB_DAT,
-.  BFD_RELOC_386_JUMP_SLOT,
-.  BFD_RELOC_386_RELATIVE,
-.  BFD_RELOC_386_GOTOFF,
-.  BFD_RELOC_386_GOTPC,
-.
-.  {* ns32k relocations *}
-.  BFD_RELOC_NS32K_IMM_8,
-.  BFD_RELOC_NS32K_IMM_16,
-.  BFD_RELOC_NS32K_IMM_32,
-.  BFD_RELOC_NS32K_IMM_8_PCREL,
-.  BFD_RELOC_NS32K_IMM_16_PCREL,
-.  BFD_RELOC_NS32K_IMM_32_PCREL,
-.  BFD_RELOC_NS32K_DISP_8,
-.  BFD_RELOC_NS32K_DISP_16,
-.  BFD_RELOC_NS32K_DISP_32,
-.  BFD_RELOC_NS32K_DISP_8_PCREL,
-.  BFD_RELOC_NS32K_DISP_16_PCREL,
-.  BFD_RELOC_NS32K_DISP_32_PCREL,
-.
-.  {* PowerPC/POWER (RS/6000) relocs.  *}
-.  {* 26 bit relative branch.  Low two bits must be zero.  High 24
-.     bits installed in bits 6 through 29 of instruction.  *}
-.  BFD_RELOC_PPC_B26,
-.  {* 26 bit absolute branch, like BFD_RELOC_PPC_B26 but absolute.  *}
-.  BFD_RELOC_PPC_BA26,
-.  {* 16 bit TOC relative reference.  *}
-.  BFD_RELOC_PPC_TOC16,
-.
-.  {* this must be the highest numeric value *}
-.  BFD_RELOC_UNUSED
-. } bfd_reloc_code_real_type;
+.typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
 */
 
 
@@ -1428,7 +2640,7 @@ FUNCTION
        bfd_reloc_type_lookup
 
 SYNOPSIS
-       const struct reloc_howto_struct *
+       reloc_howto_type *
        bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code);
 
 DESCRIPTION
@@ -1439,7 +2651,7 @@ DESCRIPTION
 */
 
 
-const struct reloc_howto_struct *
+reloc_howto_type *
 bfd_reloc_type_lookup (abfd, code)
      bfd *abfd;
      bfd_reloc_code_real_type code;
@@ -1456,7 +2668,7 @@ INTERNAL_FUNCTION
        bfd_default_reloc_type_lookup
 
 SYNOPSIS
-       const struct reloc_howto_struct *bfd_default_reloc_type_lookup
+       reloc_howto_type *bfd_default_reloc_type_lookup
        (bfd *abfd, bfd_reloc_code_real_type  code);
 
 DESCRIPTION
@@ -1465,7 +2677,7 @@ DESCRIPTION
 
 */
 
-const struct reloc_howto_struct *
+reloc_howto_type *
 bfd_default_reloc_type_lookup (abfd, code)
      bfd *abfd;
      bfd_reloc_code_real_type code;
@@ -1489,9 +2701,29 @@ bfd_default_reloc_type_lookup (abfd, code)
     default:
       BFD_FAIL ();
     }
-  return (const struct reloc_howto_struct *) NULL;
+  return (reloc_howto_type *) NULL;
 }
 
+/*
+FUNCTION
+       bfd_get_reloc_code_name
+
+SYNOPSIS
+       const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code);
+
+DESCRIPTION
+       Provides a printable name for the supplied relocation code.
+       Useful mainly for printing error messages.
+*/
+
+const char *
+bfd_get_reloc_code_name (code)
+     bfd_reloc_code_real_type code;
+{
+  if (code > BFD_RELOC_UNUSED)
+    return 0;
+  return bfd_reloc_code_real_names[(int)code];
+}
 
 /*
 INTERNAL_FUNCTION
@@ -1512,15 +2744,37 @@ DESCRIPTION
 /*ARGSUSED*/
 boolean
 bfd_generic_relax_section (abfd, section, link_info, again)
-     bfd *abfd;
-     asection *section;
-     struct bfd_link_info *link_info;
+     bfd *abfd ATTRIBUTE_UNUSED;
+     asection *section ATTRIBUTE_UNUSED;
+     struct bfd_link_info *link_info ATTRIBUTE_UNUSED;
      boolean *again;
 {
   *again = false;
   return true;
 }
 
+/*
+INTERNAL_FUNCTION
+       bfd_generic_gc_sections
+
+SYNOPSIS
+       boolean bfd_generic_gc_sections
+        (bfd *, struct bfd_link_info *);
+
+DESCRIPTION
+       Provides default handling for relaxing for back ends which
+       don't do section gc -- i.e., does nothing.
+*/
+
+/*ARGSUSED*/
+boolean
+bfd_generic_gc_sections (abfd, link_info)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     struct bfd_link_info *link_info ATTRIBUTE_UNUSED;
+{
+  return true;
+}
+
 /*
 INTERNAL_FUNCTION
        bfd_generic_get_relocated_section_contents
@@ -1561,12 +2815,9 @@ bfd_generic_get_relocated_section_contents (abfd, link_info, link_order, data,
   if (reloc_size < 0)
     goto error_return;
 
-  reloc_vector = (arelent **) malloc (reloc_size);
+  reloc_vector = (arelent **) bfd_malloc ((size_t) reloc_size);
   if (reloc_vector == NULL && reloc_size != 0)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      goto error_return;
-    }
+    goto error_return;
 
   /* read in the section */
   if (!bfd_get_section_contents (input_bfd,
This page took 0.055694 seconds and 4 git commands to generate.