Still a lot of bogus code; just a checkpoint.
[deliverable/binutils-gdb.git] / bfd / reloc.c
index 6a9e8aebca1d27e84dd8cd8181042453dae72bca..78a92416e8122807eac262636f6d7e8729110a3d 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD support for handling relocation entries.
-   Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1997
+   Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -411,14 +411,14 @@ FUNCTION
        bfd_get_reloc_size
 
 SYNOPSIS
-       int bfd_get_reloc_size (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)
      reloc_howto_type *howto;
 {
@@ -451,6 +451,112 @@ DESCRIPTION
 */
 
 
+/*
+FUNCTION
+       bfd_check_overflow
+
+SYNOPSIS
+       bfd_reloc_status_type
+               bfd_check_overflow
+                       (enum complain_overflow how,
+                        unsigned int bitsize,
+                        unsigned int rightshift,
+                        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.
+       The result is either of @code{bfd_reloc_ok} or
+       @code{bfd_reloc_overflow}.
+
+*/
+
+bfd_reloc_status_type
+bfd_check_overflow (how, bitsize, rightshift, relocation)
+     enum complain_overflow how;
+     unsigned int bitsize, rightshift;
+     bfd_vma relocation;
+{
+  bfd_vma check;
+  bfd_reloc_status_type flag = bfd_reloc_ok;
+
+  /* Get the value that will be used for the relocation, but
+     starting at bit position zero.  */
+  check = relocation >> rightshift;
+
+  switch (how)
+    {
+    case complain_overflow_dont:
+      break;
+
+    case complain_overflow_signed:
+      {
+       /* Assumes two's complement.  */
+       bfd_signed_vma reloc_signed_max =
+         ((bfd_signed_vma) 1 << (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 (rightshift > 0
+           && (bfd_signed_vma) relocation < 0)
+         check |= ((bfd_vma) - 1
+                   & ~((bfd_vma) - 1
+                       >> rightshift));
+       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 `bitsize' is the number of bits in
+          bfd_vma.  */
+       bfd_vma reloc_unsigned_max =
+         ((((bfd_vma) 1 << (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 `bitsize' is the number of bits in
+          bfd_vma.  */
+       bfd_vma reloc_bits = (((1 << (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 (rightshift > 0
+               && (bfd_signed_vma) relocation < 0)
+             {
+               check |= ((bfd_vma) - 1
+                         & ~((bfd_vma) - 1
+                             >> rightshift));
+               if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
+                 flag = bfd_reloc_overflow;
+             }
+           else
+             flag = bfd_reloc_overflow;
+         }
+      }
+      break;
+
+    default:
+      abort ();
+    }
+
+  return flag;
+}
+
 
 /*
 FUNCTION
@@ -721,75 +827,8 @@ space consuming.  For each target:
      adding in the value contained in the object file.  */
   if (howto->complain_on_overflow != complain_overflow_dont
       && flag == bfd_reloc_ok)
-    {
-      bfd_vma check;
-
-      /* Get the value that will be used for the relocation, but
-        starting at bit position zero.  */
-      check = relocation >> 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 > 0
-               && (bfd_signed_vma) relocation < 0)
-             check |= ((bfd_vma) - 1
-                       & ~((bfd_vma) - 1
-                           >> howto->rightshift));
-           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 > 0
-                   && (bfd_signed_vma) relocation < 0)
-                 {
-                   check |= ((bfd_vma) - 1
-                             & ~((bfd_vma) - 1
-                                 >> howto->rightshift));
-                   if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
-                     flag = bfd_reloc_overflow;
-                 }
-               else
-                 flag = bfd_reloc_overflow;
-             }
-         }
-         break;
-       default:
-         abort ();
-       }
-    }
+    flag = bfd_check_overflow (howto->complain_on_overflow, howto->bitsize,
+                              howto->rightshift, relocation);
 
   /*
     Either we are relocating all the way, or we don't want to apply
@@ -1172,79 +1211,11 @@ space consuming.  For each target:
      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)
-    {
-      bfd_vma check;
-
-      /* Get the value that will be used for the relocation, but
-        starting at bit position zero.  */
-      check = relocation >> 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 > 0
-               && (bfd_signed_vma) relocation < 0)
-             check |= ((bfd_vma) - 1
-                       & ~((bfd_vma) - 1
-                           >> howto->rightshift));
-           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 > 0
-                   && (bfd_signed_vma) relocation < 0)
-                 {
-                   check |= ((bfd_vma) - 1
-                             & ~((bfd_vma) - 1
-                                 >> howto->rightshift));
-                   if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
-                     flag = bfd_reloc_overflow;
-                 }
-               else
-                 flag = bfd_reloc_overflow;
-             }
-         }
-         break;
-       default:
-         abort ();
-       }
-    }
+    flag = bfd_check_overflow (howto->complain_on_overflow, howto->bitsize,
+                              howto->rightshift, relocation);
 
   /*
     Either we are relocating all the way, or we don't want to apply
@@ -1376,8 +1347,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
@@ -1553,7 +1525,8 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
        case complain_overflow_signed:
          {
            /* Assumes two's complement.  */
-           bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+           bfd_signed_vma reloc_signed_max =
+             ((bfd_signed_vma) 1 << (howto->bitsize - 1)) - 1;
            bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
 
            if (signed_check > reloc_signed_max
@@ -1567,7 +1540,7 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
               overflow if howto->bitsize is the number of bits in
               bfd_vma.  */
            bfd_vma reloc_unsigned_max =
-           (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+             ((((bfd_vma) 1 << (howto->bitsize - 1)) - 1) << 1) | 1;
 
            if (check > reloc_unsigned_max)
              overflow = true;
@@ -1875,8 +1848,30 @@ 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_32LE
 ENUMDOC
-  Some relocations we're using for SPARC V9 -- subject to change.
+  SPARC little endian relocation
 
 ENUM
   BFD_RELOC_ALPHA_GPDISP_HI16
@@ -2020,9 +2015,40 @@ ENUMX
   BFD_RELOC_MIPS_CALL_HI16
 ENUMX
   BFD_RELOC_MIPS_CALL_LO16
+COMMENT
+{* start-sanitize-r5900 *}
+ENUMX
+  BFD_RELOC_MIPS15_S3
+COMMENT
+{* end-sanitize-r5900 *}
 ENUMDOC
   MIPS ELF relocations.
 
+COMMENT
+{* start-sanitize-sky *}
+ENUM
+  BFD_RELOC_MIPS_DVP_11_PCREL
+ENUMDOC
+  MIPS DVP Relocations.
+  This is an 11-bit pc relative reloc.  The recorded address is for the
+  lower instruction word, and the value is in 128 bit units.
+ENUM
+  BFD_RELOC_MIPS_DVP_27_S4
+ENUMDOC
+  This is a 27 bit address left shifted by 4.
+ENUM
+  BFD_RELOC_MIPS_DVP_11_S4
+ENUMDOC
+  This is the 11 bit offset operand of ilw/stw instructions
+  left shifted by 4.
+ENUM
+  BFD_RELOC_MIPS_DVP_U15_S3
+ENUMDOC
+  This is the 15 bit unsigned immediate operand of the iaddiu instruction
+  left shifted by 3.
+COMMENT
+{* end-sanitize-sky *}
+
 ENUM
   BFD_RELOC_386_GOT32
 ENUMX
@@ -2243,7 +2269,6 @@ ENUMDOC
   stored in the instruction.  The high 24 bits are installed in bits 23
   through 0.
 
-COMMENT
 ENUM
   BFD_RELOC_D10V_10_PCREL_R
 ENUMDOC
@@ -2268,10 +2293,7 @@ ENUM
 ENUMDOC
   This is an 18-bit reloc with the right 2 bits
   assumed to be 0.
-COMMENT
 
-COMMENT
-{* start-sanitize-d30v *}
 ENUM
   BFD_RELOC_D30V_6
 ENUMDOC
@@ -2331,8 +2353,6 @@ ENUM
   BFD_RELOC_D30V_32_PCREL
 ENUMDOC
   This is a 32-bit pc-relative reloc.
-COMMENT
-{* end-sanitize-d30v *}
 
 ENUM
   BFD_RELOC_M32R_24
@@ -2458,6 +2478,37 @@ ENUM
 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_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
@@ -2584,6 +2635,28 @@ bfd_generic_relax_section (abfd, section, link_info, again)
   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;
+     struct bfd_link_info *link_info;
+{
+  return true;
+}
+
 /*
 INTERNAL_FUNCTION
        bfd_generic_get_relocated_section_contents
This page took 0.027672 seconds and 4 git commands to generate.