summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-02-09 22:53:53 +0000
committerRichard Henderson <rth@redhat.com>2002-02-09 22:53:53 +0000
commit2ef1cc2c94c0dbce9730e15c532071c35b2d8595 (patch)
tree19b4fb167b0d181afc46d4ec370064bb4e4b8098
parent6bb3d76fd766e6cb683977efac98eccb573f9433 (diff)
downloadgdb-2ef1cc2c94c0dbce9730e15c532071c35b2d8595.tar.gz
* 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.
-rw-r--r--bfd/ChangeLog8
-rw-r--r--bfd/bfd-in2.h5
-rw-r--r--bfd/elf64-alpha.c83
-rw-r--r--bfd/libbfd.h1
-rw-r--r--bfd/reloc.c7
5 files changed, 103 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index bf5854df4e4..ab71fcfc2bd 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 2692b00d6b4..ff4ba0d5c8e 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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,
diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c
index ef6e853615d..6df126a4d13 100644
--- a/bfd/elf64-alpha.c
+++ b/bfd/elf64-alpha.c
@@ -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:
{
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index ad99a07fe1f..d864b22e24c 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -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",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 40e07a6a2d5..559a351dfd7 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -1956,6 +1956,13 @@ ENUMDOC
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
Bits 27..2 of the relocation address shifted right 2 bits;