Nios II large-GOT relocations
authorSandra Loosemore <sandra@codesourcery.com>
Mon, 3 Feb 2014 16:42:42 +0000 (08:42 -0800)
committerSandra Loosemore <sandra@codesourcery.com>
Mon, 3 Feb 2014 16:42:42 +0000 (08:42 -0800)
2014-02-03  Sandra Loosemore  <sandra@codesourcery.com>

include/elf/
* nios2.h (R_NIOS2_GOT_LO, R_NIOS2_GOT_HA): New.
(R_NIOS2_CALL_LO, R_NIOS2_CALL_HA): New.
(R_NIOS2_ILLEGAL): Adjust.

gas/
* config/tc-nios2.c (md_apply_fix): Test for new relocs.
(nios2_special_reloc): Add %call_lo, %call_hiadj, %got_lo,
%got_hiadj relocation operators.  Sort table and add comment
to explain ordering.
(nios2_fix_adjustable): Test for new relocs.
* doc/c-nios2.texi (Nios II Relocations): Document new relocation
operators.

bfd/
* reloc.c (BFD_RELOC_NIOS2_GOT_LO, BFD_RELOC_NIOS2_GOT_HA): New.
(BFD_RELOC_NIOS2_CALL_LO, BFD_RELOC_NIOS2_CALL_HA): New.
* libbfd.h: Regenerated.
* bfd-in2.h: Regenerated.
* elf32-nios2.c (elf_nios2_howto_table_rel): Add new relocations.
(nios2_reloc_map): Likewise.
(GOT_USED, CALL_USED): Renamed from GOT16_USED and CALL16_USED.
Fixed all references.
(nios2_elf32_relocate_section): Add new relocations.
(nios2_elf32_check_relocs): Likewise.
(nios2_elf32_gc_sweep_hook): Likewise.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf32-nios2.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-nios2.c
gas/doc/c-nios2.texi
include/elf/ChangeLog
include/elf/nios2.h

index 2793df0..b5d658b 100644 (file)
@@ -1,3 +1,17 @@
+2014-02-03  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * reloc.c (BFD_RELOC_NIOS2_GOT_LO, BFD_RELOC_NIOS2_GOT_HA): New.
+       (BFD_RELOC_NIOS2_CALL_LO, BFD_RELOC_NIOS2_CALL_HA): New.
+       * libbfd.h: Regenerated.
+       * bfd-in2.h: Regenerated.
+       * elf32-nios2.c (elf_nios2_howto_table_rel): Add new relocations.
+       (nios2_reloc_map): Likewise.
+       (GOT_USED, CALL_USED): Renamed from GOT16_USED and CALL16_USED.
+       Fixed all references.
+       (nios2_elf32_relocate_section): Add new relocations.
+       (nios2_elf32_check_relocs): Likewise.
+       (nios2_elf32_gc_sweep_hook): Likewise.
+
 2014-02-03  Alan Modra  <amodra@gmail.com>
 
        * elf32-ppc.c (struct ppc_elf_link_hash_table): Add params.
index 036f65a..33792f4 100644 (file)
@@ -5227,6 +5227,10 @@ a matching LO8XG part.  */
   BFD_RELOC_NIOS2_RELATIVE,
   BFD_RELOC_NIOS2_GOTOFF,
   BFD_RELOC_NIOS2_CALL26_NOAT,
+  BFD_RELOC_NIOS2_GOT_LO,
+  BFD_RELOC_NIOS2_GOT_HA,
+  BFD_RELOC_NIOS2_CALL_LO,
+  BFD_RELOC_NIOS2_CALL_HA,
 
 /* IQ2000 Relocations.  */
   BFD_RELOC_IQ2000_OFFSET_16,
index dbe5289..b6a60ff 100644 (file)
@@ -670,6 +670,62 @@ static reloc_howto_type elf_nios2_howto_table_rel[] = {
         0xffffffc0,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
+  HOWTO (R_NIOS2_GOT_LO,
+        0,
+        2,
+        16,
+        FALSE,
+        6,
+        complain_overflow_dont,
+        bfd_elf_generic_reloc,
+        "R_NIOS2_GOT_LO",
+        FALSE,
+        0x003fffc0,
+        0x003fffc0,
+        FALSE),
+
+  HOWTO (R_NIOS2_GOT_HA,
+        0,
+        2,
+        16,
+        FALSE,
+        6,
+        complain_overflow_dont,
+        bfd_elf_generic_reloc,
+        "R_NIOS2_GOT_HA",
+        FALSE,
+        0x003fffc0,
+        0x003fffc0,
+        FALSE),
+
+  HOWTO (R_NIOS2_CALL_LO,
+        0,
+        2,
+        16,
+        FALSE,
+        6,
+        complain_overflow_dont,
+        bfd_elf_generic_reloc,
+        "R_NIOS2_CALL_LO",
+        FALSE,
+        0x003fffc0,
+        0x003fffc0,
+        FALSE),
+
+  HOWTO (R_NIOS2_CALL_HA,
+        0,
+        2,
+        16,
+        FALSE,
+        6,
+        complain_overflow_dont,
+        bfd_elf_generic_reloc,
+        "R_NIOS2_CALL_HA",
+        FALSE,
+        0x003fffc0,
+        0x003fffc0,
+        FALSE),
+
 /* Add other relocations here.  */
 };
 
@@ -749,6 +805,10 @@ static const struct elf_reloc_map nios2_reloc_map[] = {
   {BFD_RELOC_NIOS2_RELATIVE, R_NIOS2_RELATIVE},
   {BFD_RELOC_NIOS2_GOTOFF, R_NIOS2_GOTOFF},
   {BFD_RELOC_NIOS2_CALL26_NOAT, R_NIOS2_CALL26_NOAT},
+  {BFD_RELOC_NIOS2_GOT_LO, R_NIOS2_GOT_LO},
+  {BFD_RELOC_NIOS2_GOT_HA, R_NIOS2_GOT_HA},
+  {BFD_RELOC_NIOS2_CALL_LO, R_NIOS2_CALL_LO},
+  {BFD_RELOC_NIOS2_CALL_HA, R_NIOS2_CALL_HA},
 };
 
 enum elf32_nios2_stub_type
@@ -839,10 +899,11 @@ struct elf32_nios2_link_hash_entry
      a dynamic GOT reloc in shared objects, only a dynamic PLT reloc.  Lazy
      linking will not work if the dynamic GOT reloc exists.
      To check for this condition efficiently, we compare got_types_used against
-     CALL16_USED, meaning
-     (got_types_used & (GOT16_USED | CALL16_USED)) == CALL16_USED.  */
-#define GOT16_USED     1
-#define CALL16_USED    2
+     CALL_USED, meaning
+     (got_types_used & (GOT_USED | CALL_USED)) == CALL_USED.
+  */
+#define GOT_USED       1
+#define CALL_USED      2
   unsigned char got_types_used;
 };
 
@@ -2942,6 +3003,10 @@ nios2_elf32_relocate_section (bfd *output_bfd,
 
            case R_NIOS2_GOT16:
            case R_NIOS2_CALL16:
+           case R_NIOS2_GOT_LO:
+           case R_NIOS2_GOT_HA:
+           case R_NIOS2_CALL_LO:
+           case R_NIOS2_CALL_HA:
              /* Relocation is to the entry for this symbol in the
                 global offset table.  */
              if (sgot == NULL)
@@ -2957,7 +3022,7 @@ nios2_elf32_relocate_section (bfd *output_bfd,
                  bfd_boolean dyn;
 
                  eh = (struct elf32_nios2_link_hash_entry *)h;
-                 use_plt = (eh->got_types_used == CALL16_USED
+                 use_plt = (eh->got_types_used == CALL_USED
                             && h->plt.offset != (bfd_vma) -1);
 
                  off = h->got.offset;
@@ -3044,9 +3109,30 @@ nios2_elf32_relocate_section (bfd *output_bfd,
              /* This relocation does not use the addend.  */
              rel->r_addend = 0;
 
-             r = _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                           contents, rel->r_offset,
-                                           relocation, rel->r_addend);
+             switch (howto->type)
+               {
+               case R_NIOS2_GOT_LO:
+               case R_NIOS2_CALL_LO:
+                 r = nios2_elf32_do_lo16_relocate (input_bfd, howto,
+                                                   input_section, contents,
+                                                   rel->r_offset, relocation,
+                                                   rel->r_addend);
+                 break;
+               case R_NIOS2_GOT_HA:
+               case R_NIOS2_CALL_HA:
+                 r = nios2_elf32_do_hiadj16_relocate (input_bfd, howto,
+                                                      input_section, contents,
+                                                      rel->r_offset,
+                                                      relocation,
+                                                      rel->r_addend);
+                 break;
+               default:
+                 r = _bfd_final_link_relocate (howto, input_bfd,
+                                               input_section, contents,
+                                               rel->r_offset, relocation,
+                                               rel->r_addend);
+                 break;
+               }
              break;
 
            case R_NIOS2_GOTOFF_LO:
@@ -3671,7 +3757,11 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
       switch (r_type)
        {
        case R_NIOS2_GOT16:
+       case R_NIOS2_GOT_LO:
+       case R_NIOS2_GOT_HA:
        case R_NIOS2_CALL16:
+       case R_NIOS2_CALL_LO:
+       case R_NIOS2_CALL_HA:
        case R_NIOS2_TLS_GD16:
        case R_NIOS2_TLS_IE16:
          /* This symbol requires a global offset table entry.  */
@@ -3682,7 +3772,11 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
              {
              default:
              case R_NIOS2_GOT16:
+             case R_NIOS2_GOT_LO:
+             case R_NIOS2_GOT_HA:
              case R_NIOS2_CALL16:
+             case R_NIOS2_CALL_LO:
+             case R_NIOS2_CALL_HA:
                tls_type = GOT_NORMAL;
                break;
              case R_NIOS2_TLS_GD16:
@@ -3719,7 +3813,9 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                  = (struct elf32_nios2_link_hash_entry *)h;
                h->got.refcount++;
                old_tls_type = elf32_nios2_hash_entry(h)->tls_type;
-               if (r_type == R_NIOS2_CALL16)
+               if (r_type == R_NIOS2_CALL16
+                   || r_type == R_NIOS2_CALL_LO
+                   || r_type == R_NIOS2_CALL_HA)
                  {
                    /* Make sure a plt entry is created for this symbol if
                       it turns out to be a function defined by a dynamic
@@ -3727,10 +3823,10 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                    h->plt.refcount++;
                    h->needs_plt = 1;
                    h->type = STT_FUNC;
-                   eh->got_types_used |= CALL16_USED;
+                   eh->got_types_used |= CALL_USED;
                  }
                else
-                 eh->got_types_used |= GOT16_USED;
+                 eh->got_types_used |= GOT_USED;
              }
            else
              {
@@ -3964,7 +4060,11 @@ nios2_elf32_gc_sweep_hook (bfd *abfd,
       switch (r_type)
        {
        case R_NIOS2_GOT16:
+       case R_NIOS2_GOT_LO:
+       case R_NIOS2_GOT_HA:
        case R_NIOS2_CALL16:
+       case R_NIOS2_CALL_LO:
+       case R_NIOS2_CALL_HA:
          if (h != NULL)
            {
              if (h->got.refcount > 0)
@@ -4114,7 +4214,7 @@ nios2_elf32_finish_dynamic_symbol (bfd *output_bfd,
        }
     }
 
-  use_plt = (eh->got_types_used == CALL16_USED
+  use_plt = (eh->got_types_used == CALL_USED
             && h->plt.offset != (bfd_vma) -1);
 
   if (!use_plt && h->got.offset != (bfd_vma) -1
@@ -4587,7 +4687,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
     }
 
   eh = (struct elf32_nios2_link_hash_entry *) h;
-  use_plt = (eh->got_types_used == CALL16_USED
+  use_plt = (eh->got_types_used == CALL_USED
             && h->plt.offset != (bfd_vma) -1);
 
   if (h->got.refcount > 0)
index 9711e17..bbca43f 100644 (file)
@@ -2533,6 +2533,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_NIOS2_RELATIVE",
   "BFD_RELOC_NIOS2_GOTOFF",
   "BFD_RELOC_NIOS2_CALL26_NOAT",
+  "BFD_RELOC_NIOS2_GOT_LO",
+  "BFD_RELOC_NIOS2_GOT_HA",
+  "BFD_RELOC_NIOS2_CALL_LO",
+  "BFD_RELOC_NIOS2_CALL_HA",
   "BFD_RELOC_IQ2000_OFFSET_16",
   "BFD_RELOC_IQ2000_OFFSET_21",
   "BFD_RELOC_IQ2000_UHI16",
index 3d1256d..5cc6e0c 100644 (file)
@@ -6067,6 +6067,14 @@ ENUMX
   BFD_RELOC_NIOS2_GOTOFF
 ENUMX
   BFD_RELOC_NIOS2_CALL26_NOAT
+ENUMX
+  BFD_RELOC_NIOS2_GOT_LO
+ENUMX
+  BFD_RELOC_NIOS2_GOT_HA
+ENUMX
+  BFD_RELOC_NIOS2_CALL_LO
+ENUMX
+  BFD_RELOC_NIOS2_CALL_HA
 ENUMDOC
   Relocations used by the Altera Nios II core.
 
index a3f0f03..19d4025 100644 (file)
@@ -1,3 +1,13 @@
+2014-02-03  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * config/tc-nios2.c (md_apply_fix): Test for new relocs.
+       (nios2_special_reloc): Add %call_lo, %call_hiadj, %got_lo,
+       %got_hiadj relocation operators.  Sort table and add comment
+       to explain ordering.
+       (nios2_fix_adjustable): Test for new relocs.
+       * doc/c-nios2.texi (Nios II Relocations): Document new relocation
+       operators.
+
 2014-01-30  Sandra Loosemore  <sandra@codesourcery.com>
 
        * config/tc-nios2.c (md_apply_fix): Handle BFD_RELOC_NIOS2_CALL26_NOAT.
index eb81b35..3d52048 100644 (file)
@@ -1139,7 +1139,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
                  || fixP->fx_r_type == BFD_RELOC_NIOS2_U16
                  || fixP->fx_r_type == BFD_RELOC_16_PCREL
                  || fixP->fx_r_type == BFD_RELOC_NIOS2_CALL26
-                 || fixP->fx_r_type == BFD_RELOC_NIOS2_CALL26_NOAT
                  || fixP->fx_r_type == BFD_RELOC_NIOS2_IMM5
                  || fixP->fx_r_type == BFD_RELOC_NIOS2_CACHE_OPX
                  || fixP->fx_r_type == BFD_RELOC_NIOS2_IMM6
@@ -1165,6 +1164,11 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
                  || fixP->fx_r_type == BFD_RELOC_NIOS2_TLS_LE16
                  || fixP->fx_r_type == BFD_RELOC_NIOS2_GOTOFF
                  || fixP->fx_r_type == BFD_RELOC_NIOS2_TLS_DTPREL
+                 || fixP->fx_r_type == BFD_RELOC_NIOS2_CALL26_NOAT
+                 || fixP->fx_r_type == BFD_RELOC_NIOS2_GOT_LO
+                 || fixP->fx_r_type == BFD_RELOC_NIOS2_GOT_HA
+                 || fixP->fx_r_type == BFD_RELOC_NIOS2_CALL_LO
+                 || fixP->fx_r_type == BFD_RELOC_NIOS2_CALL_HA
                  /* Add other relocs here as we generate them.  */
                  ));
 
@@ -1301,21 +1305,28 @@ struct nios2_special_relocS
   bfd_reloc_code_real_type reloc_type;
 };
 
+/* This table is sorted so that prefix strings are listed after the longer
+   strings that include them -- e.g., %got after %got_hiadj, etc.  */
+
 struct nios2_special_relocS nios2_special_reloc[] = {
   {"%hiadj", BFD_RELOC_NIOS2_HIADJ16},
   {"%hi", BFD_RELOC_NIOS2_HI16},
   {"%lo", BFD_RELOC_NIOS2_LO16},
   {"%gprel", BFD_RELOC_NIOS2_GPREL},
+  {"%call_lo", BFD_RELOC_NIOS2_CALL_LO},
+  {"%call_hiadj", BFD_RELOC_NIOS2_CALL_HA},
   {"%call", BFD_RELOC_NIOS2_CALL16},
   {"%gotoff_lo", BFD_RELOC_NIOS2_GOTOFF_LO},
   {"%gotoff_hiadj", BFD_RELOC_NIOS2_GOTOFF_HA},
+  {"%gotoff", BFD_RELOC_NIOS2_GOTOFF},
+  {"%got_hiadj", BFD_RELOC_NIOS2_GOT_HA},
+  {"%got_lo", BFD_RELOC_NIOS2_GOT_LO},
+  {"%got", BFD_RELOC_NIOS2_GOT16},
   {"%tls_gd", BFD_RELOC_NIOS2_TLS_GD16},
   {"%tls_ldm", BFD_RELOC_NIOS2_TLS_LDM16},
   {"%tls_ldo", BFD_RELOC_NIOS2_TLS_LDO16},
   {"%tls_ie", BFD_RELOC_NIOS2_TLS_IE16},
   {"%tls_le", BFD_RELOC_NIOS2_TLS_LE16},
-  {"%gotoff", BFD_RELOC_NIOS2_GOTOFF},
-  {"%got", BFD_RELOC_NIOS2_GOT16}
 };
 
 #define NIOS2_NUM_SPECIAL_RELOCS \
@@ -2824,7 +2835,12 @@ nios2_fix_adjustable (fixS *fixp)
       || fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_DTPMOD
       || fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_DTPREL
       || fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_TPREL
-      || fixp->fx_r_type == BFD_RELOC_NIOS2_GOTOFF)
+      || fixp->fx_r_type == BFD_RELOC_NIOS2_GOTOFF
+      || fixp->fx_r_type == BFD_RELOC_NIOS2_GOT_LO
+      || fixp->fx_r_type == BFD_RELOC_NIOS2_GOT_HA
+      || fixp->fx_r_type == BFD_RELOC_NIOS2_CALL_LO
+      || fixp->fx_r_type == BFD_RELOC_NIOS2_CALL_HA
+      )
     return 0;
 
   return 1;
index 1d45dd2..0ba6b9b 100644 (file)
@@ -131,7 +131,11 @@ fastint:
 @end smallexample
 
 @cindex @code{call} directive, Nios II
+@cindex @code{call_lo} directive, Nios II
+@cindex @code{call_hiadj} directive, Nios II
 @cindex @code{got} directive, Nios II
+@cindex @code{got_lo} directive, Nios II
+@cindex @code{got_hiadj} directive, Nios II
 @cindex @code{gotoff} directive, Nios II
 @cindex @code{gotoff_lo} directive, Nios II
 @cindex @code{gotoff_hiadj} directive, Nios II
@@ -141,7 +145,11 @@ fastint:
 @cindex @code{tls_ldm} directive, Nios II
 @cindex @code{tls_ldo} directive, Nios II
 @item %call(@var{expression})
+@item %call_lo(@var{expression})
+@item %call_hiadj(@var{expression})
 @itemx %got(@var{expression})
+@itemx %got_lo(@var{expression})
+@itemx %got_hiadj(@var{expression})
 @itemx %gotoff(@var{expression})
 @itemx %gotoff_lo(@var{expression})
 @itemx %gotoff_hiadj(@var{expression})
index 28272d8..6d144b4 100644 (file)
@@ -1,3 +1,9 @@
+2014-02-03  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * nios2.h (R_NIOS2_GOT_LO, R_NIOS2_GOT_HA): New.
+       (R_NIOS2_CALL_LO, R_NIOS2_CALL_HA): New.
+       (R_NIOS2_ILLEGAL): Adjust.
+
 2014-01-30  Sandra Loosemore  <sandra@codesourcery.com>
 
        * nios2.h (elf_nios2_reloc_type): Add R_NIOS2_CALL26_NOAT.
index 7686350..47afc0f 100644 (file)
@@ -76,7 +76,11 @@ START_RELOC_NUMBERS (elf_nios2_reloc_type)
   RELOC_NUMBER (R_NIOS2_RELATIVE, 39)
   RELOC_NUMBER (R_NIOS2_GOTOFF, 40)
   RELOC_NUMBER (R_NIOS2_CALL26_NOAT,  41)
-  RELOC_NUMBER (R_NIOS2_ILLEGAL, 42)
+  RELOC_NUMBER (R_NIOS2_GOT_LO, 42)
+  RELOC_NUMBER (R_NIOS2_GOT_HA, 43)
+  RELOC_NUMBER (R_NIOS2_CALL_LO, 44)
+  RELOC_NUMBER (R_NIOS2_CALL_HA, 45)
+  RELOC_NUMBER (R_NIOS2_ILLEGAL, 46)
 END_RELOC_NUMBERS (R_NIOS2_maxext)
 
 /* Processor-specific section flags.  */