* bfd/aoutx.h (aout_link_input_section_std,
authorIan Lance Taylor <ian@airs.com>
Mon, 24 Jan 1994 20:23:18 +0000 (20:23 +0000)
committerIan Lance Taylor <ian@airs.com>
Mon, 24 Jan 1994 20:23:18 +0000 (20:23 +0000)
aout_link_input_section_ext): Pass additional arguments to
reloc_overflow callback.
* coff-alpha.c (alpha_ecoff_get_relocated_section_contents,
alpha_relocat_section): Likewise.
* coff-h8300.c (h8300_reloc16_extra_cases): Likewise.
* coff-h8500.c (extra_case): Likewise.
* coff-mips.c (mips_relocate_section): Likewise.
* coff-z8k.c (extra_case): Likewise.
* elf32-hppa.c (hppa_elf_stub_finish): Likewise.
* reloc.c (bfd_generic_get_relocated_section_contents): Likewise.

bfd/ChangeLog
bfd/aoutx.h
bfd/coff-alpha.c
bfd/coff-h8300.c
bfd/coff-h8500.c
bfd/coff-mips.c
bfd/coff-z8k.c
bfd/elf32-hppa.c
bfd/reloc.c

index bd165d2ca1e8550ed47ffeb783beec21d13050e6..52587594b262c0c45a6e34798acd6294cee6d625 100644 (file)
@@ -1,5 +1,17 @@
 Mon Jan 24 12:38:54 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
 
+       * bfd/aoutx.h (aout_link_input_section_std,
+       aout_link_input_section_ext): Pass additional arguments to
+       reloc_overflow callback.
+       * coff-alpha.c (alpha_ecoff_get_relocated_section_contents,
+       alpha_relocat_section): Likewise.
+       * coff-h8300.c (h8300_reloc16_extra_cases): Likewise.
+       * coff-h8500.c (extra_case): Likewise.
+       * coff-mips.c (mips_relocate_section): Likewise.
+       * coff-z8k.c (extra_case): Likewise.
+       * elf32-hppa.c (hppa_elf_stub_finish): Likewise.
+       * reloc.c (bfd_generic_get_relocated_section_contents): Likewise.
+
        * bout.c (calljx_callback, callj_callback): Use get_value to get
        the symbol value and check for undefined symbols.
        (get_value): If the symbol is undefined, look it up in the linker
index b7d2d44ab0e97aaa3b1f64929f02dff1e0afaeee..2f70cd36438eea8c327611b645c8d3698a9f3c5b 100644 (file)
@@ -4253,9 +4253,24 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
            case bfd_reloc_outofrange:
              abort ();
            case bfd_reloc_overflow:
-             if (! ((*finfo->info->callbacks->reloc_overflow)
-                    (finfo->info, input_bfd, input_section, r_addr)))
-               return false;
+             {
+               const char *name;
+
+               if (r_extern)
+                 name = strings + GET_WORD (input_bfd,
+                                            syms[r_index].e_strx);
+               else
+                 {
+                   asection *s;
+
+                   s = aout_reloc_index_to_section (input_bfd, r_index);
+                   name = bfd_section_name (input_bfd, s);
+                 }
+               if (! ((*finfo->info->callbacks->reloc_overflow)
+                      (finfo->info, name, howto_table_std[howto_idx].name,
+                       (bfd_vma) 0, input_bfd, input_section, r_addr)))
+                 return false;
+             }
              break;
            }
        }
@@ -4539,9 +4554,24 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
                case bfd_reloc_outofrange:
                  abort ();
                case bfd_reloc_overflow:
-                 if (! ((*finfo->info->callbacks->reloc_overflow)
-                        (finfo->info, input_bfd, input_section, r_addr)))
-                   return false;
+                 {
+                   const char *name;
+
+                   if (r_extern)
+                     name = strings + GET_WORD (input_bfd,
+                                                syms[r_index].e_strx);
+                   else
+                     {
+                       asection *s;
+
+                       s = aout_reloc_index_to_section (input_bfd, r_index);
+                       name = bfd_section_name (input_bfd, s);
+                     }
+                   if (! ((*finfo->info->callbacks->reloc_overflow)
+                          (finfo->info, name, howto_table_ext[r_type].name,
+                           r_addend, input_bfd, input_section, r_addr)))
+                     return false;
+                 }
                  break;
                }
            }
index 9153d02a8592472399f3dc712d5ff9d0867fad5c..5a35d7d2116e497636b0142056e132aa91e8d1ba 100644 (file)
@@ -1032,7 +1032,9 @@ alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order,
              break;
            case bfd_reloc_overflow:
              if (! ((*link_info->callbacks->reloc_overflow)
-                    (link_info, input_bfd, input_section, rel->address)))
+                    (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
+                     rel->howto->name, rel->addend, input_bfd,
+                     input_section, rel->address)))
                return NULL;
              break;
            case bfd_reloc_outofrange:
@@ -1749,10 +1751,20 @@ alpha_relocate_section (output_bfd, info, input_bfd, input_section,
                case bfd_reloc_outofrange:
                  abort ();
                case bfd_reloc_overflow:
-                 if (! ((*info->callbacks->reloc_overflow)
-                        (info, input_bfd, input_section,
-                         r_vaddr - input_section->vma)))
-                   return false;
+                 {
+                   const char *name;
+
+                   if (r_extern)
+                     name = sym_hashes[r_symndx]->root.root.string;
+                   else
+                     name = bfd_section_name (input_bfd,
+                                              symndx_to_section[r_symndx]);
+                   if (! ((*info->callbacks->reloc_overflow)
+                          (info, name, alpha_howto_table[r_type].name,
+                           (bfd_vma) 0, input_bfd, input_section,
+                           r_vaddr - input_section->vma)))
+                     return false;
+                 }
                  break;
                }
            }
index 5ae8833f78f6f3244ed23d5c27550eca46b236c5..75b7a81435e545f7742a7338d5d16e16041ceec0 100644 (file)
@@ -20,13 +20,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
-#include "libbfd.h"
 #include "obstack.h"
+#include "libbfd.h"
+#include "bfdlink.h"
 #include "coff/h8300.h"
 #include "coff/internal.h"
-#include "seclet.h"
 #include "libcoff.h"
-extern bfd_error_vector_type bfd_error_vector;
 
 static reloc_howto_type howto_table[] =
 {
@@ -178,11 +177,12 @@ DEFUN (reloc_processing, (relent, reloc, symbols, abfd, section),
 
 
 static int
-h8300_reloc16_estimate(input_section, symbols, reloc, shrink)
+h8300_reloc16_estimate(input_section, symbols, reloc, shrink, link_info)
      asection *input_section;
      asymbol **symbols;
      arelent *reloc;
      unsigned int shrink;
+     struct bfd_link_info *link_info;
 {
   bfd_vma value;  
   bfd_vma dot;
@@ -207,8 +207,8 @@ h8300_reloc16_estimate(input_section, symbols, reloc, shrink)
 
       /* Thing is a move one byte */
     case R_MOVB1:
-      value = bfd_coff_reloc16_get_value(reloc,0);
-       
+      value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+
       if (value >= 0xff00)
        { 
 
@@ -227,7 +227,7 @@ h8300_reloc16_estimate(input_section, symbols, reloc, shrink)
        actual data */
 
     case R_JMPL1:
-      value = bfd_coff_reloc16_get_value(reloc, 0);
+      value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
        
       dot = input_section->output_section->vma +
        input_section->output_offset + address;
@@ -252,7 +252,7 @@ h8300_reloc16_estimate(input_section, symbols, reloc, shrink)
 
     case R_JMP1:
 
-      value = bfd_coff_reloc16_get_value(reloc, 0);
+      value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
        
       dot = input_section->output_section->vma +
        input_section->output_offset + address;
@@ -296,9 +296,11 @@ h8300_reloc16_estimate(input_section, symbols, reloc, shrink)
 */
 
 static void
-h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
+h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
+                          dst_ptr)
      bfd *abfd;
-     struct bfd_seclet *seclet;
+     struct bfd_link_info *link_info;
+     struct bfd_link_order *link_order;
      arelent *reloc;
      bfd_byte *data;
      unsigned int *src_ptr;
@@ -306,6 +308,7 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
 {
   unsigned int src_address = *src_ptr;
   unsigned int dst_address = *dst_ptr;
+  asection *input_section = link_order->u.indirect.section;
 
   switch (reloc->howto->type)
     {
@@ -313,13 +316,18 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
         the byte before the 24bit hole, so we can treat it as a 32bit pointer */
     case R_PCRBYTE:
       {
-       bfd_vma dot = seclet->offset 
+       bfd_vma dot = link_order->offset 
          + dst_address 
-           + seclet->u.indirect.section->output_section->vma;
-       int gap = bfd_coff_reloc16_get_value (reloc, seclet) - dot;
+           + link_order->u.indirect.section->output_section->vma;
+       int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
+                  - dot);
        if (gap > 127 || gap < -128)
          {
-           bfd_error_vector.reloc_value_truncated (reloc, seclet);
+           if (! ((*link_info->callbacks->reloc_overflow)
+                  (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+                   reloc->howto->name, reloc->addend, input_section->owner,
+                   input_section, reloc->address)))
+             abort ();
          }
 
        bfd_put_8 (abfd, gap, data + dst_address);
@@ -331,10 +339,15 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
 
     case R_RELBYTE:
       {
-       unsigned int gap = bfd_coff_reloc16_get_value (reloc, seclet);
+       unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
+                                                      input_section);
        if (gap > 0xff && gap < ~0xff)
          {
-           bfd_error_vector.reloc_value_truncated (reloc, seclet);
+           if (! ((*link_info->callbacks->reloc_overflow)
+                  (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+                   reloc->howto->name, reloc->addend, input_section->owner,
+                   input_section, reloc->address)))
+             abort ();
          }
 
        bfd_put_8 (abfd, gap, data + dst_address);
@@ -350,13 +363,15 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
       /* A relword which would like to have been modified but
             didn't make it */
     case R_RELWORD:
-      bfd_put_16 (abfd, bfd_coff_reloc16_get_value (reloc, seclet),
+      bfd_put_16 (abfd,
+                 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
                  data + dst_address);
       dst_address += 2;
       src_address += 2;
       break;
     case R_RELLONG:
-      bfd_put_32 (abfd, bfd_coff_reloc16_get_value (reloc, seclet),
+      bfd_put_32 (abfd,
+                 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
                  data + dst_address);
       dst_address += 4;
       src_address += 4;
@@ -389,7 +404,8 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
       /* the offset must fit ! after all, what was all the relaxing
             about ? */
 
-      bfd_put_8 (abfd, bfd_coff_reloc16_get_value (reloc, seclet),
+      bfd_put_8 (abfd,
+                bfd_coff_reloc16_get_value (reloc, link_info, input_section),
                 data + dst_address);
 
       /* Note the magic - src goes up by two bytes, but dst by only
@@ -403,11 +419,12 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
       
       /* Speciial relaxed type */
       {
-       bfd_vma dot = seclet->offset
+       bfd_vma dot = link_order->offset
        + dst_address
-       + seclet->u.indirect.section->output_section->vma;
+       + link_order->u.indirect.section->output_section->vma;
 
-       int gap = bfd_coff_reloc16_get_value (reloc, seclet) - dot - 1;
+       int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
+                  - dot - 1);
 
        if ((gap & ~0xff) != 0 && ((gap & 0xff00) != 0xff00))
          abort ();
@@ -439,11 +456,12 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
       
       /* Speciial relaxed type */
       {
-       bfd_vma dot = seclet->offset
+       bfd_vma dot = link_order->offset
        + dst_address
-       + seclet->u.indirect.section->output_section->vma;
+       + link_order->u.indirect.section->output_section->vma;
 
-       int gap = bfd_coff_reloc16_get_value (reloc, seclet) - dot - 2;
+       int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
+                  - dot - 2);
 
        if ((gap & ~0xff) != 0 && ((gap & 0xff00) != 0xff00))
          abort ();
@@ -473,7 +491,7 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
 
     case R_JMPL1:
       {
-       int v = bfd_coff_reloc16_get_value (reloc, seclet);
+       int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
        int o = bfd_get_32 (abfd, data + src_address);
        v = (v & 0x00ffffff) | (o & 0xff000000);
        bfd_put_32 (abfd, v, data + dst_address);
@@ -488,7 +506,7 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
         the byte before the 24bit hole, so we can treat it as a 32bit pointer */
     case R_MOVLB1:
       {
-       int v = bfd_coff_reloc16_get_value (reloc, seclet);
+       int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
        int o = bfd_get_32 (abfd, data + dst_address);
        v = (v & 0x00ffffff) | (o & 0xff000000);
        bfd_put_32 (abfd, v, data + dst_address);
@@ -516,7 +534,8 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
 
 #undef coff_bfd_get_relocated_section_contents
 #undef coff_bfd_relax_section
-#define  coff_bfd_get_relocated_section_contents bfd_coff_reloc16_get_relocated_section_contents
+#define coff_bfd_get_relocated_section_contents \
+  bfd_coff_reloc16_get_relocated_section_contents
 #define coff_bfd_relax_section bfd_coff_reloc16_relax_section
 
 
@@ -530,7 +549,7 @@ bfd_target h8300coff_vec =
 
   (HAS_RELOC | EXEC_P |                /* object flags */
    HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
+   HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),       /* section flags */
   '_',                         /* leading char */
   '/',                         /* ar_pad_char */
index e8e3a5ee5884a8dd80266db1ba4c14b2cd3d8604..fec25d72bf3c1bbb646480a4264651cdd39a4577 100644 (file)
@@ -21,50 +21,48 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
-#include "libbfd.h"
 #include "obstack.h"
+#include "libbfd.h"
+#include "bfdlink.h"
 #include "coff/h8500.h"
 #include "coff/internal.h"
 #include "libcoff.h"
-#include "seclet.h"
-
-extern bfd_error_vector_type bfd_error_vector;
 
 static reloc_howto_type r_imm8 =
-HOWTO (R_H8500_IMM8, 0, 1, 8, false, 0, true,
-       true, 0, "r_imm8", true, 0x000000ff, 0x000000ff, false);
+HOWTO (R_H8500_IMM8, 0, 1, 8, false, 0,
+       complain_overflow_bitfield, 0, "r_imm8", true, 0x000000ff, 0x000000ff, false);
 
 static reloc_howto_type r_imm16 =
-HOWTO (R_H8500_IMM16, 0, 1, 16, false, 0, true,
-       true, 0, "r_imm16", true, 0x0000ffff, 0x0000ffff, false);
+HOWTO (R_H8500_IMM16, 0, 1, 16, false, 0,
+       complain_overflow_bitfield, 0, "r_imm16", true, 0x0000ffff, 0x0000ffff, false);
 
 static reloc_howto_type r_imm24 =
-HOWTO (R_H8500_IMM24, 0, 1, 24, false, 0, true,
-       true, 0, "r_imm24", true, 0x00ffffff, 0x00ffffff, false);
+HOWTO (R_H8500_IMM24, 0, 1, 24, false, 0,
+       complain_overflow_bitfield, 0, "r_imm24", true, 0x00ffffff, 0x00ffffff, false);
 
 static reloc_howto_type r_imm32 =
-HOWTO (R_H8500_IMM32, 0, 1, 32, false, 0, true,
-       true, 0, "r_imm32", true, 0xffffffff, 0xffffffff, false);
+HOWTO (R_H8500_IMM32, 0, 1, 32, false, 0,
+       complain_overflow_bitfield, 0, "r_imm32", true, 0xffffffff, 0xffffffff, false);
 
 
 static reloc_howto_type r_high8 =
-HOWTO (R_H8500_HIGH8, 0, 1, 8, false, 0, true,
-       true, 0, "r_high8", true, 0x000000ff, 0x000000ff, false);
+HOWTO (R_H8500_HIGH8, 0, 1, 8, false, 0,
+       complain_overflow_bitfield, 0, "r_high8", true, 0x000000ff, 0x000000ff, false);
 
 static reloc_howto_type r_low16 =
-HOWTO (R_H8500_LOW16, 0, 1, 16, false, 0, true,
-       true, 0, "r_low16", true, 0x0000ffff, 0x0000ffff, false);
+HOWTO (R_H8500_LOW16, 0, 1, 16, false, 0,
+       complain_overflow_bitfield, 0, "r_low16", true, 0x0000ffff, 0x0000ffff, false);
 
 static reloc_howto_type r_pcrel8 =
-HOWTO (R_H8500_PCREL8, 0, 1, 8, true, 0, true, true, 0, "r_pcrel8", true, 0, 0, true);
+HOWTO (R_H8500_PCREL8, 0, 1, 8, true, 0, complain_overflow_signed, 0, "r_pcrel8", true, 0, 0, true);
 
 
 static reloc_howto_type r_pcrel16 =
-HOWTO (R_H8500_PCREL16, 0, 1, 16, true, 0, true, true, 0, "r_pcrel16", true, 0, 0, true);
+HOWTO (R_H8500_PCREL16, 0, 1, 16, true, 0, complain_overflow_signed, 0, "r_pcrel16", true, 0, 0, true);
 
 static reloc_howto_type r_high16 =
-HOWTO (R_H8500_HIGH16, 0, 1, 8, false, 0, true,
-       true, 0, "r_high16", true, 0x000ffff, 0x0000ffff, false);
+HOWTO (R_H8500_HIGH16, 0, 1, 8, false, 0,
+       complain_overflow_bitfield, 0, "r_high16", true, 0x000ffff, 0x0000ffff, false);
 
 
 /* Turn a howto into a reloc number */
@@ -102,7 +100,7 @@ rtype2howto(internal, dst)
   switch (dst->r_type)
     {
     default:
-      printf ("BAD 0x%x\n", dst->r_type);
+      fprintf (stderr, "BAD 0x%x\n", dst->r_type);
     case R_H8500_IMM8:
       internal->howto = &r_imm8;
       break;
@@ -171,20 +169,22 @@ static void reloc_processing (relent, reloc, symbols, abfd, section)
 }
 
 static void
-extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
+extra_case (in_abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)
      bfd *in_abfd;
-     bfd_seclet_type *seclet;
+     struct bfd_link_info *link_info;
+     struct bfd_link_order *link_order;
      arelent *reloc;
      bfd_byte *data;
      unsigned int *src_ptr;
      unsigned int *dst_ptr;
 {
   bfd_byte *d = data+*dst_ptr;
+  asection *input_section = link_order->u.indirect.section;
   switch (reloc->howto->type)
     {
     case R_H8500_IMM8:
       bfd_put_8 (in_abfd,
-                bfd_coff_reloc16_get_value (reloc, seclet),
+                bfd_coff_reloc16_get_value (reloc, link_info, input_section),
                 d);
       (*dst_ptr) += 1;
       (*src_ptr) += 1;
@@ -192,7 +192,8 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
 
     case R_H8500_HIGH8:
       bfd_put_8 (in_abfd,
-                (bfd_coff_reloc16_get_value (reloc, seclet)>>16),
+                (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
+                 >> 16),
                 d );
       (*dst_ptr) += 1;
       (*src_ptr) += 1;
@@ -200,7 +201,7 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
 
     case R_H8500_IMM16:
       bfd_put_16 (in_abfd,
-                 bfd_coff_reloc16_get_value (reloc, seclet) ,
+                 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
                  d  );
       (*dst_ptr) += 2;
       (*src_ptr) += 2;
@@ -208,7 +209,7 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
 
     case R_H8500_LOW16:
       bfd_put_16 (in_abfd,
-                 bfd_coff_reloc16_get_value (reloc, seclet) ,
+                 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
                  d);
 
       (*dst_ptr) += 2;
@@ -217,7 +218,8 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
       
     case R_H8500_HIGH16:
       bfd_put_16 (in_abfd,
-                 bfd_coff_reloc16_get_value (reloc, seclet)>>16 ,
+                 (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
+                  >>16),
                  d);
 
       (*dst_ptr) += 2;
@@ -226,7 +228,7 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
 
     case R_H8500_IMM24:
       {
-       int v = bfd_coff_reloc16_get_value(reloc, seclet);
+       int v = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
        int o = bfd_get_32(in_abfd, data+ *dst_ptr -1);
        v = (v & 0x00ffffff) | (o & 0xff00000);
        bfd_put_32 (in_abfd, v, data  + *dst_ptr -1);
@@ -236,7 +238,7 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
       break;
     case R_H8500_IMM32:
       {
-       int v = bfd_coff_reloc16_get_value(reloc, seclet);
+       int v = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
        bfd_put_32 (in_abfd, v, data  + *dst_ptr);
        (*dst_ptr) +=4;
        (*src_ptr)+=4;;
@@ -246,16 +248,21 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
 
     case R_H8500_PCREL8:
       {
-       bfd_vma dst = bfd_coff_reloc16_get_value (reloc, seclet);
-       bfd_vma dot = seclet->offset
+       bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+                                                 input_section);
+       bfd_vma dot = link_order->offset
          + *dst_ptr
-           + seclet->u.indirect.section->output_section->vma;
+           + link_order->u.indirect.section->output_section->vma;
        int gap = dst - dot - 1; /* -1 since were in the odd byte of the
                                    word and the pc's been incremented */
 
        if (gap > 128 || gap < -128)
          {
-           bfd_error_vector.reloc_value_truncated (reloc, seclet);
+           if (! ((*link_info->callbacks->reloc_overflow)
+                  (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+                   reloc->howto->name, reloc->addend, input_section->owner,
+                   input_section, reloc->address)))
+             abort ();
          }
        bfd_put_8 (in_abfd, gap, data + *dst_ptr);
        (*dst_ptr)++;
@@ -264,16 +271,21 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
       }
     case R_H8500_PCREL16:
       {
-       bfd_vma dst = bfd_coff_reloc16_get_value (reloc, seclet);
-       bfd_vma dot = seclet->offset
+       bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+                                                 input_section);
+       bfd_vma dot = link_order->offset
          + *dst_ptr
-           + seclet->u.indirect.section->output_section->vma;
+           + link_order->u.indirect.section->output_section->vma;
        int gap = dst - dot - 1; /* -1 since were in the odd byte of the
                                    word and the pc's been incremented */
 
        if (gap > 32767 || gap < -32768)
          {
-           bfd_error_vector.reloc_value_truncated (reloc, seclet);
+           if (! ((*link_info->callbacks->reloc_overflow)
+                  (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+                   reloc->howto->name, reloc->addend, input_section->owner,
+                   input_section, reloc->address)))
+             abort ();
          }
        bfd_put_16 (in_abfd, gap, data + *dst_ptr);
        (*dst_ptr)+=2;
@@ -293,7 +305,8 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
 
 #undef  coff_bfd_get_relocated_section_contents
 #undef coff_bfd_relax_section
-#define  coff_bfd_get_relocated_section_contents bfd_coff_reloc16_get_relocated_section_contents
+#define coff_bfd_get_relocated_section_contents \
+  bfd_coff_reloc16_get_relocated_section_contents
 #define coff_bfd_relax_section bfd_coff_reloc16_relax_section
 
 bfd_target h8500coff_vec =
@@ -305,19 +318,19 @@ bfd_target h8500coff_vec =
 
   (HAS_RELOC | EXEC_P |                /* object flags */
    HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
+   HAS_SYMS | HAS_LOCALS | WP_TEXT),
 
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),       /* section flags */
   '_',                         /* leading symbol underscore */
   '/',                         /* ar_pad_char */
   15,                          /* ar_max_namelen */
   1,                           /* minimum section alignment */
-  _do_getb64, _do_getb_signed_64, _do_putb64,
-     _do_getb32, _do_getb_signed_32, _do_putb32,
-     _do_getb16, _do_getb_signed_16, _do_putb16,       /* data */
-  _do_getb64, _do_getb_signed_64, _do_putb64,
-     _do_getb32, _do_getb_signed_32, _do_putb32,
-     _do_getb16, _do_getb_signed_16, _do_putb16,       /* hdrs */
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+     bfd_getb16, bfd_getb_signed_16, bfd_putb16,       /* data */
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+     bfd_getb16, bfd_getb_signed_16, bfd_putb16,       /* hdrs */
 
   {_bfd_dummy_target, coff_object_p,   /* bfd_check_format */
    bfd_generic_archive_p, _bfd_dummy_target},
index e641b60e6d8a877d4bfbdb0a289ed1f88a3f0592..c4a793a275c1ecfa68ce5dff5712e8b0a3c9fa27 100644 (file)
@@ -21,8 +21,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
+#include "bfdlink.h"
 #include "libbfd.h"
-#include "seclet.h"
 #include "coff/internal.h"
 #include "coff/sym.h"
 #include "coff/symconst.h"
@@ -49,25 +49,38 @@ static bfd_reloc_status_type mips_generic_reloc PARAMS ((bfd *abfd,
                                                         asymbol *symbol,
                                                         PTR data,
                                                         asection *section,
-                                                        bfd *output_bfd));
+                                                        bfd *output_bfd,
+                                                        char **error));
 static bfd_reloc_status_type mips_refhi_reloc PARAMS ((bfd *abfd,
                                                       arelent *reloc,
                                                       asymbol *symbol,
                                                       PTR data,
                                                       asection *section,
-                                                      bfd *output_bfd));
+                                                      bfd *output_bfd,
+                                                      char **error));
 static bfd_reloc_status_type mips_reflo_reloc PARAMS ((bfd *abfd,
                                                       arelent *reloc,
                                                       asymbol *symbol,
                                                       PTR data,
                                                       asection *section,
-                                                      bfd *output_bfd));
+                                                      bfd *output_bfd,
+                                                      char **error));
 static bfd_reloc_status_type mips_gprel_reloc PARAMS ((bfd *abfd,
                                                       arelent *reloc,
                                                       asymbol *symbol,
                                                       PTR data,
                                                       asection *section,
-                                                      bfd *output_bfd));
+                                                      bfd *output_bfd,
+                                                      char **error));
+static void mips_relocate_refhi PARAMS ((struct internal_reloc *refhi,
+                                        struct internal_reloc *reflo,
+                                        bfd *input_bfd,
+                                        asection *input_section,
+                                        bfd_byte *contents,
+                                        bfd_vma relocation));
+static boolean mips_relocate_section PARAMS ((bfd *, struct bfd_link_info *,
+                                             bfd *, asection *,
+                                             bfd_byte *, PTR));
 \f
 /* ECOFF has COFF sections, but the debugging information is stored in
    a completely different format.  ECOFF targets use some of the
@@ -364,7 +377,7 @@ mips_adjust_reloc_in (abfd, intern, rptr)
    are needed for MIPS.  */
 
 static void
-mips_adjust_reloc_in (abfd, rel, intern)
+mips_adjust_reloc_out (abfd, rel, intern)
      bfd *abfd;
      const arelent *rel;
      struct internal_reloc *intern;
@@ -388,13 +401,15 @@ mips_generic_reloc (abfd,
                    symbol,
                    data,
                    input_section,
-                   output_bfd)
+                   output_bfd,
+                   error_message)
      bfd *abfd;
      arelent *reloc_entry;
      asymbol *symbol;
      PTR data;
      asection *input_section;
      bfd *output_bfd;
+     char **error_message;
 {
   if (output_bfd != (bfd *) NULL
       && (symbol->flags & BSF_SECTION_SYM) == 0
@@ -422,13 +437,15 @@ mips_refhi_reloc (abfd,
                  symbol,
                  data,
                  input_section,
-                 output_bfd)
+                 output_bfd,
+                 error_message)
      bfd *abfd;
      arelent *reloc_entry;
      asymbol *symbol;
      PTR data;
      asection *input_section;
      bfd *output_bfd;
+     char **error_message;
 {
   bfd_reloc_status_type ret;
   bfd_vma relocation;
@@ -480,13 +497,15 @@ mips_reflo_reloc (abfd,
                  symbol,
                  data,
                  input_section,
-                 output_bfd)
+                 output_bfd,
+                 error_message)
      bfd *abfd;
      arelent *reloc_entry;
      asymbol *symbol;
      PTR data;
      asection *input_section;
      bfd *output_bfd;
+     char **error_message;
 {
   if (mips_refhi_addr != (bfd_byte *) NULL)
     {
@@ -522,7 +541,7 @@ mips_reflo_reloc (abfd,
 
   /* Now do the REFLO reloc in the usual way.  */
   return mips_generic_reloc (abfd, reloc_entry, symbol, data,
-                             input_section, output_bfd);
+                             input_section, output_bfd, error_message);
 }
 
 /* Do a GPREL relocation.  This is a 16 bit value which must become
@@ -530,17 +549,19 @@ mips_reflo_reloc (abfd,
 
 static bfd_reloc_status_type
 mips_gprel_reloc (abfd,
-                  reloc_entry,
-                  symbol,
-                  data,
-                  input_section,
-                  output_bfd)
+                 reloc_entry,
+                 symbol,
+                 data,
+                 input_section,
+                 output_bfd,
+                 error_message)
      bfd *abfd;
      arelent *reloc_entry;
      asymbol *symbol;
      PTR data;
      asection *input_section;
      bfd *output_bfd;
+     char **error_message;
 {
   boolean relocateable;
   bfd_vma relocation;
@@ -616,9 +637,8 @@ mips_gprel_reloc (abfd,
            {
              /* Only get the error once.  */
              ecoff_data (output_bfd)->gp = 4;
-             /* FIXME: How can we get the program name here?  */
-             fprintf (stderr,
-                      "GP relative relocation when _gp not defined\n");
+             *error_message =
+               (char *) "GP relative relocation when _gp not defined";
              return bfd_reloc_dangerous;
            }
        }
@@ -657,7 +677,7 @@ mips_gprel_reloc (abfd,
 
   /* Make sure it fit in 16 bits.  */
   if (val >= 0x8000 && val < 0xffff8000)
-    return bfd_reloc_outofrange;
+    return bfd_reloc_overflow;
 
   return bfd_reloc_ok;
 }
@@ -691,6 +711,9 @@ mips_bfd_reloc_type_lookup (abfd, code)
     case BFD_RELOC_MIPS_GPREL:
       mips_type = MIPS_R_GPREL;
       break;
+    case BFD_RELOC_MIPS_LITERAL:
+      mips_type = MIPS_R_LITERAL;
+      break;
     default:
       return (CONST struct reloc_howto_struct *) NULL;
     }
@@ -698,150 +721,443 @@ mips_bfd_reloc_type_lookup (abfd, code)
   return &mips_howto_table[mips_type];
 }
 \f
-#ifdef HOST_IRIX4
+/* A helper routine for mips_relocate_section which handles the REFHI
+   relocation.  The REFHI relocation must be followed by a REFLO
+   relocation, and the addend used is formed from the addends of both
+   instructions.  */
 
-#include <core.out.h>
-
-struct sgi_core_struct 
+static void
+mips_relocate_refhi (refhi, reflo, input_bfd, input_section, contents,
+                    relocation)
+     struct internal_reloc *refhi;
+     struct internal_reloc *reflo;
+     bfd *input_bfd;
+     asection *input_section;
+     bfd_byte *contents;
+     bfd_vma relocation;
 {
-  int sig;
-  char cmd[CORE_NAMESIZE];
-};
-
-#define core_hdr(bfd) ((bfd)->tdata.sgi_core_data)
-#define core_signal(bfd) (core_hdr(bfd)->sig)
-#define core_command(bfd) (core_hdr(bfd)->cmd)
+  unsigned long insn;
+  unsigned long val;
+  unsigned long vallo;
+
+  insn = bfd_get_32 (input_bfd,
+                    contents + refhi->r_vaddr - input_section->vma);
+  vallo = (bfd_get_32 (input_bfd,
+                      contents + reflo->r_vaddr - input_section->vma)
+          & 0xffff);
+  val = ((insn & 0xffff) << 16) + vallo;
+  val += relocation;
+
+  /* The low order 16 bits are always treated as a signed value.
+     Therefore, a negative value in the low order bits requires an
+     adjustment in the high order bits.  We need to make this
+     adjustment in two ways: once for the bits we took from the data,
+     and once for the bits we are putting back in to the data.  */
+  if ((vallo & 0x8000) != 0)
+    val -= 0x10000;
+  if ((val & 0x8000) != 0)
+    val += 0x10000;
 
-static asection *
-make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
-     bfd *abfd;
-     CONST char *name;
-     flagword flags;
-     bfd_size_type _raw_size;
-     bfd_vma vma;
-     file_ptr filepos;
-{
-  asection *asect;
+  insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
+  bfd_put_32 (input_bfd, (bfd_vma) insn,
+             contents + refhi->r_vaddr - input_section->vma);
+}
 
-  asect = bfd_make_section (abfd, name);
-  if (!asect)
-    return NULL;
+/* Relocate a section while linking a MIPS ECOFF file.  */
 
-  asect->flags = flags;
-  asect->_raw_size = _raw_size;
-  asect->vma = vma;
-  asect->filepos = filepos;
-  asect->alignment_power = 4;
+static boolean
+mips_relocate_section (output_bfd, info, input_bfd, input_section,
+                      contents, external_relocs)
+     bfd *output_bfd;
+     struct bfd_link_info *info;
+     bfd *input_bfd;
+     asection *input_section;
+     bfd_byte *contents;
+     PTR external_relocs;
+{
+  asection **symndx_to_section;
+  struct ecoff_link_hash_entry **sym_hashes;
+  bfd_vma gp;
+  boolean gp_undefined;
+  struct external_reloc *ext_rel;
+  struct external_reloc *ext_rel_end;
+  boolean got_reflo;
+
+  BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
+             == output_bfd->xvec->header_byteorder_big_p);
+
+  /* We keep a table mapping the symndx found in an internal reloc to
+     the appropriate section.  This is faster than looking up the
+     section by name each time.  */
+  symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
+  if (symndx_to_section == (asection **) NULL)
+    {
+      symndx_to_section = ((asection **)
+                          bfd_alloc (input_bfd,
+                                     (NUM_RELOC_SECTIONS
+                                      * sizeof (asection *))));
+
+      symndx_to_section[RELOC_SECTION_NONE] = NULL;
+      symndx_to_section[RELOC_SECTION_TEXT] =
+       bfd_get_section_by_name (input_bfd, ".text");
+      symndx_to_section[RELOC_SECTION_RDATA] =
+       bfd_get_section_by_name (input_bfd, ".rdata");
+      symndx_to_section[RELOC_SECTION_DATA] =
+       bfd_get_section_by_name (input_bfd, ".data");
+      symndx_to_section[RELOC_SECTION_SDATA] =
+       bfd_get_section_by_name (input_bfd, ".sdata");
+      symndx_to_section[RELOC_SECTION_SBSS] =
+       bfd_get_section_by_name (input_bfd, ".sbss");
+      symndx_to_section[RELOC_SECTION_BSS] =
+       bfd_get_section_by_name (input_bfd, ".bss");
+      symndx_to_section[RELOC_SECTION_INIT] =
+       bfd_get_section_by_name (input_bfd, ".init");
+      symndx_to_section[RELOC_SECTION_LIT8] =
+       bfd_get_section_by_name (input_bfd, ".lit8");
+      symndx_to_section[RELOC_SECTION_LIT4] =
+       bfd_get_section_by_name (input_bfd, ".lit4");
+      symndx_to_section[RELOC_SECTION_XDATA] = NULL;
+      symndx_to_section[RELOC_SECTION_PDATA] = NULL;
+      symndx_to_section[RELOC_SECTION_FINI] =
+       bfd_get_section_by_name (input_bfd, ".fini");
+      symndx_to_section[RELOC_SECTION_LITA] = NULL;
+      symndx_to_section[RELOC_SECTION_ABS] = NULL;
+
+      ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
+    }
 
-  return asect;
-}
+  sym_hashes = ecoff_data (input_bfd)->sym_hashes;
 
-static bfd_target *
-ecoff_core_file_p (abfd)
-     bfd *abfd;
-{
-  int val;
-  int i;
-  char *secname;
-  struct coreout coreout;
-  struct idesc *idg, *idf, *ids;
+  gp = ecoff_data (output_bfd)->gp;
+  if (gp == 0)
+    gp_undefined = true;
+  else
+    gp_undefined = false;
 
-  val = bfd_read ((PTR)&coreout, 1, sizeof coreout, abfd);
-  if (val != sizeof coreout)
-    return 0;
+  got_reflo = false;
 
-  if (coreout.c_magic != CORE_MAGIC
-      || coreout.c_version != CORE_VERSION1)
-    return 0;
+  ext_rel = (struct external_reloc *) external_relocs;
+  ext_rel_end = ext_rel + input_section->reloc_count;
+  for (; ext_rel < ext_rel_end; ext_rel++)
+    {
+      struct internal_reloc int_rel;
+      struct internal_reloc reflo_int_rel;
+      bfd_vma addend;
+      reloc_howto_type *howto;
+      struct ecoff_link_hash_entry *h = NULL;
+      asection *s = NULL;
+      bfd_vma relocation;
+      bfd_reloc_status_type r;
+
+      if (! got_reflo)
+       mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
+      else
+       {
+         int_rel = reflo_int_rel;
+         got_reflo = false;
+       }
 
-  core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, sizeof (struct sgi_core_struct));
-  if (!core_hdr (abfd))
-    return NULL;
+      BFD_ASSERT (int_rel.r_type
+                 < sizeof mips_howto_table / sizeof mips_howto_table[0]);
 
-  strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE);
-  core_signal (abfd) = coreout.c_sigcause;
+      /* The REFHI reloc requires special handling.  It must be
+        followed by a REFLO reloc, and the addend is formed from both
+        fields.  */
+      if (int_rel.r_type == MIPS_R_REFHI)
+       {
+         BFD_ASSERT ((ext_rel + 1) < ext_rel_end);
+         mips_ecoff_swap_reloc_in (input_bfd, (PTR) (ext_rel + 1),
+                                   &reflo_int_rel);
+         BFD_ASSERT (reflo_int_rel.r_type == MIPS_R_REFLO
+                     && int_rel.r_extern == reflo_int_rel.r_extern
+                     && int_rel.r_symndx == reflo_int_rel.r_symndx);
+         got_reflo = true;
+       }
 
-  bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET);
+      howto = &mips_howto_table[int_rel.r_type];
 
-  for (i = 0; i < coreout.c_nvmap; i++)
-    {
-      struct vmap vmap;
+      if (int_rel.r_extern)
+       {
+         h = sym_hashes[int_rel.r_symndx];
+         /* If h is NULL, that means that there is a reloc against an
+            external symbol which we thought was just a debugging
+            symbol.  This should not happen.  */
+         if (h == (struct ecoff_link_hash_entry *) NULL)
+           abort ();
+       }
+      else
+       {
+         if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
+           s = NULL;
+         else
+           s = symndx_to_section[int_rel.r_symndx];
 
-      val = bfd_read ((PTR)&vmap, 1, sizeof vmap, abfd);
-      if (val != sizeof vmap)
-       break;
+         if (s == (asection *) NULL)
+           abort ();
+       }
 
-      switch (vmap.v_type)
+      /* The GPREL reloc uses an addend: the difference in the GP
+        values.  */
+      if (int_rel.r_type != MIPS_R_GPREL)
+       addend = 0;
+      else
        {
-       case VDATA:
-         secname = ".data";
-         break;
-       case VSTACK:
-         secname = ".stack";
-         break;
-       default:
-         continue;
+         if (gp_undefined)
+           {
+             if (! ((*info->callbacks->reloc_dangerous)
+                    (info, "GP relative relocation when GP not defined",
+                     input_bfd, input_section,
+                     int_rel.r_vaddr - input_section->vma)))
+               return false;
+             /* Only give the error once per link.  */
+             ecoff_data (output_bfd)->gp = gp = 4;
+             gp_undefined = false;
+           }
+         if (! int_rel.r_extern)
+           {
+             /* This is a relocation against a section.  The current
+                addend in the instruction is the difference between
+                INPUT_SECTION->vma and the GP value of INPUT_BFD.  We
+                must change this to be the difference between the
+                final definition (which will end up in RELOCATION)
+                and the GP value of OUTPUT_BFD (which is in GP).  */
+             addend = ecoff_data (input_bfd)->gp - gp;
+           }
+         else if (! info->relocateable
+                  || h->root.type == bfd_link_hash_defined)
+           {
+             /* This is a relocation against an undefined or common
+                symbol.  The current addend in the instruction is
+                simply the desired offset into the symbol (normally
+                zero).  We are going to change this into a relocation
+                against a defined symbol, so we want the instruction
+                to hold the difference between the final definition
+                of the symbol (which will end up in RELOCATION) and
+                the GP value of OUTPUT_BFD (which is in GP).  */
+             addend = - gp;
+           }
+         else
+           {
+             /* This is a relocation against an undefined or common
+                symbol.  The current addend in the instruction is
+                simply the desired offset into the symbol (normally
+                zero).  We are generating relocateable output, and we
+                aren't going to define this symbol, so we just leave
+                the instruction alone.  */
+             addend = 0;
+           }
        }
 
-      if (!make_bfd_asection (abfd, secname,
-                             SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
-                             vmap.v_len,
-                             vmap.v_vaddr,
-                             vmap.v_offset,
-                             2))
-       return NULL;
-    }
+      if (info->relocateable)
+       {
+         /* We are generating relocateable output, and must convert
+            the existing reloc.  */
+         if (int_rel.r_extern)
+           {
+             if (h->root.type == bfd_link_hash_defined)
+               {
+                 asection *hsec;
+                 const char *name;
 
-  /* Make sure that the regs are contiguous within the core file. */
+                 /* This symbol is defined in the output.  Convert
+                    the reloc from being against the symbol to being
+                    against the section.  */
 
-  idg = &coreout.c_idesc[I_GPREGS];
-  idf = &coreout.c_idesc[I_FPREGS];
-  ids = &coreout.c_idesc[I_SPECREGS];
+                 /* Clear the r_extern bit.  */
+                 int_rel.r_extern = 0;
 
-  if (idg->i_offset + idg->i_len != idf->i_offset
-      || idf->i_offset + idf->i_len != ids->i_offset)
-    return 0;                  /* Can't deal with non-contig regs */
+                 /* Compute a new r_symndx value.  */
+                 hsec = h->root.u.def.section;
+                 name = bfd_get_section_name (output_bfd,
+                                              hsec->output_section);
 
-  bfd_seek (abfd, idg->i_offset, SEEK_SET);
+                 int_rel.r_symndx = -1;
+                 switch (name[1])
+                   {
+                   case 'b':
+                     if (strcmp (name, ".bss") == 0)
+                       int_rel.r_symndx = RELOC_SECTION_BSS;
+                     break;
+                   case 'd':
+                     if (strcmp (name, ".data") == 0)
+                       int_rel.r_symndx = RELOC_SECTION_DATA;
+                     break;
+                   case 'f':
+                     if (strcmp (name, ".fini") == 0)
+                       int_rel.r_symndx = RELOC_SECTION_FINI;
+                     break;
+                   case 'i':
+                     if (strcmp (name, ".init") == 0)
+                       int_rel.r_symndx = RELOC_SECTION_INIT;
+                     break;
+                   case 'l':
+                     if (strcmp (name, ".lit8") == 0)
+                       int_rel.r_symndx = RELOC_SECTION_LIT8;
+                     else if (strcmp (name, ".lit4") == 0)
+                       int_rel.r_symndx = RELOC_SECTION_LIT4;
+                     break;
+                   case 'r':
+                     if (strcmp (name, ".rdata") == 0)
+                       int_rel.r_symndx = RELOC_SECTION_RDATA;
+                     break;
+                   case 's':
+                     if (strcmp (name, ".sdata") == 0)
+                       int_rel.r_symndx = RELOC_SECTION_SDATA;
+                     else if (strcmp (name, ".sbss") == 0)
+                       int_rel.r_symndx = RELOC_SECTION_SBSS;
+                     break;
+                   case 't':
+                     if (strcmp (name, ".text") == 0)
+                       int_rel.r_symndx = RELOC_SECTION_TEXT;
+                     break;
+                   }
+                     
+                 if (int_rel.r_symndx == -1)
+                   abort ();
+
+                 /* Add the section VMA and the symbol value.  */
+                 relocation = (h->root.u.def.value
+                               + hsec->output_section->vma
+                               + hsec->output_offset);
+               }
+             else
+               {
+                 /* Change the symndx value to the right one for the
+                    output BFD.  */
+                 int_rel.r_symndx = h->indx;
+                 if (int_rel.r_symndx == -1)
+                   {
+                     /* This symbol is not being written out.  */
+                     if (! ((*info->callbacks->unattached_reloc)
+                            (info, h->root.root.string, input_bfd,
+                             input_section,
+                             int_rel.r_vaddr - input_section->vma)))
+                       return false;
+                     int_rel.r_symndx = 0;
+                   }
+                 relocation = 0;
+               }
+           }
+         else
+           {
+             /* This is a relocation against a section.  Adjust the
+                value by the amount the section moved.  */
+             relocation = (s->output_section->vma
+                           + s->output_offset
+                           - s->vma);
+           }
 
-  make_bfd_asection (abfd, ".reg",
-                    SEC_ALLOC+SEC_HAS_CONTENTS,
-                    idg->i_len + idf->i_len + ids->i_len,
-                    0,
-                    idg->i_offset);
+         relocation += addend;
 
-  /* OK, we believe you.  You're a core file (sure, sure).  */
+         /* Adjust the contents.  */
+         if (relocation == 0)
+           r = bfd_reloc_ok;
+         else
+           {
+             if (int_rel.r_type != MIPS_R_REFHI)
+               r = _bfd_relocate_contents (howto, input_bfd, relocation,
+                                           (contents
+                                            + int_rel.r_vaddr
+                                            - input_section->vma));
+             else
+               {
+                 mips_relocate_refhi (&int_rel, &reflo_int_rel,
+                                      input_bfd, input_section, contents,
+                                      relocation);
+                 r = bfd_reloc_ok;
+               }
+           }
 
-  return abfd->xvec;
-}
+         /* Adjust the reloc address.  */
+         int_rel.r_vaddr += (input_section->output_section->vma
+                             + input_section->output_offset
+                             - input_section->vma);
 
-static char *
-ecoff_core_file_failing_command (abfd)
-     bfd *abfd;
-{
-  return core_command (abfd);
-}
+         /* Save the changed reloc information.  */
+         mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
+       }
+      else
+       {
+         /* We are producing a final executable.  */
+         if (int_rel.r_extern)
+           {
+             /* This is a reloc against a symbol.  */
+             if (h->root.type == bfd_link_hash_defined)
+               {
+                 asection *hsec;
 
-static int
-ecoff_core_file_failing_signal (abfd)
-     bfd *abfd;
-{
-  return core_signal (abfd);
-}
+                 hsec = h->root.u.def.section;
+                 relocation = (h->root.u.def.value
+                               + hsec->output_section->vma
+                               + hsec->output_offset);
+               }
+             else
+               {
+                 if (! ((*info->callbacks->undefined_symbol)
+                        (info, h->root.root.string, input_bfd,
+                         input_section,
+                         int_rel.r_vaddr - input_section->vma)))
+                   return false;
+                 relocation = 0;
+               }
+           }
+         else
+           {
+             /* This is a reloc against a section.  */
+             relocation = (s->output_section->vma
+                           + s->output_offset
+                           - s->vma);
+
+             /* Adjust a PC relative relocation by removing the
+                reference to the original source section.  */
+             if (howto->pc_relative)
+               relocation += input_section->vma;
+           }
 
-static boolean
-ecoff_core_file_matches_executable_p (core_bfd, exec_bfd)
-     bfd *core_bfd, *exec_bfd;
-{
-  return true;                 /* XXX - FIXME */
+         if (int_rel.r_type != MIPS_R_REFHI)
+           r = _bfd_final_link_relocate (howto,
+                                         input_bfd,
+                                         input_section,
+                                         contents,
+                                         int_rel.r_vaddr - input_section->vma,
+                                         relocation,
+                                         addend);
+         else
+           {
+             mips_relocate_refhi (&int_rel, &reflo_int_rel, input_bfd,
+                                  input_section, contents, relocation);
+             r = bfd_reloc_ok;
+           }
+       }
+
+      if (r != bfd_reloc_ok)
+       {
+         switch (r)
+           {
+           default:
+           case bfd_reloc_outofrange:
+             abort ();
+           case bfd_reloc_overflow:
+             {
+               const char *name;
+
+               if (int_rel.r_extern)
+                 name = h->root.root.string;
+               else
+                 name = bfd_section_name (input_bfd, s);
+               if (! ((*info->callbacks->reloc_overflow)
+                      (info, name, howto->name, (bfd_vma) 0,
+                       input_bfd, input_section,
+                       int_rel.r_vaddr - input_section->vma)))
+                 return false;
+             }
+             break;
+           }
+       }
+    }
+
+  return true;
 }
-#else /* not def HOST_IRIX4 */
-#define ecoff_core_file_p _bfd_dummy_target
-#define ecoff_core_file_failing_command        _bfd_dummy_core_file_failing_command
-#define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
-#define ecoff_core_file_matches_executable_p \
-  _bfd_dummy_core_file_matches_executable_p
-#endif
 \f
 /* This is the ECOFF backend structure.  The backend field of the
    target vector points to this.  */
@@ -868,12 +1184,8 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
   },
   /* Supported architecture.  */
   bfd_arch_mips,
-  /* Symbol table magic number.  */
-  magicSym,
   /* Initial portion of armap string.  */
   "__________",
-  /* Alignment of debugging information.  E.g., 4.  */
-  4,
   /* The page boundary used to align sections in a demand-paged
      executable file.  E.g., 0x1000.  */
   0x1000,
@@ -885,33 +1197,39 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
   32,
   /* Reloc to use for constructor entries.  */
   &mips_howto_table[MIPS_R_REFWORD],
-  /* Sizes of external symbolic information.  */
-  sizeof (struct hdr_ext),
-  sizeof (struct dnr_ext),
-  sizeof (struct pdr_ext),
-  sizeof (struct sym_ext),
-  sizeof (struct opt_ext),
-  sizeof (struct fdr_ext),
-  sizeof (struct rfd_ext),
-  sizeof (struct ext_ext),
-  /* Functions to swap in external symbolic data.  */
-  ecoff_swap_hdr_in,
-  ecoff_swap_dnr_in,
-  ecoff_swap_pdr_in,
-  ecoff_swap_sym_in,
-  ecoff_swap_opt_in,
-  ecoff_swap_fdr_in,
-  ecoff_swap_rfd_in,
-  ecoff_swap_ext_in,
-  /* Functions to swap out external symbolic data.  */
-  ecoff_swap_hdr_out,
-  ecoff_swap_dnr_out,
-  ecoff_swap_pdr_out,
-  ecoff_swap_sym_out,
-  ecoff_swap_opt_out,
-  ecoff_swap_fdr_out,
-  ecoff_swap_rfd_out,
-  ecoff_swap_ext_out,
+  {
+    /* Symbol table magic number.  */
+    magicSym,
+    /* Alignment of debugging information.  E.g., 4.  */
+    4,
+    /* Sizes of external symbolic information.  */
+    sizeof (struct hdr_ext),
+    sizeof (struct dnr_ext),
+    sizeof (struct pdr_ext),
+    sizeof (struct sym_ext),
+    sizeof (struct opt_ext),
+    sizeof (struct fdr_ext),
+    sizeof (struct rfd_ext),
+    sizeof (struct ext_ext),
+    /* Functions to swap in external symbolic data.  */
+    ecoff_swap_hdr_in,
+    ecoff_swap_dnr_in,
+    ecoff_swap_pdr_in,
+    ecoff_swap_sym_in,
+    ecoff_swap_opt_in,
+    ecoff_swap_fdr_in,
+    ecoff_swap_rfd_in,
+    ecoff_swap_ext_in,
+    /* Functions to swap out external symbolic data.  */
+    ecoff_swap_hdr_out,
+    ecoff_swap_dnr_out,
+    ecoff_swap_pdr_out,
+    ecoff_swap_sym_out,
+    ecoff_swap_opt_out,
+    ecoff_swap_fdr_out,
+    ecoff_swap_rfd_out,
+    ecoff_swap_ext_out
+  },
   /* External reloc size.  */
   RELSZ,
   /* Reloc swapping functions.  */
@@ -919,7 +1237,9 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
   mips_ecoff_swap_reloc_out,
   /* Backend reloc tweaking.  */
   mips_adjust_reloc_in,
-  mips_adjust_reloc_out
+  mips_adjust_reloc_out,
+  /* Relocate section contents while linking.  */
+  mips_relocate_section
 };
 
 /* Looking up a reloc type is MIPS specific.  */
@@ -929,6 +1249,14 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
 #define ecoff_bfd_get_relocated_section_contents \
   bfd_generic_get_relocated_section_contents
 
+/* Core file support is usually traditional (but note that Irix uses
+   irix-core.c).  */
+#define ecoff_core_file_p _bfd_dummy_target
+#define ecoff_core_file_failing_command        _bfd_dummy_core_file_failing_command
+#define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
+#define ecoff_core_file_matches_executable_p \
+  _bfd_dummy_core_file_matches_executable_p
+
 bfd_target ecoff_little_vec =
 {
   "ecoff-littlemips",          /* name */
@@ -938,7 +1266,7 @@ bfd_target ecoff_little_vec =
 
   (HAS_RELOC | EXEC_P |                /* object flags */
    HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
 
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect
                                                            flags */
@@ -972,7 +1300,7 @@ bfd_target ecoff_big_vec =
 
   (HAS_RELOC | EXEC_P |                /* object flags */
    HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
 
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect flags */
   0,                           /* leading underscore */
index d2ad241b59734c5e385653c42f95a47d54edd5d6..59ea5e22f336ee77bb904162f8baac8f8cbcfc4e 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for Zilog Z800n COFF binaries.
-   Copyright 1992 Free Software Foundation, Inc.
+   Copyright 1992, 1993 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
    Written by Steve Chamberlain, <sac@cygnus.com>.
 
@@ -21,70 +21,35 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
-#include "libbfd.h"
 #include "obstack.h"
+#include "libbfd.h"
+#include "bfdlink.h"
 #include "coff/z8k.h"
 #include "coff/internal.h"
 #include "libcoff.h"
-#include "seclet.h"
-
-extern bfd_error_vector_type bfd_error_vector;
-
-/* Dummy for now */
-static bfd_reloc_status_type
-DEFUN (func_da, (abfd, reloc_entry, symbol, data, input_section, output_bfd),
-       bfd * abfd AND
-       arelent * reloc_entry AND
-       struct symbol_cache_entry *symbol AND
-       PTR data AND
-       asection * input_section AND
-       bfd * output_bfd)
-{
-}
-
-/* Dummy for now */
-static bfd_reloc_status_type
-DEFUN (func_imm8, (abfd, reloc_entry, symbol, data, input_section, output_bfd),
-       bfd * abfd AND
-       arelent * reloc_entry AND
-       struct symbol_cache_entry *symbol AND
-       PTR data AND
-       asection * input_section AND
-       bfd * output_bfd)
-{
-}
-
-/* Dummy for now */
-static bfd_reloc_status_type
-DEFUN (func_jr, (abfd, reloc_entry, symbol, data, input_section, output_bfd),
-       bfd * abfd AND
-       arelent * reloc_entry AND
-       struct symbol_cache_entry *symbol AND
-       PTR data AND
-       asection * input_section AND
-       bfd * output_bfd)
-{
-}
-
 
 static reloc_howto_type r_imm32 =
-HOWTO (R_IMM32, 0, 1, 32, false, 0, true,
-       true, func_jr, "r_imm32", true, 0xffffffff, 0xffffffff, false);
+HOWTO (R_IMM32, 0, 1, 32, false, 0,
+       complain_overflow_bitfield, 0, "r_imm32", true, 0xffffffff,
+       0xffffffff, false);
 
 static reloc_howto_type r_imm4l =
-HOWTO (R_IMM4L, 0, 1, 4, false, 0, true,
-       true, func_jr, "r_imm4l", true, 0xf, 0xf, false);
+HOWTO (R_IMM4L, 0, 1, 4, false, 0,
+       complain_overflow_bitfield, 0, "r_imm4l", true, 0xf, 0xf, false);
 
 static reloc_howto_type r_da =
-HOWTO (R_DA, 0, 1, 16, false, 0, true,
-       true, func_da, "r_da", true, 0x0000ffff, 0x0000ffff, false);
+HOWTO (R_IMM16, 0, 1, 16, false, 0,
+       complain_overflow_bitfield, 0, "r_da", true, 0x0000ffff, 0x0000ffff,
+       false);
 
 static reloc_howto_type r_imm8 =
-HOWTO (R_IMM8, 0, 1, 8, false, 0, true,
-       true, func_imm8, "r_imm8", true, 0x000000ff, 0x000000ff, false);
+HOWTO (R_IMM8, 0, 1, 8, false, 0,
+       complain_overflow_bitfield, 0, "r_imm8", true, 0x000000ff, 0x000000ff,
+       false);
 
 static reloc_howto_type r_jr =
-HOWTO (R_JR, 0, 1, 8, true, 0, true, true, func_jr, "r_jr", true, 0, 0, true);
+HOWTO (R_JR, 0, 1, 8, true, 0, complain_overflow_signed, 0,
+       "r_jr", true, 0, 0, true);
 
 /* Turn a howto into a reloc number */
 
@@ -122,11 +87,11 @@ DEFUN (rtype2howto, (internal, dst),
   switch (dst->r_type)
     {
       default:
-      printf ("BAD %x\n", dst->r_type);
+      fprintf (stderr, "BAD 0x%x\n", dst->r_type);
     case R_IMM8:
       internal->howto = &r_imm8;
       break;
-    case R_DA:
+     case R_IMM16:
       internal->howto = &r_da;
       break;
     case R_JR:
@@ -180,25 +145,30 @@ DEFUN (reloc_processing, (relent, reloc, symbols, abfd, section),
 }
 
 static void
-extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
+extra_case (in_abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)
      bfd *in_abfd;
-     bfd_seclet_type *seclet;
+     struct bfd_link_info *link_info;
+     struct bfd_link_order *link_order;
      arelent *reloc;
      bfd_byte *data;
      unsigned int *src_ptr;
      unsigned int *dst_ptr;
 {
+  asection *input_section = link_order->u.indirect.section;
+
   switch (reloc->howto->type)
     {
     case R_IMM8:
-      bfd_put_8 (in_abfd, bfd_coff_reloc16_get_value (reloc, seclet),
+      bfd_put_8 (in_abfd,
+                bfd_coff_reloc16_get_value (reloc, link_info, input_section),
                 data + *dst_ptr);
       (*dst_ptr) += 1;
       (*src_ptr) += 1;
       break;
 
     case R_IMM32:
-      bfd_put_32 (in_abfd, bfd_coff_reloc16_get_value (reloc, seclet),
+      bfd_put_32 (in_abfd,
+                 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
                  data + *dst_ptr);
       (*dst_ptr) += 4;
       (*src_ptr) += 4;
@@ -206,15 +176,18 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
 
     case R_IMM4L:
       bfd_put_8 (in_abfd,
-                (bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0) 
-                | (0x0f & bfd_coff_reloc16_get_value (reloc, seclet)),
+                ((bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0) 
+                 | (0x0f
+                    & bfd_coff_reloc16_get_value (reloc, link_info,
+                                                  input_section))),
                 data + *dst_ptr);
       (*dst_ptr) += 1;
       (*src_ptr) += 1;
       break;
 
-    case R_DA:
-      bfd_put_16 (in_abfd, bfd_coff_reloc16_get_value (reloc, seclet),
+    case R_IMM16:
+      bfd_put_16 (in_abfd,
+                 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
                  data + *dst_ptr);
       (*dst_ptr) += 2;
       (*src_ptr) += 2;
@@ -222,10 +195,11 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
 
     case R_JR:
       {
-       bfd_vma dst = bfd_coff_reloc16_get_value (reloc, seclet);
-       bfd_vma dot = seclet->offset
-       + *dst_ptr
-       + seclet->u.indirect.section->output_section->vma;
+       bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+                                                 input_section);
+       bfd_vma dot = (link_order->offset
+                      + *dst_ptr
+                      + input_section->output_section->vma);
        int gap = dst - dot - 1;/* -1 since were in the odd byte of the
                                    word and the pc's been incremented */
 
@@ -234,7 +208,11 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
        gap /= 2;
        if (gap > 128 || gap < -128)
          {
-           bfd_error_vector.reloc_value_truncated (reloc, seclet);
+           if (! ((*link_info->callbacks->reloc_overflow)
+                  (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+                   reloc->howto->name, reloc->addend, input_section->owner,
+                   input_section, reloc->address)))
+             abort ();
          }
        bfd_put_8 (in_abfd, gap, data + *dst_ptr);
        (*dst_ptr)++;
@@ -253,7 +231,8 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
 
 #undef  coff_bfd_get_relocated_section_contents
 #undef coff_bfd_relax_section
-#define  coff_bfd_get_relocated_section_contents bfd_coff_reloc16_get_relocated_section_contents
+#define coff_bfd_get_relocated_section_contents \
+  bfd_coff_reloc16_get_relocated_section_contents
 #define coff_bfd_relax_section bfd_coff_reloc16_relax_section
 
 bfd_target z8kcoff_vec =
@@ -265,15 +244,19 @@ bfd_target z8kcoff_vec =
 
   (HAS_RELOC | EXEC_P |                /* object flags */
    HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
+   HAS_SYMS | HAS_LOCALS | WP_TEXT),
 
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),       /* section flags */
   '_',                         /* leading symbol underscore */
   '/',                         /* ar_pad_char */
   15,                          /* ar_max_namelen */
   1,                           /* minimum section alignment */
-  _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16,      /* data */
-  _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16,      /* hdrs */
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+     bfd_getb16, bfd_getb_signed_16, bfd_putb16,       /* data */
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+     bfd_getb16, bfd_getb_signed_16, bfd_putb16,       /* hdrs */
 
   {_bfd_dummy_target, coff_object_p,   /* bfd_check_format */
    bfd_generic_archive_p, _bfd_dummy_target},
@@ -283,6 +266,5 @@ bfd_target z8kcoff_vec =
    _bfd_write_archive_contents, bfd_false},
 
   JUMP_TABLE (coff),
-  0, 0,
   COFF_SWAP_TABLE,
 };
index 4f15c6280d996257229c654b24bec07fe98c71c2..af1b8e3cb7f6e878d452d9914b8d55c27155cf7e 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for HP PA-RISC ELF files.
-   Copyright (C) 1990-1991 Free Software Foundation, Inc.
+   Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
 
    Written by
 
@@ -27,6 +27,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "sysdep.h"
 #include "libbfd.h"
 #include "obstack.h"
+#include "bfdlink.h"
 #include "libelf.h"
 
 /* ELF32/HPPA relocation support
@@ -43,7 +44,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /* ELF/PA relocation howto entries */
 
-static bfd_reloc_status_type hppa_elf_reloc ();
+static bfd_reloc_status_type hppa_elf_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
 
 static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
 {
@@ -1184,13 +1186,15 @@ static asymbol *global_symbol;
 static int global_sym_defined;
 
 static bfd_reloc_status_type
-hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
+hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+               error_message)
      bfd *abfd;
      arelent *reloc_entry;
      asymbol *symbol_in;
      PTR data;
      asection *input_section;
      bfd *output_bfd;
+     char **error_message;
 {
   unsigned long insn;
   long sym_value = 0;
@@ -1698,9 +1702,7 @@ hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
       break;
       
     default:
-      fprintf (stderr, "Relocation problem : ");
-      fprintf (stderr, "Unrecognized reloc type %d, in module %s\n",
-              r_type, abfd->filename);
+      *error_message = (char *) "Unrecognized reloc";
       return bfd_reloc_dangerous;
     }
 
@@ -1913,6 +1915,7 @@ typedef struct elf32_hppa_stub_description_struct
     int *stub_secp;            /* pointer to the next available location in the buffer */
     char *stub_contents;       /* contents of the stubs for this bfd */
     elf32_hppa_stub_name_list *stub_listP;
+    struct bfd_link_info *link_info;
   }
 elf32_hppa_stub_description;
 
@@ -1937,9 +1940,10 @@ find_stubs (abfd, stub_sec)
 }
 
 static elf32_hppa_stub_description *
-new_stub (abfd, stub_sec)
+new_stub (abfd, stub_sec, link_info)
      bfd *abfd;
      asection *stub_sec;
+     struct bfd_link_info *link_info;
 {
   elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
 
@@ -1955,6 +1959,7 @@ new_stub (abfd, stub_sec)
       stub->allocated_size = 0;
       stub->stub_contents = NULL;
       stub->stub_secp = NULL;
+      stub->link_info = link_info;
 
       stub->next = elf_hppa_stub_rootP;
       elf_hppa_stub_rootP = stub;
@@ -1993,16 +1998,17 @@ find_stub_by_name (abfd, stub_sec, name)
 
 /* Locate the stub by the given name.  */
 static elf32_hppa_stub_name_list *
-add_stub_by_name(abfd, stub_sec, sym)
+add_stub_by_name(abfd, stub_sec, sym, link_info)
      bfd *abfd;
      asection *stub_sec;
      asymbol *sym;
+     struct bfd_link_info *link_info;
 {
   elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
   elf32_hppa_stub_name_list *stub_entry;
 
   if (!stub)
-    stub = new_stub(abfd, stub_sec);
+    stub = new_stub(abfd, stub_sec, link_info);
 
   if (stub)
     {
@@ -2146,7 +2152,6 @@ void
 hppa_elf_stub_finish (output_bfd)
      bfd *output_bfd;
 {
-  extern bfd_error_vector_type bfd_error_vector;
   elf32_hppa_stub_description *stub_list = elf_hppa_stub_rootP;
   /* All the stubs have been built.  Finish up building        */
   /* stub section.  Apply relocations to the section.  */
@@ -2183,27 +2188,46 @@ hppa_elf_stub_finish (output_bfd)
              for (parent = reloc_vector; *parent != (arelent *) NULL;
                   parent++)
                {
+                 char *err = (char *) NULL;
                  bfd_reloc_status_type r =
-                 bfd_perform_relocation (stub_bfd,
-                                         *parent,
-                                         stub_list->stub_contents,
-                                         stub_sec, 0);
+                   bfd_perform_relocation (stub_bfd,
+                                           *parent,
+                                           stub_list->stub_contents,
+                                           stub_sec, (bfd *) NULL, &err);
 
 
                  if (r != bfd_reloc_ok)
                    {
+                     struct bfd_link_info *link_info = stub_list->link_info;
+
                      switch (r)
                        {
                        case bfd_reloc_undefined:
-                         bfd_error_vector.undefined_symbol (*parent, NULL);
+                         if (! ((*link_info->callbacks->undefined_symbol)
+                                (link_info,
+                                 bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+                                 stub_bfd, stub_sec, (*parent)->address)))
+                           abort ();
                          break;
                        case bfd_reloc_dangerous:
-                         bfd_error_vector.reloc_dangerous (*parent, NULL);
+                         if (! ((*link_info->callbacks->reloc_dangerous)
+                                (link_info, err, stub_bfd, stub_sec,
+                                 (*parent)->address)))
+                           abort ();
                          break;
-                       case bfd_reloc_outofrange:
                        case bfd_reloc_overflow:
-                         bfd_error_vector.reloc_value_truncated (*parent, NULL);
+                         {
+                           if (! ((*link_info->callbacks->reloc_overflow)
+                                  (link_info,
+                                   bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+                                   (*parent)->howto->name,
+                                   (*parent)->addend,
+                                   stub_bfd, stub_sec,
+                                   (*parent)->address)))
+                             abort ();
+                         }
                          break;
+                       case bfd_reloc_outofrange:
                        default:
                          abort ();
                          break;
@@ -2325,10 +2349,11 @@ elf32_hppa_reloc_type type;
 }
 
 asymbol *
-hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
+hppa_elf_build_arg_reloc_stub (abfd, output_bfd, link_info, reloc_entry,
                               stub_types, rtn_adjust, data)
      bfd *abfd;
      bfd *output_bfd;
+     struct bfd_link_info *link_info;
      arelent *reloc_entry;
      int stub_types[5];
      int rtn_adjust;
@@ -2372,12 +2397,12 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
       stub_sec->output_section = output_text_section->output_section;
       stub_sec->output_offset = 0;
       bfd_set_section_alignment (abfd, stub_sec, 2);
-      stub_desc = new_stub (abfd, stub_sec);
+      stub_desc = new_stub (abfd, stub_sec, link_info);
     }
 
   /* Make the stub if we did not find one already.  */
   if (!stub_desc)
-    stub_desc = new_stub (abfd, stub_sec);
+    stub_desc = new_stub (abfd, stub_sec, link_info);
 
   /* Allocate space to write the stub.
      FIXME.  Why using realloc?!?  */
@@ -2429,7 +2454,7 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
        = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
       stub_sym->section = stub_sec;
       stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
-      stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym);
+      stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
 
       /* Redirect the original relocation from the old symbol (a function)
         to the stub (the stub calls the function).  Change the type of
@@ -2567,6 +2592,8 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
        {
          NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
        }
+      else
+       NEW_INSTRUCTION (stub_entry, COPY_31_2);
 
       /* Save the return address.  */
       NEW_INSTRUCTION (stub_entry, STW_RP_M8SP);
@@ -2732,9 +2759,11 @@ hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types, caller_ar)
 }
 
 asymbol *
-hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data)
+hppa_elf_build_long_branch_stub (abfd, output_bfd, link_info, reloc_entry,
+                                symbol, data)
      bfd *abfd;
      bfd *output_bfd;
+     struct bfd_link_info *link_info;
      arelent *reloc_entry;
      asymbol *symbol;
      unsigned *data;
@@ -2817,11 +2846,11 @@ hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data)
       }
       
       bfd_set_section_alignment (abfd, stub_sec, 2);
-      stub_desc = new_stub (abfd, stub_sec);
+      stub_desc = new_stub (abfd, stub_sec, link_info);
     }
   
   if (!stub_desc)
-    stub_desc = new_stub (abfd, stub_sec);
+    stub_desc = new_stub (abfd, stub_sec, link_info);
   
   /* Allocate memory to contain the stub.  FIXME.  Why isn't this using
      the BFD memory allocation routines?  */
@@ -2915,7 +2944,7 @@ hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data)
        = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
       stub_sym->section = stub_sec;
       stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
-      stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym);
+      stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
       
       /* Change symbol associated with the original relocation to point
         to the stub.
@@ -3051,13 +3080,14 @@ hppa_elf_long_branch_needed_p (abfd, asec, reloc_entry, symbol, insn)
 
 asymbol *
 hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec,
-                               syms, new_sym_cnt)
+                               syms, new_sym_cnt, link_info)
      bfd *stub_bfd;
      bfd *abfd;
      bfd *output_bfd;
      asection *asec;
      asymbol **syms;
      int *new_sym_cnt;
+     struct bfd_link_info *link_info;
 {
   int i;
   int stub_types[5];
@@ -3145,7 +3175,8 @@ hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec,
                       R_HPPA_STUB_CALL_17) it will be possible to perform
                       the code reorientation.  */
                    r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
-                                                      rle, stub_types,
+                                                      link_info, rle,
+                                                      stub_types,
                                                       true, insn);
                    new_syms[new_cnt++] = *r;
                  }
@@ -3166,7 +3197,7 @@ hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec,
                          realloc (new_syms, (new_max * sizeof (asymbol)));
                      }
                    r = hppa_elf_build_long_branch_stub (stub_bfd, output_bfd,
-                                                        rle,
+                                                        link_info, rle,
                                                         rle->sym_ptr_ptr[0],
                                                         insn);
                    new_syms[new_cnt++] = *r;
@@ -3225,7 +3256,8 @@ hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec,
                          }
                      }
                    r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
-                                                      rle, stub_types,
+                                                      link_info, rle,
+                                                      stub_types,
                                                       rtn_adjust, insn);
                    new_syms[new_cnt++] = *r;
                  }
index 93fccdbcae0ac282a29829c226fac1f37f1d074d..e0fb312d81d26b6f8a52ba4345394e703f4742a7 100644 (file)
@@ -1646,7 +1646,9 @@ bfd_generic_get_relocated_section_contents (abfd, link_info, link_order, data,
          break;
        case bfd_reloc_overflow:
          if (! ((*link_info->callbacks->reloc_overflow)
-                (link_info, input_bfd, input_section, (*parent)->address)))
+                (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+                 (*parent)->howto->name, (*parent)->addend,
+                 input_bfd, input_section, (*parent)->address)))
            return NULL;
          break;
        case bfd_reloc_outofrange: