* bfd-in2.h: Regenerate.

* elf32-s390.c (elf_s390_adjust_gotplt): New prototype.
	(elf_howto_table): Rename R_390_GOTOFF to R_390_GOTOFF32. Add
	R_390_GOTOFF16, R_390_GOTOFF64, R_390_GOTPLT12, R_390_GOTPLT16,
	R_390_GOTPLT32, R_390_GOTPLT64, R_390_GOTPLTENT, R_390_PLTOFF16,
	R_390_PLTOFF32 and R_390_PLTOFF64.
	(elf_s390_reloc_type_lookup): Likewise.
	(struct elf_s390_link_hash_entry): Add gotplt_refcount to keep track
	of GOTPLT references to a function.
	(link_hash_newfunc): Initialize gotplt_refcount.
	(elf_s390_check_relocs): Move allocation of local_got_refcounts array
	and creation of the got section out of the main switch. Add support
	for the gotoff, gotplt and pltoff relocations.
	(elf_s390_gc_sweep_hook): Add reference counting for gotoff, gotplt
	and pltoff.
	(elf_s390_adjust_gotplt): New function.
	(elf_s390_adjust_dynamic_symbol): Adjust gotplt refcount for removed
	plt entries.
	(allocate_dynrelocs): Add comment.
	(elf_s390_relocate_section): Change r_type to unsigned. Add support
	for gotoff, gotplt and pltoff relocations.
	* elf64-s390.c: Same changes as for elf32-s390.c.
	* libbfd.h: Regenerate.
	* reloc.c: Add BFD_RELOC_390_GOTOFF64, BFD_RELOC_390_GOTPLT12,
	BFD_RELOC_390_GOTPLT16, BFD_RELOC_390_GOTPLT32, BFD_RELOC_390_GOTPLT64,
	BFD_RELOC_390_GOTPLTENT, BFD_RELOC_390_PLTOFF16, BFD_RELOC_390_PLTOFF32
	and BFD_RELOC_390_PLTOFF64.
This commit is contained in:
Martin Schwidefsky 2003-01-20 11:46:33 +00:00
parent f1fc51dabb
commit 5236c819d2
6 changed files with 827 additions and 264 deletions

View File

@ -1,3 +1,33 @@
2003-01-20 Martin Schwidefsky <schwidefsky@de.ibm.com>
* bfd-in2.h: Regenerate.
* elf32-s390.c (elf_s390_adjust_gotplt): New prototype.
(elf_howto_table): Rename R_390_GOTOFF to R_390_GOTOFF32. Add
R_390_GOTOFF16, R_390_GOTOFF64, R_390_GOTPLT12, R_390_GOTPLT16,
R_390_GOTPLT32, R_390_GOTPLT64, R_390_GOTPLTENT, R_390_PLTOFF16,
R_390_PLTOFF32 and R_390_PLTOFF64.
(elf_s390_reloc_type_lookup): Likewise.
(struct elf_s390_link_hash_entry): Add gotplt_refcount to keep track
of GOTPLT references to a function.
(link_hash_newfunc): Initialize gotplt_refcount.
(elf_s390_check_relocs): Move allocation of local_got_refcounts array
and creation of the got section out of the main switch. Add support
for the gotoff, gotplt and pltoff relocations.
(elf_s390_gc_sweep_hook): Add reference counting for gotoff, gotplt
and pltoff.
(elf_s390_adjust_gotplt): New function.
(elf_s390_adjust_dynamic_symbol): Adjust gotplt refcount for removed
plt entries.
(allocate_dynrelocs): Add comment.
(elf_s390_relocate_section): Change r_type to unsigned. Add support
for gotoff, gotplt and pltoff relocations.
* elf64-s390.c: Same changes as for elf32-s390.c.
* libbfd.h: Regenerate.
* reloc.c: Add BFD_RELOC_390_GOTOFF64, BFD_RELOC_390_GOTPLT12,
BFD_RELOC_390_GOTPLT16, BFD_RELOC_390_GOTPLT32, BFD_RELOC_390_GOTPLT64,
BFD_RELOC_390_GOTPLTENT, BFD_RELOC_390_PLTOFF16, BFD_RELOC_390_PLTOFF32
and BFD_RELOC_390_PLTOFF64.
2003-01-18 Jakub Jelinek <jakub@redhat.com>
* elfxx-ia64.c (elfNN_ia64_relocate_section): Handle

View File

@ -2996,6 +2996,33 @@ into 22 bits. */
/* 32 bit rel. offset to GOT entry. */
BFD_RELOC_390_GOTENT,
/* 64 bit offset to GOT. */
BFD_RELOC_390_GOTOFF64,
/* 12-bit offset to symbol-entry within GOT, with PLT handling. */
BFD_RELOC_390_GOTPLT12,
/* 16-bit offset to symbol-entry within GOT, with PLT handling. */
BFD_RELOC_390_GOTPLT16,
/* 32-bit offset to symbol-entry within GOT, with PLT handling. */
BFD_RELOC_390_GOTPLT32,
/* 64-bit offset to symbol-entry within GOT, with PLT handling. */
BFD_RELOC_390_GOTPLT64,
/* 32-bit rel. offset to symbol-entry within GOT, with PLT handling. */
BFD_RELOC_390_GOTPLTENT,
/* 16-bit rel. offset from the GOT to a PLT entry. */
BFD_RELOC_390_PLTOFF16,
/* 32-bit rel. offset from the GOT to a PLT entry. */
BFD_RELOC_390_PLTOFF32,
/* 64-bit rel. offset from the GOT to a PLT entry. */
BFD_RELOC_390_PLTOFF64,
/* Scenix IP2K - 9-bit register number / data address */
BFD_RELOC_IP2K_FR9,

View File

@ -51,6 +51,9 @@ static asection *elf_s390_gc_mark_hook
static bfd_boolean elf_s390_gc_sweep_hook
PARAMS ((bfd *, struct bfd_link_info *, asection *,
const Elf_Internal_Rela *));
struct elf_s390_link_hash_entry;
static void elf_s390_adjust_gotplt
PARAMS ((struct elf_s390_link_hash_entry *));
static bfd_boolean elf_s390_adjust_dynamic_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
static bfd_boolean allocate_dynrelocs
@ -94,28 +97,71 @@ static reloc_howto_type elf_howto_table[] =
0, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO(R_390_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_8", FALSE, 0,0x000000ff, FALSE),
HOWTO(R_390_12, 0, 1, 12, FALSE, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_390_12", FALSE, 0,0x00000fff, FALSE),
HOWTO(R_390_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_16", FALSE, 0,0x0000ffff, FALSE),
HOWTO(R_390_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_32", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_PC32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC32", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_GOT12, 0, 1, 12, FALSE, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_390_GOT12", FALSE, 0,0x00000fff, FALSE),
HOWTO(R_390_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT32", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT32", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_COPY", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_GLOB_DAT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GLOB_DAT",FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_JMP_SLOT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_JMP_SLOT",FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_RELATIVE, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_RELATIVE",FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_GOTOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTOFF", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_GOTPC, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTPC", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_GOT16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT16", FALSE, 0,0x0000ffff, FALSE),
HOWTO(R_390_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC16", FALSE, 0,0x0000ffff, TRUE),
HOWTO(R_390_PC16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC16DBL", FALSE, 0,0x0000ffff, TRUE),
HOWTO(R_390_PLT16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT16DBL", FALSE, 0,0x0000ffff, TRUE),
HOWTO(R_390_PC32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC32DBL", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_PLT32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT32DBL", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_GOTPCDBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTPCDBL", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_GOTENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTENT", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_8", FALSE, 0,0x000000ff, FALSE),
HOWTO(R_390_12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_390_12", FALSE, 0,0x00000fff, FALSE),
HOWTO(R_390_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_16", FALSE, 0,0x0000ffff, FALSE),
HOWTO(R_390_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_32", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_PC32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PC32", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_GOT12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_390_GOT12", FALSE, 0,0x00000fff, FALSE),
HOWTO(R_390_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOT32", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLT32", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_COPY", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_GLOB_DAT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GLOB_DAT", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_JMP_SLOT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_JMP_SLOT", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_RELATIVE, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_RELATIVE", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_GOTOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTOFF32", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_GOTPC, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTPC", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_GOT16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOT16", FALSE, 0,0x0000ffff, FALSE),
HOWTO(R_390_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PC16", FALSE, 0,0x0000ffff, TRUE),
HOWTO(R_390_PC16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PC16DBL", FALSE, 0,0x0000ffff, TRUE),
HOWTO(R_390_PLT16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLT16DBL", FALSE, 0,0x0000ffff, TRUE),
HOWTO(R_390_PC32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PC32DBL", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_PLT32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLT32DBL", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_GOTPCDBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTPCDBL", FALSE, 0,0xffffffff, TRUE),
EMPTY_HOWTO (R_390_64), /* Empty entry for R_390_64. */
EMPTY_HOWTO (R_390_PC64), /* Empty entry for R_390_PC64. */
EMPTY_HOWTO (R_390_GOT64), /* Empty entry for R_390_GOT64. */
EMPTY_HOWTO (R_390_PLT64), /* Empty entry for R_390_PLT64. */
HOWTO(R_390_GOTENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTENT", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_GOTOFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTOFF16", FALSE, 0,0x0000ffff, FALSE),
EMPTY_HOWTO (R_390_GOTOFF64), /* Empty entry for R_390_GOTOFF64. */
HOWTO(R_390_GOTPLT12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_390_GOTPLT12", FALSE, 0,0x00000fff, FALSE),
HOWTO(R_390_GOTPLT16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTPLT16", FALSE, 0,0x0000ffff, FALSE),
HOWTO(R_390_GOTPLT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTPLT32", FALSE, 0,0xffffffff, FALSE),
EMPTY_HOWTO (R_390_GOTPLT64), /* Empty entry for R_390_GOTPLT64. */
HOWTO(R_390_GOTPLTENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTPLTENT",FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_PLTOFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLTOFF16", FALSE, 0,0x0000ffff, FALSE),
HOWTO(R_390_PLTOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLTOFF32", FALSE, 0,0xffffffff, FALSE),
EMPTY_HOWTO (R_390_PLTOFF64), /* Empty entry for R_390_PLTOFF64. */
};
/* GNU extension to record C++ vtable hierarchy. */
@ -160,7 +206,7 @@ elf_s390_reloc_type_lookup (abfd, code)
case BFD_RELOC_390_RELATIVE:
return &elf_howto_table[(int) R_390_RELATIVE];
case BFD_RELOC_32_GOTOFF:
return &elf_howto_table[(int) R_390_GOTOFF];
return &elf_howto_table[(int) R_390_GOTOFF32];
case BFD_RELOC_390_GOTPC:
return &elf_howto_table[(int) R_390_GOTPC];
case BFD_RELOC_390_GOT16:
@ -179,6 +225,20 @@ elf_s390_reloc_type_lookup (abfd, code)
return &elf_howto_table[(int) R_390_GOTPCDBL];
case BFD_RELOC_390_GOTENT:
return &elf_howto_table[(int) R_390_GOTENT];
case BFD_RELOC_16_GOTOFF:
return &elf_howto_table[(int) R_390_GOTOFF16];
case BFD_RELOC_390_GOTPLT12:
return &elf_howto_table[(int) R_390_GOTPLT12];
case BFD_RELOC_390_GOTPLT16:
return &elf_howto_table[(int) R_390_GOTPLT16];
case BFD_RELOC_390_GOTPLT32:
return &elf_howto_table[(int) R_390_GOTPLT32];
case BFD_RELOC_390_GOTPLTENT:
return &elf_howto_table[(int) R_390_GOTPLTENT];
case BFD_RELOC_390_PLTOFF16:
return &elf_howto_table[(int) R_390_PLTOFF16];
case BFD_RELOC_390_PLTOFF32:
return &elf_howto_table[(int) R_390_PLTOFF32];
case BFD_RELOC_VTABLE_INHERIT:
return &elf32_s390_vtinherit_howto;
case BFD_RELOC_VTABLE_ENTRY:
@ -413,6 +473,9 @@ struct elf_s390_link_hash_entry
/* Track dynamic relocs copied for this symbol. */
struct elf_s390_dyn_relocs *dyn_relocs;
/* Number of GOTPLT references for a function. */
bfd_signed_vma gotplt_refcount;
};
/* s390 ELF linker hash table. */
@ -465,6 +528,7 @@ link_hash_newfunc (entry, table, string)
eh = (struct elf_s390_link_hash_entry *) entry;
eh->dyn_relocs = NULL;
eh->gotplt_refcount = 0;
}
return entry;
@ -628,6 +692,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
const Elf_Internal_Rela *rel;
const Elf_Internal_Rela *rel_end;
asection *sreloc;
bfd_signed_vma *local_got_refcounts;
if (info->relocateable)
return TRUE;
@ -635,6 +700,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
htab = elf_s390_hash_table (info);
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
local_got_refcounts = elf_local_got_refcounts (abfd);
sreloc = NULL;
@ -659,40 +725,34 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
else
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
/* Create got section and local_got_refcounts array if they
are needed. */
switch (ELF32_R_TYPE (rel->r_info))
{
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT16:
case R_390_GOT32:
case R_390_GOTENT:
/* This symbol requires a global offset table entry. */
if (h != NULL)
case R_390_GOTPLT12:
case R_390_GOTPLT16:
case R_390_GOTPLT32:
case R_390_GOTPLTENT:
if (h == NULL
&& local_got_refcounts == NULL)
{
h->got.refcount += 1;
}
else
{
bfd_signed_vma *local_got_refcounts;
/* This is a global offset table entry for a local symbol. */
local_got_refcounts = elf_local_got_refcounts (abfd);
bfd_size_type size;
size = symtab_hdr->sh_info;
size *= sizeof (bfd_signed_vma);
local_got_refcounts = ((bfd_signed_vma *)
bfd_zalloc (abfd, size));
if (local_got_refcounts == NULL)
{
bfd_size_type size;
size = symtab_hdr->sh_info;
size *= sizeof (bfd_signed_vma);
local_got_refcounts = ((bfd_signed_vma *)
bfd_zalloc (abfd, size));
if (local_got_refcounts == NULL)
return FALSE;
elf_local_got_refcounts (abfd) = local_got_refcounts;
}
local_got_refcounts[r_symndx] += 1;
return FALSE;
elf_local_got_refcounts (abfd) = local_got_refcounts;
}
/* Fall through */
case R_390_GOTOFF:
/* Fall through. */
case R_390_GOTOFF16:
case R_390_GOTOFF32:
case R_390_GOTPC:
case R_390_GOTPCDBL:
if (htab->sgot == NULL)
@ -702,11 +762,33 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
if (!create_got_section (htab->elf.dynobj, info))
return FALSE;
}
}
switch (ELF32_R_TYPE (rel->r_info))
{
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
case R_390_GOTENT:
/* This symbol requires a global offset table entry. */
if (h != NULL)
h->got.refcount += 1;
else
local_got_refcounts[r_symndx] += 1;
break;
case R_390_GOTOFF16:
case R_390_GOTOFF32:
case R_390_GOTPC:
case R_390_GOTPCDBL:
/* Got is created, nothing to be done. */
break;
case R_390_PLT16DBL:
case R_390_PLT32DBL:
case R_390_PLT32:
case R_390_PLTOFF16:
case R_390_PLTOFF32:
/* This symbol requires a procedure linkage table entry. We
actually build the entry in adjust_dynamic_symbol,
because this might be a case of linking PIC code which is
@ -716,11 +798,33 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
/* If this is a local symbol, we resolve it directly without
creating a procedure linkage table entry. */
if (h == NULL)
continue;
if (h != NULL)
{
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
h->plt.refcount += 1;
}
break;
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
h->plt.refcount += 1;
case R_390_GOTPLT12:
case R_390_GOTPLT16:
case R_390_GOTPLT32:
case R_390_GOTPLTENT:
/* This symbol requires either a procedure linkage table entry
or an entry in the local got. We actually build the entry
in adjust_dynamic_symbol because whether this is really a
global reference can change and with it the fact if we have
to create a plt entry or a local got entry. To be able to
make a once global symbol a local one we have to keep track
of the number of gotplt references that exist for this
symbol. */
if (h != NULL)
{
((struct elf_s390_link_hash_entry *) h)->gotplt_refcount++;
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
h->plt.refcount += 1;
}
else
local_got_refcounts[r_symndx] += 1;
break;
case R_390_8:
@ -965,86 +1069,133 @@ elf_s390_gc_sweep_hook (abfd, info, sec, relocs)
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; rel++)
switch (ELF32_R_TYPE (rel->r_info))
{
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
case R_390_GOTOFF:
case R_390_GOTPC:
case R_390_GOTPCDBL:
case R_390_GOTENT:
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
if (h->got.refcount > 0)
h->got.refcount -= 1;
}
else if (local_got_refcounts != NULL)
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
break;
{
r_symndx = ELF32_R_SYM (rel->r_info);
case R_390_8:
case R_390_12:
case R_390_16:
case R_390_32:
case R_390_PC16:
case R_390_PC16DBL:
case R_390_PC32DBL:
case R_390_PC32:
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
struct elf_s390_link_hash_entry *eh;
struct elf_s390_dyn_relocs **pp;
struct elf_s390_dyn_relocs *p;
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
switch (ELF32_R_TYPE (rel->r_info))
{
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
case R_390_GOTOFF16:
case R_390_GOTOFF32:
case R_390_GOTPC:
case R_390_GOTPCDBL:
case R_390_GOTENT:
if (h != NULL)
{
if (h->got.refcount > 0)
h->got.refcount -= 1;
}
else if (local_got_refcounts != NULL)
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
break;
case R_390_PLT16DBL:
case R_390_PLT32DBL:
case R_390_PLT32:
case R_390_PLTOFF16:
case R_390_PLTOFF32:
if (h != NULL)
{
if (h->plt.refcount > 0)
h->plt.refcount -= 1;
}
break;
if (!info->shared && h->plt.refcount > 0)
h->plt.refcount -= 1;
eh = (struct elf_s390_link_hash_entry *) h;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
case R_390_GOTPLT12:
case R_390_GOTPLT16:
case R_390_GOTPLT32:
case R_390_GOTPLTENT:
if (h != NULL)
{
if (h->plt.refcount > 0)
{
if (ELF32_R_TYPE (rel->r_info) == R_390_PC16
|| ELF32_R_TYPE (rel->r_info) == R_390_PC16DBL
|| ELF32_R_TYPE (rel->r_info) == R_390_PC32DBL
|| ELF32_R_TYPE (rel->r_info) == R_390_PC32)
p->pc_count -= 1;
p->count -= 1;
if (p->count == 0)
*pp = p->next;
break;
((struct elf_s390_link_hash_entry *) h)->gotplt_refcount--;
h->plt.refcount -= 1;
}
}
break;
}
else if (local_got_refcounts != NULL)
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
break;
case R_390_PLT16DBL:
case R_390_PLT32DBL:
case R_390_PLT32:
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
if (h->plt.refcount > 0)
h->plt.refcount -= 1;
}
break;
default:
break;
}
case R_390_8:
case R_390_12:
case R_390_16:
case R_390_32:
case R_390_PC16:
case R_390_PC16DBL:
case R_390_PC32DBL:
case R_390_PC32:
if (h != NULL)
{
struct elf_s390_link_hash_entry *eh;
struct elf_s390_dyn_relocs **pp;
struct elf_s390_dyn_relocs *p;
if (!info->shared && h->plt.refcount > 0)
h->plt.refcount -= 1;
eh = (struct elf_s390_link_hash_entry *) h;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
{
if (ELF32_R_TYPE (rel->r_info) == R_390_PC16
|| ELF32_R_TYPE (rel->r_info) == R_390_PC16DBL
|| ELF32_R_TYPE (rel->r_info) == R_390_PC32DBL
|| ELF32_R_TYPE (rel->r_info) == R_390_PC32)
p->pc_count -= 1;
p->count -= 1;
if (p->count == 0)
*pp = p->next;
break;
}
}
break;
default:
break;
}
}
return TRUE;
}
/* Make sure we emit a GOT entry if the symbol was supposed to have a PLT
entry but we found we will not create any. Called when we find we will
not have any PLT for this symbol, by for example
elf_s390_adjust_dynamic_symbol when we're doing a proper dynamic link,
or elf_s390_size_dynamic_sections if no dynamic sections will be
created (we're only linking static objects). */
static void
elf_s390_adjust_gotplt (h)
struct elf_s390_link_hash_entry *h;
{
if (h->elf.root.type == bfd_link_hash_warning)
h = (struct elf_s390_link_hash_entry *) h->elf.root.u.i.link;
if (h->gotplt_refcount <= 0)
return;
/* We simply add the number of gotplt references to the number
* of got references for this symbol. */
h->elf.got.refcount += h->gotplt_refcount;
h->gotplt_refcount = -1;
}
/* Adjust a symbol defined by a dynamic object and referenced by a
regular object. The current definition is in some section of the
dynamic object, but we're not including those sections. We have to
@ -1082,6 +1233,7 @@ elf_s390_adjust_dynamic_symbol (info, h)
linkage table, and we can just do a PC32 reloc instead. */
h->plt.offset = (bfd_vma) -1;
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
}
return TRUE;
@ -1218,6 +1370,9 @@ allocate_dynrelocs (h, inf)
return TRUE;
if (h->root.type == bfd_link_hash_warning)
/* When warning symbols are created, they **replace** the "real"
entry in the hash table, thus we never get to see the real
symbol in a hash traversal. So look at it now. */
h = (struct elf_link_hash_entry *) h->root.u.i.link;
info = (struct bfd_link_info *) inf;
@ -1272,12 +1427,14 @@ allocate_dynrelocs (h, inf)
{
h->plt.offset = (bfd_vma) -1;
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
}
}
else
{
h->plt.offset = (bfd_vma) -1;
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
}
if (h->got.refcount > 0)
@ -1644,7 +1801,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
relend = relocs + input_section->reloc_count;
for (; rel < relend; rel++)
{
int r_type;
unsigned int r_type;
reloc_howto_type *howto;
unsigned long r_symndx;
struct elf_link_hash_entry *h;
@ -1659,7 +1816,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
if (r_type == (int) R_390_GNU_VTINHERIT
|| r_type == (int) R_390_GNU_VTENTRY)
continue;
if (r_type < 0 || r_type >= (int) R_390_max)
if (r_type >= (int) R_390_max)
{
bfd_set_error (bfd_error_bad_value);
return FALSE;
@ -1667,6 +1824,8 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
howto = elf_howto_table + r_type;
r_symndx = ELF32_R_SYM (rel->r_info);
/* This is a final link. */
h = NULL;
sym = NULL;
sec = NULL;
@ -1723,6 +1882,39 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
switch (r_type)
{
case R_390_GOTPLT12:
case R_390_GOTPLT16:
case R_390_GOTPLT32:
case R_390_GOTPLTENT:
/* There are three cases for a GOTPLT relocation. 1) The
relocation is against the jump slot entry of a plt that
will get emitted to the output file. 2) The relocation
is against the jump slot of a plt entry that has been
removed. elf_s390_adjust_gotplt has created a GOT entry
as replacement. 3) The relocation is against a local symbol.
Cases 2) and 3) are the same as the GOT relocation code
so we just have to test for case 1 and fall through for
the other two. */
if (h != NULL && h->plt.offset != (bfd_vma) -1)
{
bfd_vma plt_index;
/* Calc. index no.
Current offset - size first entry / entry size. */
plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) /
PLT_ENTRY_SIZE;
/* Offset in GOT is PLT index plus GOT headers(3) times 4,
addr & GOT addr. */
relocation = (plt_index + 3) * GOT_ENTRY_SIZE;
unresolved_reloc = FALSE;
if (r_type == R_390_GOTPLTENT)
relocation += htab->sgot->output_section->vma;
break;
}
/* Fall through. */
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
@ -1821,12 +2013,14 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
* between the start of the GOT and the symbols entry. We
* add the vma of the GOT to get the correct value.
*/
if (r_type == R_390_GOTENT)
if ( r_type == R_390_GOTENT
|| r_type == R_390_GOTPLTENT)
relocation += htab->sgot->output_section->vma;
break;
case R_390_GOTOFF:
case R_390_GOTOFF16:
case R_390_GOTOFF32:
/* Relocation is relative to the start of the global offset
table. */
@ -1871,6 +2065,28 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
unresolved_reloc = FALSE;
break;
case R_390_PLTOFF16:
case R_390_PLTOFF32:
/* Relocation is to the entry for this symbol in the
procedure linkage table relative to the start of the GOT. */
/* For local symbols or if we didn't make a PLT entry for
this symbol resolve the symbol directly. */
if ( h == NULL
|| h->plt.offset == (bfd_vma) -1
|| htab->splt == NULL)
{
relocation -= htab->sgot->output_section->vma;
break;
}
relocation = (htab->splt->output_section->vma
+ htab->splt->output_offset
+ h->plt.offset
- htab->sgot->output_section->vma);
unresolved_reloc = FALSE;
break;
case R_390_8:
case R_390_16:
case R_390_32:

View File

@ -51,6 +51,9 @@ static asection *elf_s390_gc_mark_hook
static bfd_boolean elf_s390_gc_sweep_hook
PARAMS ((bfd *, struct bfd_link_info *, asection *,
const Elf_Internal_Rela *));
struct elf_s390_link_hash_entry;
static void elf_s390_adjust_gotplt
PARAMS ((struct elf_s390_link_hash_entry *));
static bfd_boolean elf_s390_adjust_dynamic_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
static bfd_boolean allocate_dynrelocs
@ -69,7 +72,8 @@ static enum elf_reloc_type_class elf_s390_reloc_type_class
PARAMS ((const Elf_Internal_Rela *));
static bfd_boolean elf_s390_finish_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
static bfd_boolean elf_s390_object_p PARAMS ((bfd *));
static bfd_boolean elf_s390_object_p
PARAMS ((bfd *));
#include "elf/s390.h"
@ -94,32 +98,78 @@ static reloc_howto_type elf_howto_table[] =
0, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO(R_390_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_8", FALSE, 0,0x000000ff, FALSE),
HOWTO(R_390_12, 0, 1, 12, FALSE, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_390_12", FALSE, 0,0x00000fff, FALSE),
HOWTO(R_390_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_16", FALSE, 0,0x0000ffff, FALSE),
HOWTO(R_390_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_32", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_PC32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC32", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_GOT12, 0, 1, 12, FALSE, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_390_GOT12", FALSE, 0,0x00000fff, FALSE),
HOWTO(R_390_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT32", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT32", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_COPY, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_COPY", FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_GLOB_DAT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GLOB_DAT",FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_JMP_SLOT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_JMP_SLOT",FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_RELATIVE, 0, 4, 64, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_RELATIVE",FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_GOTOFF, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTOFF", FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_GOTPC, 0, 4, 64, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTPC", FALSE, 0,MINUS_ONE, TRUE),
HOWTO(R_390_GOT16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT16", FALSE, 0,0x0000ffff, FALSE),
HOWTO(R_390_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC16", FALSE, 0,0x0000ffff, TRUE),
HOWTO(R_390_PC16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC16DBL", FALSE, 0,0x0000ffff, TRUE),
HOWTO(R_390_PLT16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT16DBL", FALSE, 0,0x0000ffff, TRUE),
HOWTO(R_390_PC32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC32DBL", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_PLT32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT32DBL", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_GOTPCDBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTPCDBL", FALSE, 0,MINUS_ONE, TRUE),
HOWTO(R_390_64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_64", FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_PC64, 0, 4, 64, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC64", FALSE, 0,MINUS_ONE, TRUE),
HOWTO(R_390_GOT64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT64", FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_PLT64, 0, 4, 64, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT64", FALSE, 0,MINUS_ONE, TRUE),
HOWTO(R_390_GOTENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTENT", FALSE, 0,MINUS_ONE, TRUE),
HOWTO(R_390_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_8", FALSE, 0,0x000000ff, FALSE),
HOWTO(R_390_12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_390_12", FALSE, 0,0x00000fff, FALSE),
HOWTO(R_390_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_16", FALSE, 0,0x0000ffff, FALSE),
HOWTO(R_390_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_32", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_PC32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PC32", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_GOT12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_390_GOT12", FALSE, 0,0x00000fff, FALSE),
HOWTO(R_390_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOT32", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLT32", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_COPY, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_COPY", FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_GLOB_DAT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GLOB_DAT", FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_JMP_SLOT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_JMP_SLOT", FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_RELATIVE, 0, 4, 64, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_RELATIVE", FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_GOTOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTOFF32", FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_GOTPC, 0, 4, 64, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTPC", FALSE, 0,MINUS_ONE, TRUE),
HOWTO(R_390_GOT16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOT16", FALSE, 0,0x0000ffff, FALSE),
HOWTO(R_390_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PC16", FALSE, 0,0x0000ffff, TRUE),
HOWTO(R_390_PC16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PC16DBL", FALSE, 0,0x0000ffff, TRUE),
HOWTO(R_390_PLT16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLT16DBL", FALSE, 0,0x0000ffff, TRUE),
HOWTO(R_390_PC32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PC32DBL", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_PLT32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLT32DBL", FALSE, 0,0xffffffff, TRUE),
HOWTO(R_390_GOTPCDBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTPCDBL", FALSE, 0,MINUS_ONE, TRUE),
HOWTO(R_390_64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_64", FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_PC64, 0, 4, 64, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PC64", FALSE, 0,MINUS_ONE, TRUE),
HOWTO(R_390_GOT64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOT64", FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_PLT64, 0, 4, 64, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLT64", FALSE, 0,MINUS_ONE, TRUE),
HOWTO(R_390_GOTENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTENT", FALSE, 0,MINUS_ONE, TRUE),
HOWTO(R_390_GOTOFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTOFF16", FALSE, 0,0x0000ffff, FALSE),
HOWTO(R_390_GOTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTOFF64", FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_GOTPLT12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_390_GOTPLT12", FALSE, 0,0x00000fff, FALSE),
HOWTO(R_390_GOTPLT16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTPLT16", FALSE, 0,0x0000ffff, FALSE),
HOWTO(R_390_GOTPLT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTPLT32", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_GOTPLT64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTPLT64", FALSE, 0,MINUS_ONE, FALSE),
HOWTO(R_390_GOTPLTENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_GOTPLTENT",FALSE, 0,MINUS_ONE, TRUE),
HOWTO(R_390_PLTOFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLTOFF16", FALSE, 0,0x0000ffff, FALSE),
HOWTO(R_390_PLTOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLTOFF32", FALSE, 0,0xffffffff, FALSE),
HOWTO(R_390_PLTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_390_PLTOFF64", FALSE, 0,MINUS_ONE, FALSE),
};
/* GNU extension to record C++ vtable hierarchy. */
@ -164,7 +214,7 @@ elf_s390_reloc_type_lookup (abfd, code)
case BFD_RELOC_390_RELATIVE:
return &elf_howto_table[(int) R_390_RELATIVE];
case BFD_RELOC_32_GOTOFF:
return &elf_howto_table[(int) R_390_GOTOFF];
return &elf_howto_table[(int) R_390_GOTOFF32];
case BFD_RELOC_390_GOTPC:
return &elf_howto_table[(int) R_390_GOTPC];
case BFD_RELOC_390_GOT16:
@ -175,10 +225,6 @@ elf_s390_reloc_type_lookup (abfd, code)
return &elf_howto_table[(int) R_390_PC16DBL];
case BFD_RELOC_390_PLT16DBL:
return &elf_howto_table[(int) R_390_PLT16DBL];
case BFD_RELOC_VTABLE_INHERIT:
return &elf64_s390_vtinherit_howto;
case BFD_RELOC_VTABLE_ENTRY:
return &elf64_s390_vtentry_howto;
case BFD_RELOC_390_PC32DBL:
return &elf_howto_table[(int) R_390_PC32DBL];
case BFD_RELOC_390_PLT32DBL:
@ -195,6 +241,30 @@ elf_s390_reloc_type_lookup (abfd, code)
return &elf_howto_table[(int) R_390_PLT64];
case BFD_RELOC_390_GOTENT:
return &elf_howto_table[(int) R_390_GOTENT];
case BFD_RELOC_16_GOTOFF:
return &elf_howto_table[(int) R_390_GOTOFF16];
case BFD_RELOC_390_GOTOFF64:
return &elf_howto_table[(int) R_390_GOTOFF64];
case BFD_RELOC_390_GOTPLT12:
return &elf_howto_table[(int) R_390_GOTPLT12];
case BFD_RELOC_390_GOTPLT16:
return &elf_howto_table[(int) R_390_GOTPLT16];
case BFD_RELOC_390_GOTPLT32:
return &elf_howto_table[(int) R_390_GOTPLT32];
case BFD_RELOC_390_GOTPLT64:
return &elf_howto_table[(int) R_390_GOTPLT64];
case BFD_RELOC_390_GOTPLTENT:
return &elf_howto_table[(int) R_390_GOTPLTENT];
case BFD_RELOC_390_PLTOFF16:
return &elf_howto_table[(int) R_390_PLTOFF16];
case BFD_RELOC_390_PLTOFF32:
return &elf_howto_table[(int) R_390_PLTOFF32];
case BFD_RELOC_390_PLTOFF64:
return &elf_howto_table[(int) R_390_PLTOFF64];
case BFD_RELOC_VTABLE_INHERIT:
return &elf64_s390_vtinherit_howto;
case BFD_RELOC_VTABLE_ENTRY:
return &elf64_s390_vtentry_howto;
default:
break;
}
@ -357,6 +427,9 @@ struct elf_s390_link_hash_entry
/* Track dynamic relocs copied for this symbol. */
struct elf_s390_dyn_relocs *dyn_relocs;
/* Number of GOTPLT references for a function. */
bfd_signed_vma gotplt_refcount;
};
/* s390 ELF linker hash table. */
@ -409,6 +482,7 @@ link_hash_newfunc (entry, table, string)
eh = (struct elf_s390_link_hash_entry *) entry;
eh->dyn_relocs = NULL;
eh->gotplt_refcount = 0;
}
return entry;
@ -572,6 +646,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
const Elf_Internal_Rela *rel;
const Elf_Internal_Rela *rel_end;
asection *sreloc;
bfd_signed_vma *local_got_refcounts;
if (info->relocateable)
return TRUE;
@ -579,6 +654,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
htab = elf_s390_hash_table (info);
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
local_got_refcounts = elf_local_got_refcounts (abfd);
sreloc = NULL;
@ -603,12 +679,54 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
else
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
/* Create got section and local_got_refcounts array if they
are needed. */
switch (ELF64_R_TYPE (rel->r_info))
{
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
case R_390_GOT64:
case R_390_GOTENT:
case R_390_GOTPLT12:
case R_390_GOTPLT16:
case R_390_GOTPLT32:
case R_390_GOTPLT64:
case R_390_GOTPLTENT:
if (h == NULL
&& local_got_refcounts == NULL)
{
bfd_size_type size;
size = symtab_hdr->sh_info;
size *= sizeof (bfd_signed_vma);
local_got_refcounts = ((bfd_signed_vma *)
bfd_zalloc (abfd, size));
if (local_got_refcounts == NULL)
return FALSE;
elf_local_got_refcounts (abfd) = local_got_refcounts;
}
/* Fall through. */
case R_390_GOTOFF16:
case R_390_GOTOFF32:
case R_390_GOTOFF64:
case R_390_GOTPC:
case R_390_GOTPCDBL:
if (htab->sgot == NULL)
{
if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd;
if (!create_got_section (htab->elf.dynobj, info))
return FALSE;
}
}
switch (ELF64_R_TYPE (rel->r_info))
{
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
case R_390_GOT64:
case R_390_GOTENT:
/* This symbol requires a global offset table entry. */
if (h != NULL)
@ -617,42 +735,25 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
}
else
{
bfd_signed_vma *local_got_refcounts;
/* This is a global offset table entry for a local symbol. */
local_got_refcounts = elf_local_got_refcounts (abfd);
if (local_got_refcounts == NULL)
{
bfd_size_type size;
size = symtab_hdr->sh_info;
size *= sizeof (bfd_signed_vma);
local_got_refcounts = ((bfd_signed_vma *)
bfd_zalloc (abfd, size));
if (local_got_refcounts == NULL)
return FALSE;
elf_local_got_refcounts (abfd) = local_got_refcounts;
}
local_got_refcounts[r_symndx] += 1;
}
/* Fall through */
case R_390_GOTOFF:
case R_390_GOTOFF16:
case R_390_GOTOFF32:
case R_390_GOTOFF64:
case R_390_GOTPC:
case R_390_GOTPCDBL:
if (htab->sgot == NULL)
{
if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd;
if (!create_got_section (htab->elf.dynobj, info))
return FALSE;
}
/* Got is created, nothing to be done. */
break;
case R_390_PLT16DBL:
case R_390_PLT32:
case R_390_PLT32DBL:
case R_390_PLT64:
case R_390_PLTOFF16:
case R_390_PLTOFF32:
case R_390_PLTOFF64:
/* This symbol requires a procedure linkage table entry. We
actually build the entry in adjust_dynamic_symbol,
because this might be a case of linking PIC code which is
@ -662,11 +763,36 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
/* If this is a local symbol, we resolve it directly without
creating a procedure linkage table entry. */
if (h == NULL)
continue;
if (h != NULL)
{
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
h->plt.refcount += 1;
}
break;
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
h->plt.refcount += 1;
case R_390_GOTPLT12:
case R_390_GOTPLT16:
case R_390_GOTPLT32:
case R_390_GOTPLT64:
case R_390_GOTPLTENT:
/* This symbol requires either a procedure linkage table entry
or an entry in the local got. We actually build the entry
in adjust_dynamic_symbol because whether this is really a
global reference can change and with it the fact if we have
to create a plt entry or a local got entry. To be able to
make a once global symbol a local one we have to keep track
of the number of gotplt references that exist for this
symbol. */
if (h != NULL)
{
((struct elf_s390_link_hash_entry *) h)->gotplt_refcount++;
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
h->plt.refcount += 1;
}
else
{
local_got_refcounts[r_symndx] += 1;
}
break;
case R_390_8:
@ -915,89 +1041,141 @@ elf_s390_gc_sweep_hook (abfd, info, sec, relocs)
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; rel++)
switch (ELF64_R_TYPE (rel->r_info))
{
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
case R_390_GOT64:
case R_390_GOTOFF:
case R_390_GOTPC:
case R_390_GOTPCDBL:
case R_390_GOTENT:
r_symndx = ELF64_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
if (h->got.refcount > 0)
h->got.refcount -= 1;
}
else if (local_got_refcounts != NULL)
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
break;
{
r_symndx = ELF64_R_SYM (rel->r_info);
case R_390_8:
case R_390_12:
case R_390_16:
case R_390_32:
case R_390_64:
case R_390_PC16:
case R_390_PC16DBL:
case R_390_PC32:
case R_390_PC32DBL:
case R_390_PC64:
r_symndx = ELF64_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
struct elf_s390_link_hash_entry *eh;
struct elf_s390_dyn_relocs **pp;
struct elf_s390_dyn_relocs *p;
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
switch (ELF64_R_TYPE (rel->r_info))
{
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
case R_390_GOT64:
case R_390_GOTOFF16:
case R_390_GOTOFF32:
case R_390_GOTOFF64:
case R_390_GOTPC:
case R_390_GOTPCDBL:
case R_390_GOTENT:
if (h != NULL)
{
if (h->got.refcount > 0)
h->got.refcount -= 1;
}
else if (local_got_refcounts != NULL)
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
break;
case R_390_PLT16DBL:
case R_390_PLT32:
case R_390_PLT32DBL:
case R_390_PLT64:
case R_390_PLTOFF16:
case R_390_PLTOFF32:
case R_390_PLTOFF64:
if (h != NULL)
{
if (h->plt.refcount > 0)
h->plt.refcount -= 1;
}
break;
if (!info->shared && h->plt.refcount > 0)
h->plt.refcount -= 1;
eh = (struct elf_s390_link_hash_entry *) h;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
case R_390_GOTPLT12:
case R_390_GOTPLT16:
case R_390_GOTPLT32:
case R_390_GOTPLT64:
case R_390_GOTPLTENT:
if (h != NULL)
{
if (h->plt.refcount > 0)
{
if (ELF64_R_TYPE (rel->r_info) == R_390_PC16
|| ELF64_R_TYPE (rel->r_info) == R_390_PC16DBL
|| ELF64_R_TYPE (rel->r_info) == R_390_PC32)
p->pc_count -= 1;
p->count -= 1;
if (p->count == 0)
*pp = p->next;
break;
((struct elf_s390_link_hash_entry *) h)->gotplt_refcount--;
h->plt.refcount -= 1;
}
}
break;
}
else if (local_got_refcounts != NULL)
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
break;
case R_390_PLT16DBL:
case R_390_PLT32:
case R_390_PLT32DBL:
case R_390_PLT64:
r_symndx = ELF64_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
if (h->plt.refcount > 0)
h->plt.refcount -= 1;
}
break;
case R_390_8:
case R_390_12:
case R_390_16:
case R_390_32:
case R_390_64:
case R_390_PC16:
case R_390_PC16DBL:
case R_390_PC32:
case R_390_PC32DBL:
case R_390_PC64:
if (h != NULL)
{
struct elf_s390_link_hash_entry *eh;
struct elf_s390_dyn_relocs **pp;
struct elf_s390_dyn_relocs *p;
if (!info->shared && h->plt.refcount > 0)
h->plt.refcount -= 1;
eh = (struct elf_s390_link_hash_entry *) h;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
{
if (ELF64_R_TYPE (rel->r_info) == R_390_PC16
|| ELF64_R_TYPE (rel->r_info) == R_390_PC16DBL
|| ELF64_R_TYPE (rel->r_info) == R_390_PC32
|| ELF64_R_TYPE (rel->r_info) == R_390_PC32DBL
|| ELF64_R_TYPE (rel->r_info) == R_390_PC64)
p->pc_count -= 1;
p->count -= 1;
if (p->count == 0)
*pp = p->next;
break;
}
}
break;
default:
break;
}
default:
break;
}
}
return TRUE;
}
/* Make sure we emit a GOT entry if the symbol was supposed to have a PLT
entry but we found we will not create any. Called when we find we will
not have any PLT for this symbol, by for example
elf_s390_adjust_dynamic_symbol when we're doing a proper dynamic link,
or elf_s390_size_dynamic_sections if no dynamic sections will be
created (we're only linking static objects). */
static void
elf_s390_adjust_gotplt (h)
struct elf_s390_link_hash_entry *h;
{
if (h->elf.root.type == bfd_link_hash_warning)
h = (struct elf_s390_link_hash_entry *) h->elf.root.u.i.link;
if (h->gotplt_refcount <= 0)
return;
/* We simply add the number of gotplt references to the number
* of got references for this symbol. */
h->elf.got.refcount += h->gotplt_refcount;
h->gotplt_refcount = -1;
}
/* Adjust a symbol defined by a dynamic object and referenced by a
regular object. The current definition is in some section of the
dynamic object, but we're not including those sections. We have to
@ -1035,6 +1213,7 @@ elf_s390_adjust_dynamic_symbol (info, h)
linkage table, and we can just do a PC32 reloc instead. */
h->plt.offset = (bfd_vma) -1;
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
}
return TRUE;
@ -1171,6 +1350,9 @@ allocate_dynrelocs (h, inf)
return TRUE;
if (h->root.type == bfd_link_hash_warning)
/* When warning symbols are created, they **replace** the "real"
entry in the hash table, thus we never get to see the real
symbol in a hash traversal. So look at it now. */
h = (struct elf_link_hash_entry *) h->root.u.i.link;
info = (struct bfd_link_info *) inf;
@ -1225,12 +1407,14 @@ allocate_dynrelocs (h, inf)
{
h->plt.offset = (bfd_vma) -1;
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
}
}
else
{
h->plt.offset = (bfd_vma) -1;
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
}
if (h->got.refcount > 0)
@ -1597,7 +1781,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
relend = relocs + input_section->reloc_count;
for (; rel < relend; rel++)
{
int r_type;
unsigned int r_type;
reloc_howto_type *howto;
unsigned long r_symndx;
struct elf_link_hash_entry *h;
@ -1612,7 +1796,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
if (r_type == (int) R_390_GNU_VTINHERIT
|| r_type == (int) R_390_GNU_VTENTRY)
continue;
if (r_type < 0 || r_type >= (int) R_390_max)
if (r_type >= (int) R_390_max)
{
bfd_set_error (bfd_error_bad_value);
return FALSE;
@ -1620,6 +1804,8 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
howto = elf_howto_table + r_type;
r_symndx = ELF64_R_SYM (rel->r_info);
/* This is a final link. */
h = NULL;
sym = NULL;
sec = NULL;
@ -1676,6 +1862,40 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
switch (r_type)
{
case R_390_GOTPLT12:
case R_390_GOTPLT16:
case R_390_GOTPLT32:
case R_390_GOTPLT64:
case R_390_GOTPLTENT:
/* There are three cases for a GOTPLT relocation. 1) The
relocation is against the jump slot entry of a plt that
will get emitted to the output file. 2) The relocation
is against the jump slot of a plt entry that has been
removed. elf_s390_adjust_gotplt has created a GOT entry
as replacement. 3) The relocation is against a local symbol.
Cases 2) and 3) are the same as the GOT relocation code
so we just have to test for case 1 and fall through for
the other two. */
if (h != NULL && h->plt.offset != (bfd_vma) -1)
{
bfd_vma plt_index;
/* Calc. index no.
Current offset - size first entry / entry size. */
plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) /
PLT_ENTRY_SIZE;
/* Offset in GOT is PLT index plus GOT headers(3) times 4,
addr & GOT addr. */
relocation = (plt_index + 3) * GOT_ENTRY_SIZE;
unresolved_reloc = FALSE;
if (r_type == R_390_GOTPLTENT)
relocation += htab->sgot->output_section->vma;
break;
}
/* Fall through. */
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
@ -1775,12 +1995,15 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
* between the start of the GOT and the symbols entry. We
* add the vma of the GOT to get the correct value.
*/
if (r_type == R_390_GOTENT)
if ( r_type == R_390_GOTENT
|| r_type == R_390_GOTPLTENT)
relocation += htab->sgot->output_section->vma;
break;
case R_390_GOTOFF:
case R_390_GOTOFF16:
case R_390_GOTOFF32:
case R_390_GOTOFF64:
/* Relocation is relative to the start of the global offset
table. */
@ -1790,7 +2013,6 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
permitted by the ABI, we might have to change this
calculation. */
relocation -= htab->sgot->output_section->vma;
break;
case R_390_GOTPC:
@ -1825,6 +2047,29 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
+ htab->splt->output_offset
+ h->plt.offset);
unresolved_reloc = FALSE;
break;
case R_390_PLTOFF16:
case R_390_PLTOFF32:
case R_390_PLTOFF64:
/* Relocation is to the entry for this symbol in the
procedure linkage table relative to the start of the GOT. */
/* For local symbols or if we didn't make a PLT entry for
this symbol resolve the symbol directly. */
if ( h == NULL
|| h->plt.offset == (bfd_vma) -1
|| htab->splt == NULL)
{
relocation -= htab->sgot->output_section->vma;
break;
}
relocation = (htab->splt->output_section->vma
+ htab->splt->output_offset
+ h->plt.offset
- htab->sgot->output_section->vma);
unresolved_reloc = FALSE;
break;
case R_390_8:

View File

@ -1208,6 +1208,15 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_390_GOT64",
"BFD_RELOC_390_PLT64",
"BFD_RELOC_390_GOTENT",
"BFD_RELOC_390_GOTOFF64",
"BFD_RELOC_390_GOTPLT12",
"BFD_RELOC_390_GOTPLT16",
"BFD_RELOC_390_GOTPLT32",
"BFD_RELOC_390_GOTPLT64",
"BFD_RELOC_390_GOTPLTENT",
"BFD_RELOC_390_PLTOFF16",
"BFD_RELOC_390_PLTOFF32",
"BFD_RELOC_390_PLTOFF64",
"BFD_RELOC_IP2K_FR9",
"BFD_RELOC_IP2K_BANK",
"BFD_RELOC_IP2K_ADDR16CJP",

View File

@ -3169,6 +3169,42 @@ ENUM
BFD_RELOC_390_GOTENT
ENUMDOC
32 bit rel. offset to GOT entry.
ENUM
BFD_RELOC_390_GOTOFF64
ENUMDOC
64 bit offset to GOT.
ENUM
BFD_RELOC_390_GOTPLT12
ENUMDOC
12-bit offset to symbol-entry within GOT, with PLT handling.
ENUM
BFD_RELOC_390_GOTPLT16
ENUMDOC
16-bit offset to symbol-entry within GOT, with PLT handling.
ENUM
BFD_RELOC_390_GOTPLT32
ENUMDOC
32-bit offset to symbol-entry within GOT, with PLT handling.
ENUM
BFD_RELOC_390_GOTPLT64
ENUMDOC
64-bit offset to symbol-entry within GOT, with PLT handling.
ENUM
BFD_RELOC_390_GOTPLTENT
ENUMDOC
32-bit rel. offset to symbol-entry within GOT, with PLT handling.
ENUM
BFD_RELOC_390_PLTOFF16
ENUMDOC
16-bit rel. offset from the GOT to a PLT entry.
ENUM
BFD_RELOC_390_PLTOFF32
ENUMDOC
32-bit rel. offset from the GOT to a PLT entry.
ENUM
BFD_RELOC_390_PLTOFF64
ENUMDOC
64-bit rel. offset from the GOT to a PLT entry.
ENUM
BFD_RELOC_IP2K_FR9