* 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.
This commit is contained in:
parent
da966255a5
commit
7793f4d007
5 changed files with 103 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
{
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue