From 7793f4d007be419ed2020614783f0797cc5e3634 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 9 Feb 2002 22:53:53 +0000 Subject: [PATCH] * 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. --- bfd/ChangeLog | 8 +++++ bfd/bfd-in2.h | 5 +++ bfd/elf64-alpha.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++- bfd/libbfd.h | 1 + bfd/reloc.c | 7 ++++ 5 files changed, 103 insertions(+), 1 deletion(-) 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 + + * 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 * 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 = _(""); + 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 = _(""); + 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 @@ -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 -- 2.30.2