* elf64-alpha.c (elf64_alpha_howto): Add R_ALPHA_BRSGP.
authorRichard Henderson <rth@redhat.com>
Sat, 9 Feb 2002 22:53:53 +0000 (22:53 +0000)
committerRichard Henderson <rth@redhat.com>
Sat, 9 Feb 2002 22:53:53 +0000 (22:53 +0000)
        (elf64_alpha_reloc_map, elf64_alpha_check_relocs): Likewise.
        (elf64_alpha_relocate_section): Likewise.
        * reloc.c (BFD_RELOC_ALPHA_BRSGP): New.
        * bfd-in2.h, libbfd.h: Rebuild.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf64-alpha.c
bfd/libbfd.h
bfd/reloc.c

index bf5854df4e4c1a73ca4353cbdac3f885e477bbd3..ab71fcfc2bdc7bd4d1a4be2b84b04447f7b7ab3c 100644 (file)
@@ -1,3 +1,11 @@
+2002-02-09  Richard Henderson  <rth@redhat.com>
+
+       * elf64-alpha.c (elf64_alpha_howto): Add R_ALPHA_BRSGP.
+       (elf64_alpha_reloc_map, elf64_alpha_check_relocs): Likewise.
+       (elf64_alpha_relocate_section): Likewise.
+       * reloc.c (BFD_RELOC_ALPHA_BRSGP): New.
+       * bfd-in2.h, libbfd.h: Rebuild.
+
 2002-02-09  Hans-Peter Nilsson  <hp@bitrange.com>
 
        * elf64-mmix.c (_bfd_mmix_finalize_linker_allocated_gregs): Check
index 2692b00d6b4d014d74cffdcf2bce15746b85d2ce..ff4ba0d5c8e3eaf3b54ddf4cf38272e3c4cf8e98 100644 (file)
@@ -2136,6 +2136,11 @@ GP register.  */
   BFD_RELOC_ALPHA_GPREL_HI16,
   BFD_RELOC_ALPHA_GPREL_LO16,
 
+/* Like BFD_RELOC_23_PCREL_S2, except that the source and target must
+share a common GP, and the target address is adjusted for 
+STO_ALPHA_STD_GPLOAD.  */
+  BFD_RELOC_ALPHA_BRSGP,
+
 /* Bits 27..2 of the relocation address shifted right 2 bits;
 simple reloc otherwise.  */
   BFD_RELOC_MIPS_JMP,
index ef6e853615d4ec684b2532c8becc675a1fe2f034..6df126a4d13c9237744dc57654069fdb6b0b5ede 100644 (file)
@@ -732,7 +732,22 @@ static reloc_howto_type elf64_alpha_howto_table[] =
         false,
         0,
         0,
-        true)
+        true),
+
+  /* A 21 bit branch that adjusts for gp loads.  */
+  HOWTO (R_ALPHA_BRSGP,                /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        21,                    /* bitsize */
+        true,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        0,                     /* special_function */
+        "BRSGP",               /* name */
+        false,                 /* partial_inplace */
+        0x1fffff,              /* src_mask */
+        0x1fffff,              /* dst_mask */
+        true),                 /* pcrel_offset */
 };
 
 /* A relocation function which doesn't do anything.  */
@@ -886,6 +901,7 @@ static const struct elf_reloc_map elf64_alpha_reloc_map[] =
   {BFD_RELOC_ALPHA_GPREL_HI16,         R_ALPHA_GPRELHIGH},
   {BFD_RELOC_ALPHA_GPREL_LO16,         R_ALPHA_GPRELLOW},
   {BFD_RELOC_GPREL16,                  R_ALPHA_GPREL16},
+  {BFD_RELOC_ALPHA_BRSGP,              R_ALPHA_BRSGP},
 };
 
 /* Given a BFD reloc type, return a HOWTO structure.  */
@@ -2414,6 +2430,7 @@ elf64_alpha_check_relocs (abfd, info, sec, relocs)
        case R_ALPHA_GPREL32:
        case R_ALPHA_GPRELHIGH:
        case R_ALPHA_GPRELLOW:
+       case R_ALPHA_BRSGP:
          /* We don't actually use the .got here, but the sections must
             be created before the linker maps input sections to output
             sections.  */
@@ -3555,6 +3572,70 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section,
          addend -= 4;
          goto default_reloc;
 
+       case R_ALPHA_BRSGP:
+         {
+           int other;
+           const char *name;
+
+           /* The regular PC-relative stuff measures from the start of
+              the instruction rather than the end.  */
+           addend -= 4;
+
+           /* The source and destination gp must be the same.  */
+           if (h != NULL
+               && gotobj != alpha_elf_tdata (sec->owner)->gotobj)
+             {
+               if (h != NULL)
+                 name = h->root.root.root.string;
+               else
+                 {
+                   name = (bfd_elf_string_from_elf_section
+                           (input_bfd, symtab_hdr->sh_link, sym->st_name));
+                   if (name == NULL)
+                     name = _("<unknown>");
+                   else if (name[0] == 0)
+                     name = bfd_section_name (input_bfd, sec);
+                 }
+               (*_bfd_error_handler)
+                 (_("%s: change in gp: BRSGP %s"),
+                  bfd_archive_filename (input_bfd), name);
+               ret_val = false;
+             }
+
+           /* The symbol should be marked either NOPV or STD_GPLOAD.  */
+           if (h != NULL)
+             other = h->root.other;
+           else
+             other = sym->st_other;
+           switch (other & STO_ALPHA_STD_GPLOAD)
+             {
+             case STO_ALPHA_NOPV:
+               break;
+             case STO_ALPHA_STD_GPLOAD:
+               addend += 8;
+               break;
+             default:
+               if (h != NULL)
+                 name = h->root.root.root.string;
+               else
+                 {
+                   name = (bfd_elf_string_from_elf_section
+                           (input_bfd, symtab_hdr->sh_link, sym->st_name));
+                   if (name == NULL)
+                     name = _("<unknown>");
+                   else if (name[0] == 0)
+                     name = bfd_section_name (input_bfd, sec);
+                 }
+               (*_bfd_error_handler)
+                 (_("%s: !samegp reloc against symbol without .prologue: %s"),
+                  bfd_archive_filename (input_bfd), name);
+               ret_val = false;
+               break;
+             }
+
+           goto default_reloc;
+         }
+
        case R_ALPHA_REFLONG:
        case R_ALPHA_REFQUAD:
          {
index ad99a07fe1fc35d9f7881eb809a4a820dd590499..d864b22e24c051abb368ea8640d408c776ac98fe 100644 (file)
@@ -721,6 +721,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_ALPHA_CODEADDR",
   "BFD_RELOC_ALPHA_GPREL_HI16",
   "BFD_RELOC_ALPHA_GPREL_LO16",
+  "BFD_RELOC_ALPHA_BRSGP",
   "BFD_RELOC_MIPS_JMP",
   "BFD_RELOC_MIPS16_JMP",
   "BFD_RELOC_MIPS16_GPREL",
index 40e07a6a2d5b47ad6da7d92b1bc79de2ba5b11d3..559a351dfd74e6f901d42d34bd8fddda38aab069 100644 (file)
@@ -1955,6 +1955,13 @@ ENUMDOC
   The GPREL_HI/LO relocations together form a 32-bit offset from the
      GP register.
 
+ENUM
+  BFD_RELOC_ALPHA_BRSGP
+ENUMDOC
+  Like BFD_RELOC_23_PCREL_S2, except that the source and target must
+  share a common GP, and the target address is adjusted for 
+  STO_ALPHA_STD_GPLOAD.
+
 ENUM
   BFD_RELOC_MIPS_JMP
 ENUMDOC