* blockframe.c (create_new_frame, get_prev_frame_info):
[deliverable/binutils-gdb.git] / bfd / reloc.c
index 327a7eb40468408707d2c1ff86e77b2cb8233c5f..acce99e82591e17e51a0cd5dd9600cec1bb2dc29 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD support for handling relocation entries.
-   Copyright (C) 1990-1991 Free Software Foundation, Inc.
+   Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -33,7 +33,7 @@ SECTION
 
        All a back end has to do to fit the BFD interface is to create
        as many <<struct reloc_cache_entry>> as there are relocations
-       in a particuar section, and fill in the right bits:
+       in a particular section, and fill in the right bits:
 
 @menu
 @* typedef arelent::
@@ -65,7 +65,7 @@ CODE_FRAGMENT
 .       {* The relocation was performed, but there was an overflow. *}
 .  bfd_reloc_overflow,
 .
-.       {* The address to relocate was not within the section supplied*}
+.       {* The address to relocate was not within the section supplied*}
 .  bfd_reloc_outofrange,
 .
 .       {* Used by special functions *}
@@ -74,10 +74,10 @@ CODE_FRAGMENT
 .       {* Unused *}
 .  bfd_reloc_notsupported,
 .
-.       {* Unsupported relocation size requested.  *}
+.       {* Unsupported relocation size requested. *}
 .  bfd_reloc_other,
 .
-.       {* The symbol to relocate against was undefined.*}
+.       {* The symbol to relocate against was undefined. *}
 .  bfd_reloc_undefined,
 .
 .       {* The relocation was performed, but may not be ok - presently
@@ -94,7 +94,7 @@ CODE_FRAGMENT
 .  struct symbol_cache_entry **sym_ptr_ptr;
 .
 .       {* offset in section *}
-.  rawdata_offset address;
+.  bfd_size_type address;
 .
 .       {* addend for relocation value *}
 .  bfd_vma addend;    
@@ -181,7 +181,7 @@ DESCRIPTION
 |        jmp      r1
 
 
-        This whould create two relocs, both pointing to _foo, and with
+        This should create two relocs, both pointing to _foo, and with
         0x12340000 in their addend field. The data would consist of:
 
 
@@ -200,7 +200,7 @@ DESCRIPTION
         value of _foo. Note that all 32 bits have to be kept around
         somewhere, to cope with carry from bit 15 to bit 16.
 
-        On further example is the sparc and the a.out format. The
+        One further example is the sparc and the a.out format. The
         sparc has a similar problem to the 88k, in that some
         instructions don't have room for an entire offset, but on the
         sparc the parts are created odd sized lumps. The designers of
@@ -242,6 +242,34 @@ DESCRIPTION
         
 */
 
+/*
+SUBSUBSECTION
+       <<enum complain_overflow>>
+
+       Indicates what sort of overflow checking should be done when
+       performing a relocation.
+
+CODE_FRAGMENT
+.
+.enum complain_overflow
+.{
+.      {* Do not complain on overflow. *}
+.  complain_overflow_dont,
+.
+.      {* Complain if the bitfield overflows, whether it is considered
+.         as signed or unsigned. *}
+.  complain_overflow_bitfield,
+.
+.      {* Complain if the value overflows when considered as signed
+.         number. *}
+.  complain_overflow_signed,
+.
+.      {* Complain if the value overflows when considered as an
+.         unsigned number. *}
+.  complain_overflow_unsigned
+.};
+
+*/
 
 /*
 SUBSUBSECTION 
@@ -268,11 +296,12 @@ CODE_FRAGMENT
 .  unsigned int rightshift;
 .
 .       {*  The size of the item to be relocated - 0, is one byte, 1 is 2
-.           bytes, 3 is four bytes.  A -ve value indicates that the
-.          result is to be subtracted from the data*}
+.           bytes, 2 is four bytes.  A negative value indicates that the
+.          result is to be subtracted from the data.  *}
 .  int size;
 .
-.       {*  Now obsolete *}
+.       {*  The number of bits in the item to be relocated.  This is used
+.          when doing overflow checking.  *}
 .  unsigned int bitsize;
 .
 .       {*  Notes that the relocation is relative to the location in the
@@ -281,19 +310,17 @@ CODE_FRAGMENT
 .           being relocated. *}
 .  boolean pc_relative;
 .
-.       {*  Now obsolete *}
+.      {*  The bit position of the reloc value in the destination.
+.          The relocated value is left shifted by this amount. *}
 .  unsigned int bitpos;
 .
-.       {*  Now obsolete *}
-.  boolean absolute;
-.
-.       {* Causes the relocation routine to return an error if overflow
-.          is detected when relocating. *}
-.  boolean complain_on_overflow;
+.      {* What type of overflow error should be checked for when
+.         relocating. *}
+.  enum complain_overflow complain_on_overflow;
 .
 .       {* If this field is non null, then the supplied function is
 .          called rather than the normal function. This allows really
-.          strange relocation methods to be accomodated (eg, i960 callj
+.          strange relocation methods to be accomodated (e.g., i960 callj
 .          instructions). *}
 .  bfd_reloc_status_type (*special_function) 
 .                                  PARAMS ((bfd *abfd,
@@ -311,26 +338,26 @@ CODE_FRAGMENT
 .  boolean partial_inplace;
 .
 .       {* The src_mask is used to select what parts of the read in data
-.          are to be used in the relocation sum. Eg, if this was an 8 bit
+.          are to be used in the relocation sum.  E.g., if this was an 8 bit
 .          bit of data which we read and relocated, this would be
 .          0x000000ff. When we have relocs which have an addend, such as
 .          sun4 extended relocs, the value in the offset part of a
 .          relocating field is garbage so we never use it. In this case
 .          the mask would be 0x00000000. *}
-.  bfd_word src_mask;
+.  bfd_vma src_mask;
 .
 .       {* The dst_mask is what parts of the instruction are replaced
 .          into the instruction. In most cases src_mask == dst_mask,
 .          except in the above special case, where dst_mask would be
 .          0x000000ff, and src_mask would be 0x00000000.   *}
-.  bfd_word dst_mask;           
+.  bfd_vma dst_mask;           
 .
 .       {* When some formats create PC relative instructions, they leave
 .          the value of the pc of the place being relocated in the offset
 .          slot of the instruction, so that a PC relative relocation can
-.          be made just by adding in an ordinary offset (eg sun3 a.out).
+.          be made just by adding in an ordinary offset (e.g., sun3 a.out).
 .          Some formats leave the displacement part of an instruction
-.          empty (eg m88k bcs), this flag signals the fact.*}
+.          empty (e.g., m88k bcs), this flag signals the fact.*}
 .  boolean pcrel_offset;
 .
 .} reloc_howto_type;
@@ -345,15 +372,15 @@ DESCRIPTION
        The HOWTO define is horrible and will go away.
 
 
-.#define HOWTO(C, R,S,B, P, BI, ABS, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
-.  {(unsigned)C,R,S,B, P, BI, ABS,O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
+.#define HOWTO(C, R,S,B, P, BI, O, SF, 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
        moment, we are compatible, so do it this way..
 
 
-.#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,false,false,FUNCTION, NAME,false,0,0,IN)
+.#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,complain_overflow_dont,FUNCTION, NAME,false,0,0,IN)
 .
 DESCRIPTION
        Helper routine to turn a symbol into a relocation value.
@@ -361,7 +388,7 @@ DESCRIPTION
 .#define HOWTO_PREPARE(relocation, symbol)      \
 .  {                                            \
 .  if (symbol != (asymbol *)NULL) {             \
-.    if (symbol->section == &bfd_com_section) { \
+.    if (bfd_is_com_section (symbol->section)) { \
 .      relocation = 0;                          \
 .    }                                          \
 .    else {                                     \
@@ -411,7 +438,7 @@ DESCRIPTION
        state of the world. There are two ways of reflecting the
        results of partial linkage in an output file; by modifying the
        output data in place, and by modifying the relocation record.
-       Some native formats (eg basic a.out and basic coff) have no
+       Some native formats (e.g., basic a.out and basic coff) have no
        way of specifying an addend in the relocation type, so the
        addend has to go in the output data.  This is no big deal
        since in these formats the output data slot will always be big
@@ -435,7 +462,7 @@ DEFUN(bfd_perform_relocation,(abfd,
 {
   bfd_vma relocation;
   bfd_reloc_status_type flag = bfd_reloc_ok;
-  bfd_vma addr = reloc_entry->address ;
+  bfd_size_type addr = reloc_entry->address ;
   bfd_vma output_base = 0;
   reloc_howto_type *howto = reloc_entry->howto;
   asection *reloc_target_output_section ;
@@ -445,128 +472,190 @@ DEFUN(bfd_perform_relocation,(abfd,
   symbol = *( reloc_entry->sym_ptr_ptr);
   if ((symbol->section == &bfd_abs_section) 
       && output_bfd != (bfd *)NULL) 
-  {
-    reloc_entry->address += input_section->output_offset;
-       
-    return bfd_reloc_ok;
-       
-  }
+    {
+      reloc_entry->address += input_section->output_offset;
+      return bfd_reloc_ok;
+    }
 
-  if ((symbol->section == &bfd_und_section) && output_bfd == (bfd *)NULL) {
+  if ((symbol->section == &bfd_und_section) && output_bfd == (bfd *)NULL)
     flag = bfd_reloc_undefined;
-  }
 
-  if (howto->special_function) {
-    bfd_reloc_status_type cont;
-    cont = howto->special_function(abfd,
-                                  reloc_entry,
-                                  symbol,
-                                  data,
-                                  input_section,
-                                  output_bfd);
-    if (cont != bfd_reloc_continue) return cont;
-  }
+  /* 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;
+      cont = howto->special_function (abfd, reloc_entry, symbol, data,
+                                     input_section, output_bfd);
+      if (cont != bfd_reloc_continue)
+       return cont;
+    }
 
-  /* 
-    Work out which section the relocation is targetted at and the
-    initial relocation command value.
-    */
+  /* 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.  */
 
-  if (symbol->section == &bfd_com_section) {
+  /* Get symbol value.  (Common symbols are special.)  */
+  if (bfd_is_com_section (symbol->section))
     relocation = 0;
-  }
-  else {
+  else
     relocation = symbol->value;
-  }
 
 
   reloc_target_output_section = symbol->section->output_section;
 
-  if (output_bfd && howto->partial_inplace==false) {
+  /* Convert input-section-relative symbol value to absolute.  */
+  if (output_bfd && howto->partial_inplace==false)
     output_base = 0;
-  }
-  else {
+  else
     output_base = reloc_target_output_section->vma;
 
-  }
-
-  relocation += output_base +   symbol->section->output_offset;
-  
+  relocation += output_base + symbol->section->output_offset;
 
-  relocation += reloc_entry->addend ;
-
-
-  if(reloc_entry->address > input_section->_cooked_size)
-  {
-    return bfd_reloc_outofrange;
-  }
-          
+  /* Add in supplied addend.  */
+  relocation += reloc_entry->addend;
 
   if (howto->pc_relative == true)
-  {
-    /*
-      Anything which started out as pc relative should end up that
-      way too. 
-      
-      There are two ways we can see a pcrel instruction. Sometimes
-      the pcrel displacement has been partially calculated, it
-      includes the distance from the start of the section to the
-      instruction in it (eg sun3), and sometimes the field is
-      totally blank - eg m88kbcs.
-      */
+    {
+      /* Anything which started out as pc relative should end up that
+        way too. 
 
-        
-    relocation -= 
-     input_section->output_section->vma + input_section->output_offset;
+        There are two ways we can see a pcrel instruction. Sometimes
+        the pcrel displacement has been partially calculated, it
+        includes the distance from the start of the section to the
+        instruction in it (e.g., sun3), and sometimes the field is
+        totally blank - e.g., m88kbcs.  */
 
-    if (howto->pcrel_offset == true) {
-      relocation -= reloc_entry->address;
-    }
+      relocation -= 
+       input_section->output_section->vma + input_section->output_offset;
 
-  }
+      if (howto->pcrel_offset == true)
+       relocation -= reloc_entry->address;
+    }
 
   if (output_bfd!= (bfd *)NULL) 
-  {
-    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;
+      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) 
+           {
+             relocation -= reloc_entry->addend;
+             reloc_entry->addend = 0;
+           }
+         else
+           {
+             reloc_entry->addend = relocation;
+           }
+       }
     }
-    else 
+  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->addend = 0;
+    }
 
-      reloc_entry->address += input_section->output_offset;
+  /* 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)
+    {
+      bfd_vma check;
 
-      if (abfd->xvec->flavour == bfd_target_coff_flavour) 
-      {
-       relocation -= reloc_entry->addend;
-       reloc_entry->addend = 0;
-      }
+      /* 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);
       else
-      {
-       reloc_entry->addend = relocation  ;
-      }
+       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 ();
+       }
     }
-  }
-  else 
-  {
-    reloc_entry->addend = 0;
-  }
   
-
   /* 
     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
@@ -615,45 +704,59 @@ DEFUN(bfd_perform_relocation,(abfd,
   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 + addr);
-      DOIT(x);
-      bfd_put_8(abfd,x, (unsigned char *) data + addr);
-    }
-     break;
-
-    case 1:
-    { 
-      short x = bfd_get_16(abfd, (bfd_byte *)data + addr);
-      DOIT(x);
-      bfd_put_16(abfd, x,   (unsigned char *)data + addr);
-    }
-     break;
-    case 2:
-    {
-      long  x = bfd_get_32(abfd, (bfd_byte *) data + addr);
-      DOIT(x);
-      bfd_put_32(abfd,x,    (bfd_byte *)data + addr);
-    }      
-     break;
-    case -2:
-    {
-      long  x = bfd_get_32(abfd, (bfd_byte *) data + addr);
-      relocation = -relocation;
-      DOIT(x);
-      bfd_put_32(abfd,x,    (bfd_byte *)data + addr);
-    }      
-     break;
-
-    case 3:
-
-     /* Do nothing */
-     break;
-    default:
-     return bfd_reloc_other;
-   }
+     {
+     case 0:
+       {
+        char x = bfd_get_8(abfd, (char *)data + addr);
+        DOIT(x);
+        bfd_put_8(abfd,x, (unsigned char *) data + addr);
+       }
+       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);
+        }
+       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);
+        }
+       break;
+     case -2:
+       {
+        long  x = bfd_get_32(abfd, (bfd_byte *) data + addr);
+        relocation = -relocation;
+        DOIT(x);
+        bfd_put_32(abfd,x,    (bfd_byte *)data + addr);
+       }
+       break;
+
+     case 3:
+       /* Do nothing */
+       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
+       break;
+     default:
+       return bfd_reloc_other;
+     }
 
   return flag;
 }
@@ -686,17 +789,27 @@ CODE_FRAGMENT
 .typedef enum bfd_reloc_code_real 
 .
 .{
+.      {* 64 bits wide, simple reloc *}
+.  BFD_RELOC_64,
+.      {* 64 bits, PC-relative *}
+.  BFD_RELOC_64_PCREL,
+.
+.       {* 32 bits wide, simple reloc *}
+.  BFD_RELOC_32,
+.      {* 32 bits, PC-relative *}
+.  BFD_RELOC_32_PCREL,
+.
 .       {* 16 bits wide, simple reloc *}
 .  BFD_RELOC_16,        
-.
-.       {* 8 bits wide, but used to form an address like 0xffnn *}
-.  BFD_RELOC_8_FFnn,
+.      {* 16 bits, PC-relative *}
+.  BFD_RELOC_16_PCREL,
 .
 .       {* 8 bits wide, simple *}
 .  BFD_RELOC_8,
-.
 .       {* 8 bits wide, pc relative *}
 .  BFD_RELOC_8_PCREL,
+.       {* 8 bits wide, but used to form an address like 0xffnn *}
+.  BFD_RELOC_8_FFnn,
 .
 .       {* The type of reloc used to build a contructor table - at the
 .          moment probably a 32 bit wide abs address, but the cpu can
@@ -704,11 +817,6 @@ CODE_FRAGMENT
 .
 .  BFD_RELOC_CTOR,
 .
-.       {* 32 bits wide, simple reloc *}
-.  BFD_RELOC_32,
-.      {* 32 bits, PC-relative *}
-.  BFD_RELOC_32_PCREL,
-.
 .      {* High 22 bits of 32-bit value; simple reloc.  *}
 .  BFD_RELOC_HI22,
 .      {* Low 10 bits.  *}
@@ -718,7 +826,6 @@ CODE_FRAGMENT
 .  BFD_RELOC_24_PCREL,
 .  BFD_RELOC_I960_CALLJ,
 .
-.  BFD_RELOC_16_PCREL,
 .      {* 32-bit pc-relative, shifted right 2 bits (i.e., 30-bit
 .         word displacement, e.g. for SPARC) *}
 .  BFD_RELOC_32_PCREL_S2,
@@ -728,7 +835,6 @@ CODE_FRAGMENT
 .  BFD_RELOC_SPARC_WDISP22,
 .  BFD_RELOC_SPARC22,
 .  BFD_RELOC_SPARC13,
-.  BFD_RELOC_SPARC_BASE13,
 .  BFD_RELOC_SPARC_GOT10,
 .  BFD_RELOC_SPARC_GOT13,
 .  BFD_RELOC_SPARC_GOT22,
@@ -742,8 +848,147 @@ CODE_FRAGMENT
 .  BFD_RELOC_SPARC_UA32,
 .
 .  {* this one is a.out specific? *}
+.  BFD_RELOC_SPARC_BASE13,
 .  BFD_RELOC_SPARC_BASE22,
 .
+.  {* start-sanitize-v9 *}
+.  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,
+.  {* end-sanitize-v9 *}
+.
+.       {* Bits 27..2 of the relocation address shifted right 2 bits;
+.         simple reloc otherwise.  *}
+.  BFD_RELOC_MIPS_JMP,
+.
+.       {* signed 16-bit pc-relative, shifted right 2 bits (e.g. for MIPS) *}
+.  BFD_RELOC_16_PCREL_S2,
+.
+.       {* 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,
+.
+.      {* 16 bit relocation relative to the global pointer.  *}
+.  BFD_RELOC_MIPS_GPREL,
+.
+.       {* These are, so far, specific to HPPA processors.  I'm not sure that
+.         some don't duplicate other reloc types, such as BFD_RELOC_32 and
+.         _32_PCREL.  Also, many more were in the list I got that don't
+.         fit in well in the model BFD uses, so I've omitted them for now.
+.         If we do make this reloc type get used for code that really does
+.         implement the funky reloc types, they'll have to be added to this
+.         list.   *}
+.  BFD_RELOC_HPPA_32,
+.  BFD_RELOC_HPPA_11,
+.  BFD_RELOC_HPPA_14,
+.  BFD_RELOC_HPPA_17,
+.  BFD_RELOC_HPPA_L21,
+.  BFD_RELOC_HPPA_R11,
+.  BFD_RELOC_HPPA_R14,
+.  BFD_RELOC_HPPA_R17,
+.  BFD_RELOC_HPPA_LS21,
+.  BFD_RELOC_HPPA_RS11,
+.  BFD_RELOC_HPPA_RS14,
+.  BFD_RELOC_HPPA_RS17,
+.  BFD_RELOC_HPPA_LD21,
+.  BFD_RELOC_HPPA_RD11,
+.  BFD_RELOC_HPPA_RD14,
+.  BFD_RELOC_HPPA_RD17,
+.  BFD_RELOC_HPPA_LR21,
+.  BFD_RELOC_HPPA_RR14,
+.  BFD_RELOC_HPPA_RR17,
+.  BFD_RELOC_HPPA_GOTOFF_11,
+.  BFD_RELOC_HPPA_GOTOFF_14,
+.  BFD_RELOC_HPPA_GOTOFF_L21,
+.  BFD_RELOC_HPPA_GOTOFF_R11,
+.  BFD_RELOC_HPPA_GOTOFF_R14,
+.  BFD_RELOC_HPPA_GOTOFF_LS21,
+.  BFD_RELOC_HPPA_GOTOFF_RS11,
+.  BFD_RELOC_HPPA_GOTOFF_RS14,
+.  BFD_RELOC_HPPA_GOTOFF_LD21,
+.  BFD_RELOC_HPPA_GOTOFF_RD11,
+.  BFD_RELOC_HPPA_GOTOFF_RD14,
+.  BFD_RELOC_HPPA_GOTOFF_LR21,
+.  BFD_RELOC_HPPA_GOTOFF_RR14,
+.  BFD_RELOC_HPPA_DLT_32,
+.  BFD_RELOC_HPPA_DLT_11,
+.  BFD_RELOC_HPPA_DLT_14,
+.  BFD_RELOC_HPPA_DLT_L21,
+.  BFD_RELOC_HPPA_DLT_R11,
+.  BFD_RELOC_HPPA_DLT_R14,
+.  BFD_RELOC_HPPA_ABS_CALL_11,
+.  BFD_RELOC_HPPA_ABS_CALL_14,
+.  BFD_RELOC_HPPA_ABS_CALL_17,
+.  BFD_RELOC_HPPA_ABS_CALL_L21,
+.  BFD_RELOC_HPPA_ABS_CALL_R11,
+.  BFD_RELOC_HPPA_ABS_CALL_R14,
+.  BFD_RELOC_HPPA_ABS_CALL_R17,
+.  BFD_RELOC_HPPA_ABS_CALL_LS21,
+.  BFD_RELOC_HPPA_ABS_CALL_RS11,
+.  BFD_RELOC_HPPA_ABS_CALL_RS14,
+.  BFD_RELOC_HPPA_ABS_CALL_RS17,
+.  BFD_RELOC_HPPA_ABS_CALL_LD21,
+.  BFD_RELOC_HPPA_ABS_CALL_RD11,
+.  BFD_RELOC_HPPA_ABS_CALL_RD14,
+.  BFD_RELOC_HPPA_ABS_CALL_RD17,
+.  BFD_RELOC_HPPA_ABS_CALL_LR21,
+.  BFD_RELOC_HPPA_ABS_CALL_RR14,
+.  BFD_RELOC_HPPA_ABS_CALL_RR17,
+.  BFD_RELOC_HPPA_PCREL_CALL_11,
+.  BFD_RELOC_HPPA_PCREL_CALL_12,
+.  BFD_RELOC_HPPA_PCREL_CALL_14,
+.  BFD_RELOC_HPPA_PCREL_CALL_17,
+.  BFD_RELOC_HPPA_PCREL_CALL_L21,
+.  BFD_RELOC_HPPA_PCREL_CALL_R11,
+.  BFD_RELOC_HPPA_PCREL_CALL_R14,
+.  BFD_RELOC_HPPA_PCREL_CALL_R17,
+.  BFD_RELOC_HPPA_PCREL_CALL_LS21,
+.  BFD_RELOC_HPPA_PCREL_CALL_RS11,
+.  BFD_RELOC_HPPA_PCREL_CALL_RS14,
+.  BFD_RELOC_HPPA_PCREL_CALL_RS17,
+.  BFD_RELOC_HPPA_PCREL_CALL_LD21,
+.  BFD_RELOC_HPPA_PCREL_CALL_RD11,
+.  BFD_RELOC_HPPA_PCREL_CALL_RD14,
+.  BFD_RELOC_HPPA_PCREL_CALL_RD17,
+.  BFD_RELOC_HPPA_PCREL_CALL_LR21,
+.  BFD_RELOC_HPPA_PCREL_CALL_RR14,
+.  BFD_RELOC_HPPA_PCREL_CALL_RR17,
+.  BFD_RELOC_HPPA_PLABEL_32,
+.  BFD_RELOC_HPPA_PLABEL_11,
+.  BFD_RELOC_HPPA_PLABEL_14,
+.  BFD_RELOC_HPPA_PLABEL_L21,
+.  BFD_RELOC_HPPA_PLABEL_R11,
+.  BFD_RELOC_HPPA_PLABEL_R14,
+.  BFD_RELOC_HPPA_UNWIND_ENTRY,
+.  BFD_RELOC_HPPA_UNWIND_ENTRIES,
+.
+.  {* 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,
+.
 .  {* this must be the highest numeric value *}
 .  BFD_RELOC_UNUSED
 . } bfd_reloc_code_real_type;
@@ -776,7 +1021,7 @@ DEFUN(bfd_reloc_type_lookup,(abfd, code),
 }
 
 static reloc_howto_type bfd_howto_32 =
- HOWTO(0, 00,2,32,false,0,false,true,0,"VRT32", false,0xffffffff,0xffffffff,true);
+ HOWTO(0, 00,2,32,false,0,complain_overflow_bitfield,0,"VRT32", false,0xffffffff,0xffffffff,true);
 
 
 /*
@@ -785,38 +1030,39 @@ INTERNAL_FUNCTION
 
 SYNOPSIS
        CONST struct reloc_howto_struct *bfd_default_reloc_type_lookup
-       (CONST struct bfd_arch_info *,
+       (bfd *abfd AND
          bfd_reloc_code_real_type  code);
 
 DESCRIPTION
-       Provides a default relocation lookuperer for any architectue 
+       Provides a default relocation lookup routine for any architecture.
 
 
 */
+
 CONST struct reloc_howto_struct *
-DEFUN(bfd_default_reloc_type_lookup,(arch,  code),
-     CONST struct bfd_arch_info *arch AND
-      bfd_reloc_code_real_type  code)
+DEFUN(bfd_default_reloc_type_lookup, (abfd, code),
+      bfd *abfd AND
+      bfd_reloc_code_real_type code)
 {
-    switch (code) 
+  switch (code) 
     {
-       case BFD_RELOC_CTOR:
-       /* The type of reloc used in a ctor, which will be as wide as the
-          address - so either a 64, 32, or 16 bitter.. */
-       switch (arch->bits_per_address) {
-          case 64:
-           BFD_FAIL();
-          case 32:
-           return &bfd_howto_32;
-          case 16:
-           BFD_FAIL();
-          default:
-           BFD_FAIL();
-       }
-       default:
+    case BFD_RELOC_CTOR:
+      /* The type of reloc used in a ctor, which will be as wide as the
+        address - so either a 64, 32, or 16 bitter.. */
+      switch (bfd_get_arch_info (abfd)->bits_per_address) {
+      case 64:
+       BFD_FAIL();
+      case 32:
+       return &bfd_howto_32;
+      case 16:
        BFD_FAIL();
+      default:
+       BFD_FAIL();
+      }
+    default:
+      BFD_FAIL();
     }
-return (CONST struct reloc_howto_struct *)NULL;
+  return (CONST struct reloc_howto_struct *)NULL;
 }
 
 
@@ -853,9 +1099,10 @@ INTERNAL_FUNCTION
 
 SYNOPSIS
        bfd_byte *
-          bfd_generic_get_relocated_section_contents(bfd *abfd,
-            struct bfd_seclet_struct  *seclet,
-            bfd_byte *data)
+          bfd_generic_get_relocated_section_contents (bfd *abfd,
+            struct bfd_seclet *seclet,
+            bfd_byte *data,
+            boolean relocateable);
 
 DESCRIPTION
        Provides default handling of relocation effort for back ends
@@ -864,10 +1111,14 @@ DESCRIPTION
 */
 
 bfd_byte *
-DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet, data),
+DEFUN(bfd_generic_get_relocated_section_contents,(abfd,
+                                                 seclet,
+                                                 data,
+                                                 relocateable),
       bfd *abfd AND
-      struct bfd_seclet_struct *seclet AND
-      bfd_byte *data)
+      struct bfd_seclet *seclet AND
+      bfd_byte *data AND
+      boolean relocateable)
 {
   extern bfd_error_vector_type bfd_error_vector;
 
@@ -877,8 +1128,7 @@ DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet, data),
 
 
 
-  bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
-                                                      input_section);
+  size_t reloc_size = bfd_get_reloc_upper_bound(input_bfd, input_section);
   arelent **reloc_vector = (arelent **) alloca(reloc_size);
   
   /* read in the section */
@@ -906,8 +1156,17 @@ DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet, data),
        bfd_perform_relocation(input_bfd,
                              *parent,
                              data,
-                             input_section, 0);
+                             input_section,
+                             relocateable ? abfd : (bfd *) NULL);
       
+      if (relocateable)
+       {
+         asection *os = input_section->output_section;
+
+         /* A partial link, so keep the relocs */
+         os->orelocation[os->reloc_count] = *parent;
+         os->reloc_count++;
+       }
 
       if (r != bfd_reloc_ok) 
       {
@@ -937,4 +1196,3 @@ DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet, data),
 
   
 }
-
This page took 0.034455 seconds and 4 git commands to generate.