blob: ee3c3b2c5f79aec4770ed26795d03b2a3e74a1c4 [file] [log] [blame]
/* PowerPC64-specific support for 64-bit ELF.
Copyright (C) 1999-2016 Free Software Foundation, Inc.
Written by Linus Nordberg, Swox AB <info@swox.com>,
based on elf32-ppc.c by Ian Lance Taylor.
Largely rewritten by Alan Modra.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
/* The 64-bit PowerPC ELF ABI may be found at
http://www.linuxbase.org/spec/ELF/ppc64/PPC-elf64abi.txt, and
http://www.linuxbase.org/spec/ELF/ppc64/spec/book1.html */
#include "sysdep.h"
#include <stdarg.h>
#include "bfd.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/ppc64.h"
#include "elf64-ppc.h"
#include "dwarf2.h"
static bfd_reloc_status_type ppc64_elf_ha_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type ppc64_elf_branch_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type ppc64_elf_brtaken_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type ppc64_elf_sectoff_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type ppc64_elf_sectoff_ha_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type ppc64_elf_toc_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type ppc64_elf_toc_ha_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type ppc64_elf_toc64_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type ppc64_elf_unhandled_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_vma opd_entry_value
(asection *, bfd_vma, asection **, bfd_vma *, bfd_boolean);
#define TARGET_LITTLE_SYM powerpc_elf64_le_vec
#define TARGET_LITTLE_NAME "elf64-powerpcle"
#define TARGET_BIG_SYM powerpc_elf64_vec
#define TARGET_BIG_NAME "elf64-powerpc"
#define ELF_ARCH bfd_arch_powerpc
#define ELF_TARGET_ID PPC64_ELF_DATA
#define ELF_MACHINE_CODE EM_PPC64
#define ELF_MAXPAGESIZE 0x10000
#define ELF_COMMONPAGESIZE 0x10000
#define elf_info_to_howto ppc64_elf_info_to_howto
#define elf_backend_want_got_sym 0
#define elf_backend_want_plt_sym 0
#define elf_backend_plt_alignment 3
#define elf_backend_plt_not_loaded 1
#define elf_backend_got_header_size 8
#define elf_backend_can_gc_sections 1
#define elf_backend_can_refcount 1
#define elf_backend_rela_normal 1
#define elf_backend_default_execstack 0
#define bfd_elf64_mkobject ppc64_elf_mkobject
#define bfd_elf64_bfd_reloc_type_lookup ppc64_elf_reloc_type_lookup
#define bfd_elf64_bfd_reloc_name_lookup ppc64_elf_reloc_name_lookup
#define bfd_elf64_bfd_merge_private_bfd_data ppc64_elf_merge_private_bfd_data
#define bfd_elf64_bfd_print_private_bfd_data ppc64_elf_print_private_bfd_data
#define bfd_elf64_new_section_hook ppc64_elf_new_section_hook
#define bfd_elf64_bfd_link_hash_table_create ppc64_elf_link_hash_table_create
#define bfd_elf64_get_synthetic_symtab ppc64_elf_get_synthetic_symtab
#define bfd_elf64_bfd_link_just_syms ppc64_elf_link_just_syms
#define elf_backend_object_p ppc64_elf_object_p
#define elf_backend_grok_prstatus ppc64_elf_grok_prstatus
#define elf_backend_grok_psinfo ppc64_elf_grok_psinfo
#define elf_backend_write_core_note ppc64_elf_write_core_note
#define elf_backend_create_dynamic_sections ppc64_elf_create_dynamic_sections
#define elf_backend_copy_indirect_symbol ppc64_elf_copy_indirect_symbol
#define elf_backend_add_symbol_hook ppc64_elf_add_symbol_hook
#define elf_backend_check_directives ppc64_elf_before_check_relocs
#define elf_backend_notice_as_needed ppc64_elf_notice_as_needed
#define elf_backend_archive_symbol_lookup ppc64_elf_archive_symbol_lookup
#define elf_backend_check_relocs ppc64_elf_check_relocs
#define elf_backend_gc_keep ppc64_elf_gc_keep
#define elf_backend_gc_mark_dynamic_ref ppc64_elf_gc_mark_dynamic_ref
#define elf_backend_gc_mark_hook ppc64_elf_gc_mark_hook
#define elf_backend_gc_sweep_hook ppc64_elf_gc_sweep_hook
#define elf_backend_adjust_dynamic_symbol ppc64_elf_adjust_dynamic_symbol
#define elf_backend_hide_symbol ppc64_elf_hide_symbol
#define elf_backend_maybe_function_sym ppc64_elf_maybe_function_sym
#define elf_backend_always_size_sections ppc64_elf_func_desc_adjust
#define elf_backend_size_dynamic_sections ppc64_elf_size_dynamic_sections
#define elf_backend_hash_symbol ppc64_elf_hash_symbol
#define elf_backend_init_index_section _bfd_elf_init_2_index_sections
#define elf_backend_action_discarded ppc64_elf_action_discarded
#define elf_backend_relocate_section ppc64_elf_relocate_section
#define elf_backend_finish_dynamic_symbol ppc64_elf_finish_dynamic_symbol
#define elf_backend_reloc_type_class ppc64_elf_reloc_type_class
#define elf_backend_finish_dynamic_sections ppc64_elf_finish_dynamic_sections
#define elf_backend_link_output_symbol_hook ppc64_elf_output_symbol_hook
#define elf_backend_special_sections ppc64_elf_special_sections
#define elf_backend_merge_symbol_attribute ppc64_elf_merge_symbol_attribute
/* The name of the dynamic interpreter. This is put in the .interp
section. */
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
/* The size in bytes of an entry in the procedure linkage table. */
#define PLT_ENTRY_SIZE(htab) (htab->opd_abi ? 24 : 8)
/* The initial size of the plt reserved for the dynamic linker. */
#define PLT_INITIAL_ENTRY_SIZE(htab) (htab->opd_abi ? 24 : 16)
/* Offsets to some stack save slots. */
#define STK_LR 16
#define STK_TOC(htab) (htab->opd_abi ? 40 : 24)
/* This one is dodgy. ELFv2 does not have a linker word, so use the
CR save slot. Used only by optimised __tls_get_addr call stub,
relying on __tls_get_addr_opt not saving CR.. */
#define STK_LINKER(htab) (htab->opd_abi ? 32 : 8)
/* TOC base pointers offset from start of TOC. */
#define TOC_BASE_OFF 0x8000
/* TOC base alignment. */
#define TOC_BASE_ALIGN 256
/* Offset of tp and dtp pointers from start of TLS block. */
#define TP_OFFSET 0x7000
#define DTP_OFFSET 0x8000
/* .plt call stub instructions. The normal stub is like this, but
sometimes the .plt entry crosses a 64k boundary and we need to
insert an addi to adjust r11. */
#define STD_R2_0R1 0xf8410000 /* std %r2,0+40(%r1) */
#define ADDIS_R11_R2 0x3d620000 /* addis %r11,%r2,xxx@ha */
#define LD_R12_0R11 0xe98b0000 /* ld %r12,xxx+0@l(%r11) */
#define MTCTR_R12 0x7d8903a6 /* mtctr %r12 */
#define LD_R2_0R11 0xe84b0000 /* ld %r2,xxx+8@l(%r11) */
#define LD_R11_0R11 0xe96b0000 /* ld %r11,xxx+16@l(%r11) */
#define BCTR 0x4e800420 /* bctr */
#define ADDI_R11_R11 0x396b0000 /* addi %r11,%r11,off@l */
#define ADDIS_R2_R2 0x3c420000 /* addis %r2,%r2,off@ha */
#define ADDI_R2_R2 0x38420000 /* addi %r2,%r2,off@l */
#define XOR_R2_R12_R12 0x7d826278 /* xor %r2,%r12,%r12 */
#define ADD_R11_R11_R2 0x7d6b1214 /* add %r11,%r11,%r2 */
#define XOR_R11_R12_R12 0x7d8b6278 /* xor %r11,%r12,%r12 */
#define ADD_R2_R2_R11 0x7c425a14 /* add %r2,%r2,%r11 */
#define CMPLDI_R2_0 0x28220000 /* cmpldi %r2,0 */
#define BNECTR 0x4ca20420 /* bnectr+ */
#define BNECTR_P4 0x4ce20420 /* bnectr+ */
#define LD_R12_0R2 0xe9820000 /* ld %r12,xxx+0(%r2) */
#define LD_R11_0R2 0xe9620000 /* ld %r11,xxx+0(%r2) */
#define LD_R2_0R2 0xe8420000 /* ld %r2,xxx+0(%r2) */
#define LD_R2_0R1 0xe8410000 /* ld %r2,0(%r1) */
#define LD_R2_0R12 0xe84c0000 /* ld %r2,0(%r12) */
#define ADD_R2_R2_R12 0x7c426214 /* add %r2,%r2,%r12 */
#define LIS_R2 0x3c400000 /* lis %r2,xxx@ha */
#define ADDIS_R2_R12 0x3c4c0000 /* addis %r2,%r12,xxx@ha */
#define ADDIS_R12_R2 0x3d820000 /* addis %r12,%r2,xxx@ha */
#define ADDIS_R12_R12 0x3d8c0000 /* addis %r12,%r12,xxx@ha */
#define LD_R12_0R12 0xe98c0000 /* ld %r12,xxx@l(%r12) */
/* glink call stub instructions. We enter with the index in R0. */
#define GLINK_CALL_STUB_SIZE (16*4)
/* 0: */
/* .quad plt0-1f */
/* __glink: */
#define MFLR_R12 0x7d8802a6 /* mflr %12 */
#define BCL_20_31 0x429f0005 /* bcl 20,31,1f */
/* 1: */
#define MFLR_R11 0x7d6802a6 /* mflr %11 */
/* ld %2,(0b-1b)(%11) */
#define MTLR_R12 0x7d8803a6 /* mtlr %12 */
#define ADD_R11_R2_R11 0x7d625a14 /* add %11,%2,%11 */
/* ld %12,0(%11) */
/* ld %2,8(%11) */
/* mtctr %12 */
/* ld %11,16(%11) */
/* bctr */
#define MFLR_R0 0x7c0802a6 /* mflr %r0 */
#define MTLR_R0 0x7c0803a6 /* mtlr %r0 */
#define SUB_R12_R12_R11 0x7d8b6050 /* subf %r12,%r11,%r12 */
#define ADDI_R0_R12 0x380c0000 /* addi %r0,%r12,0 */
#define SRDI_R0_R0_2 0x7800f082 /* rldicl %r0,%r0,62,2 */
/* Pad with this. */
#define NOP 0x60000000
/* Some other nops. */
#define CROR_151515 0x4def7b82
#define CROR_313131 0x4ffffb82
/* .glink entries for the first 32k functions are two instructions. */
#define LI_R0_0 0x38000000 /* li %r0,0 */
#define B_DOT 0x48000000 /* b . */
/* After that, we need two instructions to load the index, followed by
a branch. */
#define LIS_R0_0 0x3c000000 /* lis %r0,0 */
#define ORI_R0_R0_0 0x60000000 /* ori %r0,%r0,0 */
/* Instructions used by the save and restore reg functions. */
#define STD_R0_0R1 0xf8010000 /* std %r0,0(%r1) */
#define STD_R0_0R12 0xf80c0000 /* std %r0,0(%r12) */
#define LD_R0_0R1 0xe8010000 /* ld %r0,0(%r1) */
#define LD_R0_0R12 0xe80c0000 /* ld %r0,0(%r12) */
#define STFD_FR0_0R1 0xd8010000 /* stfd %fr0,0(%r1) */
#define LFD_FR0_0R1 0xc8010000 /* lfd %fr0,0(%r1) */
#define LI_R12_0 0x39800000 /* li %r12,0 */
#define STVX_VR0_R12_R0 0x7c0c01ce /* stvx %v0,%r12,%r0 */
#define LVX_VR0_R12_R0 0x7c0c00ce /* lvx %v0,%r12,%r0 */
#define MTLR_R0 0x7c0803a6 /* mtlr %r0 */
#define BLR 0x4e800020 /* blr */
/* Since .opd is an array of descriptors and each entry will end up
with identical R_PPC64_RELATIVE relocs, there is really no need to
propagate .opd relocs; The dynamic linker should be taught to
relocate .opd without reloc entries. */
#ifndef NO_OPD_RELOCS
#define NO_OPD_RELOCS 0
#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
#endif
static inline int
abiversion (bfd *abfd)
{
return elf_elfheader (abfd)->e_flags & EF_PPC64_ABI;
}
static inline void
set_abiversion (bfd *abfd, int ver)
{
elf_elfheader (abfd)->e_flags &= ~EF_PPC64_ABI;
elf_elfheader (abfd)->e_flags |= ver & EF_PPC64_ABI;
}
#define ONES(n) (((bfd_vma) 1 << ((n) - 1) << 1) - 1)
/* Relocation HOWTO's. */
static reloc_howto_type *ppc64_elf_howto_table[(int) R_PPC64_max];
static reloc_howto_type ppc64_elf_howto_raw[] = {
/* This reloc does nothing. */
HOWTO (R_PPC64_NONE, /* type */
0, /* rightshift */
3, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_NONE", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
/* A standard 32 bit relocation. */
HOWTO (R_PPC64_ADDR32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_ADDR32", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* An absolute 26 bit branch; the lower two bits must be zero.
FIXME: we don't check that, we just clear them. */
HOWTO (R_PPC64_ADDR24, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
26, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_ADDR24", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0x03fffffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* A standard 16 bit relocation. */
HOWTO (R_PPC64_ADDR16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_ADDR16", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A 16 bit relocation without overflow. */
HOWTO (R_PPC64_ADDR16_LO, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_ADDR16_LO", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Bits 16-31 of an address. */
HOWTO (R_PPC64_ADDR16_HI, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_ADDR16_HI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Bits 16-31 of an address, plus 1 if the contents of the low 16
bits, treated as a signed number, is negative. */
HOWTO (R_PPC64_ADDR16_HA, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_ha_reloc, /* special_function */
"R_PPC64_ADDR16_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* An absolute 16 bit branch; the lower two bits must be zero.
FIXME: we don't check that, we just clear them. */
HOWTO (R_PPC64_ADDR14, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_branch_reloc, /* special_function */
"R_PPC64_ADDR14", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0x0000fffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* An absolute 16 bit branch, for which bit 10 should be set to
indicate that the branch is expected to be taken. The lower two
bits must be zero. */
HOWTO (R_PPC64_ADDR14_BRTAKEN, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_brtaken_reloc, /* special_function */
"R_PPC64_ADDR14_BRTAKEN",/* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0x0000fffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* An absolute 16 bit branch, for which bit 10 should be set to
indicate that the branch is not expected to be taken. The lower
two bits must be zero. */
HOWTO (R_PPC64_ADDR14_BRNTAKEN, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_brtaken_reloc, /* special_function */
"R_PPC64_ADDR14_BRNTAKEN",/* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0x0000fffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* A relative 26 bit branch; the lower two bits must be zero. */
HOWTO (R_PPC64_REL24, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
26, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_branch_reloc, /* special_function */
"R_PPC64_REL24", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0x03fffffc, /* dst_mask */
TRUE), /* pcrel_offset */
/* A relative 16 bit branch; the lower two bits must be zero. */
HOWTO (R_PPC64_REL14, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_branch_reloc, /* special_function */
"R_PPC64_REL14", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0x0000fffc, /* dst_mask */
TRUE), /* pcrel_offset */
/* A relative 16 bit branch. Bit 10 should be set to indicate that
the branch is expected to be taken. The lower two bits must be
zero. */
HOWTO (R_PPC64_REL14_BRTAKEN, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_brtaken_reloc, /* special_function */
"R_PPC64_REL14_BRTAKEN", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0x0000fffc, /* dst_mask */
TRUE), /* pcrel_offset */
/* A relative 16 bit branch. Bit 10 should be set to indicate that
the branch is not expected to be taken. The lower two bits must
be zero. */
HOWTO (R_PPC64_REL14_BRNTAKEN, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_brtaken_reloc, /* special_function */
"R_PPC64_REL14_BRNTAKEN",/* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0x0000fffc, /* dst_mask */
TRUE), /* pcrel_offset */
/* Like R_PPC64_ADDR16, but referring to the GOT table entry for the
symbol. */
HOWTO (R_PPC64_GOT16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT16", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_ADDR16_LO, but referring to the GOT table entry for
the symbol. */
HOWTO (R_PPC64_GOT16_LO, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT16_LO", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_ADDR16_HI, but referring to the GOT table entry for
the symbol. */
HOWTO (R_PPC64_GOT16_HI, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed,/* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT16_HI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_ADDR16_HA, but referring to the GOT table entry for
the symbol. */
HOWTO (R_PPC64_GOT16_HA, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed,/* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT16_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* This is used only by the dynamic linker. The symbol should exist
both in the object being run and in some shared library. The
dynamic linker copies the data addressed by the symbol from the
shared library into the object, because the object being
run has to have the data at some particular address. */
HOWTO (R_PPC64_COPY, /* type */
0, /* rightshift */
0, /* this one is variable size */
0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_COPY", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_ADDR64, but used when setting global offset table
entries. */
HOWTO (R_PPC64_GLOB_DAT, /* type */
0, /* rightshift */
4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
64, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GLOB_DAT", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
ONES (64), /* dst_mask */
FALSE), /* pcrel_offset */
/* Created by the link editor. Marks a procedure linkage table
entry for a symbol. */
HOWTO (R_PPC64_JMP_SLOT, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_JMP_SLOT", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
/* Used only by the dynamic linker. When the object is run, this
doubleword64 is set to the load address of the object, plus the
addend. */
HOWTO (R_PPC64_RELATIVE, /* type */
0, /* rightshift */
4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
64, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_RELATIVE", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
ONES (64), /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_ADDR32, but may be unaligned. */
HOWTO (R_PPC64_UADDR32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_UADDR32", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_ADDR16, but may be unaligned. */
HOWTO (R_PPC64_UADDR16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_UADDR16", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* 32-bit PC relative. */
HOWTO (R_PPC64_REL32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_REL32", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
TRUE), /* pcrel_offset */
/* 32-bit relocation to the symbol's procedure linkage table. */
HOWTO (R_PPC64_PLT32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_PLT32", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* 32-bit PC relative relocation to the symbol's procedure linkage table.
FIXME: R_PPC64_PLTREL32 not supported. */
HOWTO (R_PPC64_PLTREL32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_PLTREL32", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
TRUE), /* pcrel_offset */
/* Like R_PPC64_ADDR16_LO, but referring to the PLT table entry for
the symbol. */
HOWTO (R_PPC64_PLT16_LO, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_PLT16_LO", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_ADDR16_HI, but referring to the PLT table entry for
the symbol. */
HOWTO (R_PPC64_PLT16_HI, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_PLT16_HI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_ADDR16_HA, but referring to the PLT table entry for
the symbol. */
HOWTO (R_PPC64_PLT16_HA, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_PLT16_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* 16-bit section relative relocation. */
HOWTO (R_PPC64_SECTOFF, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_sectoff_reloc, /* special_function */
"R_PPC64_SECTOFF", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_SECTOFF, but no overflow warning. */
HOWTO (R_PPC64_SECTOFF_LO, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_sectoff_reloc, /* special_function */
"R_PPC64_SECTOFF_LO", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* 16-bit upper half section relative relocation. */
HOWTO (R_PPC64_SECTOFF_HI, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_sectoff_reloc, /* special_function */
"R_PPC64_SECTOFF_HI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* 16-bit upper half adjusted section relative relocation. */
HOWTO (R_PPC64_SECTOFF_HA, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_sectoff_ha_reloc, /* special_function */
"R_PPC64_SECTOFF_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_REL24 without touching the two least significant bits. */
HOWTO (R_PPC64_REL30, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
30, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_REL30", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffffffc, /* dst_mask */
TRUE), /* pcrel_offset */
/* Relocs in the 64-bit PowerPC ELF ABI, not in the 32-bit ABI. */
/* A standard 64-bit relocation. */
HOWTO (R_PPC64_ADDR64, /* type */
0, /* rightshift */
4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
64, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_ADDR64", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
ONES (64), /* dst_mask */
FALSE), /* pcrel_offset */
/* The bits 32-47 of an address. */
HOWTO (R_PPC64_ADDR16_HIGHER, /* type */
32, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_ADDR16_HIGHER", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* The bits 32-47 of an address, plus 1 if the contents of the low
16 bits, treated as a signed number, is negative. */
HOWTO (R_PPC64_ADDR16_HIGHERA, /* type */
32, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_ha_reloc, /* special_function */
"R_PPC64_ADDR16_HIGHERA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* The bits 48-63 of an address. */
HOWTO (R_PPC64_ADDR16_HIGHEST,/* type */
48, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_ADDR16_HIGHEST", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* The bits 48-63 of an address, plus 1 if the contents of the low
16 bits, treated as a signed number, is negative. */
HOWTO (R_PPC64_ADDR16_HIGHESTA,/* type */
48, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_ha_reloc, /* special_function */
"R_PPC64_ADDR16_HIGHESTA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like ADDR64, but may be unaligned. */
HOWTO (R_PPC64_UADDR64, /* type */
0, /* rightshift */
4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
64, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_UADDR64", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
ONES (64), /* dst_mask */
FALSE), /* pcrel_offset */
/* 64-bit relative relocation. */
HOWTO (R_PPC64_REL64, /* type */
0, /* rightshift */
4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
64, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_REL64", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
ONES (64), /* dst_mask */
TRUE), /* pcrel_offset */
/* 64-bit relocation to the symbol's procedure linkage table. */
HOWTO (R_PPC64_PLT64, /* type */
0, /* rightshift */
4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
64, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_PLT64", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
ONES (64), /* dst_mask */
FALSE), /* pcrel_offset */
/* 64-bit PC relative relocation to the symbol's procedure linkage
table. */
/* FIXME: R_PPC64_PLTREL64 not supported. */
HOWTO (R_PPC64_PLTREL64, /* type */
0, /* rightshift */
4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
64, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_PLTREL64", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
ONES (64), /* dst_mask */
TRUE), /* pcrel_offset */
/* 16 bit TOC-relative relocation. */
/* R_PPC64_TOC16 47 half16* S + A - .TOC. */
HOWTO (R_PPC64_TOC16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_toc_reloc, /* special_function */
"R_PPC64_TOC16", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* 16 bit TOC-relative relocation without overflow. */
/* R_PPC64_TOC16_LO 48 half16 #lo (S + A - .TOC.) */
HOWTO (R_PPC64_TOC16_LO, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_toc_reloc, /* special_function */
"R_PPC64_TOC16_LO", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* 16 bit TOC-relative relocation, high 16 bits. */
/* R_PPC64_TOC16_HI 49 half16 #hi (S + A - .TOC.) */
HOWTO (R_PPC64_TOC16_HI, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_toc_reloc, /* special_function */
"R_PPC64_TOC16_HI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* 16 bit TOC-relative relocation, high 16 bits, plus 1 if the
contents of the low 16 bits, treated as a signed number, is
negative. */
/* R_PPC64_TOC16_HA 50 half16 #ha (S + A - .TOC.) */
HOWTO (R_PPC64_TOC16_HA, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_toc_ha_reloc, /* special_function */
"R_PPC64_TOC16_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* 64-bit relocation; insert value of TOC base (.TOC.). */
/* R_PPC64_TOC 51 doubleword64 .TOC. */
HOWTO (R_PPC64_TOC, /* type */
0, /* rightshift */
4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
64, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_toc64_reloc, /* special_function */
"R_PPC64_TOC", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
ONES (64), /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_GOT16, but also informs the link editor that the
value to relocate may (!) refer to a PLT entry which the link
editor (a) may replace with the symbol value. If the link editor
is unable to fully resolve the symbol, it may (b) create a PLT
entry and store the address to the new PLT entry in the GOT.
This permits lazy resolution of function symbols at run time.
The link editor may also skip all of this and just (c) emit a
R_PPC64_GLOB_DAT to tie the symbol to the GOT entry. */
/* FIXME: R_PPC64_PLTGOT16 not implemented. */
HOWTO (R_PPC64_PLTGOT16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_PLTGOT16", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_PLTGOT16, but without overflow. */
/* FIXME: R_PPC64_PLTGOT16_LO not implemented. */
HOWTO (R_PPC64_PLTGOT16_LO, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_PLTGOT16_LO", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_PLT_GOT16, but using bits 16-31 of the address. */
/* FIXME: R_PPC64_PLTGOT16_HI not implemented. */
HOWTO (R_PPC64_PLTGOT16_HI, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_PLTGOT16_HI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_PLT_GOT16, but using bits 16-31 of the address, plus
1 if the contents of the low 16 bits, treated as a signed number,
is negative. */
/* FIXME: R_PPC64_PLTGOT16_HA not implemented. */
HOWTO (R_PPC64_PLTGOT16_HA, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_PLTGOT16_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_ADDR16, but for instructions with a DS field. */
HOWTO (R_PPC64_ADDR16_DS, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_ADDR16_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_ADDR16_LO, but for instructions with a DS field. */
HOWTO (R_PPC64_ADDR16_LO_DS, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_ADDR16_LO_DS",/* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_GOT16, but for instructions with a DS field. */
HOWTO (R_PPC64_GOT16_DS, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT16_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_GOT16_LO, but for instructions with a DS field. */
HOWTO (R_PPC64_GOT16_LO_DS, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT16_LO_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_PLT16_LO, but for instructions with a DS field. */
HOWTO (R_PPC64_PLT16_LO_DS, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_PLT16_LO_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_SECTOFF, but for instructions with a DS field. */
HOWTO (R_PPC64_SECTOFF_DS, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_sectoff_reloc, /* special_function */
"R_PPC64_SECTOFF_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_SECTOFF_LO, but for instructions with a DS field. */
HOWTO (R_PPC64_SECTOFF_LO_DS, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_sectoff_reloc, /* special_function */
"R_PPC64_SECTOFF_LO_DS",/* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_TOC16, but for instructions with a DS field. */
HOWTO (R_PPC64_TOC16_DS, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_toc_reloc, /* special_function */
"R_PPC64_TOC16_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_TOC16_LO, but for instructions with a DS field. */
HOWTO (R_PPC64_TOC16_LO_DS, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_toc_reloc, /* special_function */
"R_PPC64_TOC16_LO_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_PLTGOT16, but for instructions with a DS field. */
/* FIXME: R_PPC64_PLTGOT16_DS not implemented. */
HOWTO (R_PPC64_PLTGOT16_DS, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_PLTGOT16_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_PLTGOT16_LO, but for instructions with a DS field. */
/* FIXME: R_PPC64_PLTGOT16_LO not implemented. */
HOWTO (R_PPC64_PLTGOT16_LO_DS,/* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_PLTGOT16_LO_DS",/* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Marker relocs for TLS. */
HOWTO (R_PPC64_TLS,
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_TLS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_PPC64_TLSGD,
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_TLSGD", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_PPC64_TLSLD,
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_TLSLD", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_PPC64_TOCSAVE,
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_TOCSAVE", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
/* Computes the load module index of the load module that contains the
definition of its TLS sym. */
HOWTO (R_PPC64_DTPMOD64,
0, /* rightshift */
4, /* size (0 = byte, 1 = short, 2 = long) */
64, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPMOD64", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
ONES (64), /* dst_mask */
FALSE), /* pcrel_offset */
/* Computes a dtv-relative displacement, the difference between the value
of sym+add and the base address of the thread-local storage block that
contains the definition of sym, minus 0x8000. */
HOWTO (R_PPC64_DTPREL64,
0, /* rightshift */
4, /* size (0 = byte, 1 = short, 2 = long) */
64, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPREL64", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
ONES (64), /* dst_mask */
FALSE), /* pcrel_offset */
/* A 16 bit dtprel reloc. */
HOWTO (R_PPC64_DTPREL16,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPREL16", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like DTPREL16, but no overflow. */
HOWTO (R_PPC64_DTPREL16_LO,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPREL16_LO", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like DTPREL16_LO, but next higher group of 16 bits. */
HOWTO (R_PPC64_DTPREL16_HI,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPREL16_HI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like DTPREL16_HI, but adjust for low 16 bits. */
HOWTO (R_PPC64_DTPREL16_HA,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPREL16_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like DTPREL16_HI, but next higher group of 16 bits. */
HOWTO (R_PPC64_DTPREL16_HIGHER,
32, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPREL16_HIGHER", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like DTPREL16_HIGHER, but adjust for low 16 bits. */
HOWTO (R_PPC64_DTPREL16_HIGHERA,
32, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPREL16_HIGHERA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like DTPREL16_HIGHER, but next higher group of 16 bits. */
HOWTO (R_PPC64_DTPREL16_HIGHEST,
48, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPREL16_HIGHEST", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like DTPREL16_HIGHEST, but adjust for low 16 bits. */
HOWTO (R_PPC64_DTPREL16_HIGHESTA,
48, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPREL16_HIGHESTA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like DTPREL16, but for insns with a DS field. */
HOWTO (R_PPC64_DTPREL16_DS,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPREL16_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like DTPREL16_DS, but no overflow. */
HOWTO (R_PPC64_DTPREL16_LO_DS,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPREL16_LO_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Computes a tp-relative displacement, the difference between the value of
sym+add and the value of the thread pointer (r13). */
HOWTO (R_PPC64_TPREL64,
0, /* rightshift */
4, /* size (0 = byte, 1 = short, 2 = long) */
64, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_TPREL64", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
ONES (64), /* dst_mask */
FALSE), /* pcrel_offset */
/* A 16 bit tprel reloc. */
HOWTO (R_PPC64_TPREL16,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_TPREL16", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like TPREL16, but no overflow. */
HOWTO (R_PPC64_TPREL16_LO,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_TPREL16_LO", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like TPREL16_LO, but next higher group of 16 bits. */
HOWTO (R_PPC64_TPREL16_HI,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_TPREL16_HI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like TPREL16_HI, but adjust for low 16 bits. */
HOWTO (R_PPC64_TPREL16_HA,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_TPREL16_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like TPREL16_HI, but next higher group of 16 bits. */
HOWTO (R_PPC64_TPREL16_HIGHER,
32, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_TPREL16_HIGHER", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like TPREL16_HIGHER, but adjust for low 16 bits. */
HOWTO (R_PPC64_TPREL16_HIGHERA,
32, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_TPREL16_HIGHERA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like TPREL16_HIGHER, but next higher group of 16 bits. */
HOWTO (R_PPC64_TPREL16_HIGHEST,
48, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_TPREL16_HIGHEST", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like TPREL16_HIGHEST, but adjust for low 16 bits. */
HOWTO (R_PPC64_TPREL16_HIGHESTA,
48, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_TPREL16_HIGHESTA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like TPREL16, but for insns with a DS field. */
HOWTO (R_PPC64_TPREL16_DS,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_TPREL16_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like TPREL16_DS, but no overflow. */
HOWTO (R_PPC64_TPREL16_LO_DS,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_TPREL16_LO_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Allocates two contiguous entries in the GOT to hold a tls_index structure,
with values (sym+add)@dtpmod and (sym+add)@dtprel, and computes the offset
to the first entry relative to the TOC base (r2). */
HOWTO (R_PPC64_GOT_TLSGD16,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_TLSGD16", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like GOT_TLSGD16, but no overflow. */
HOWTO (R_PPC64_GOT_TLSGD16_LO,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_TLSGD16_LO", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like GOT_TLSGD16_LO, but next higher group of 16 bits. */
HOWTO (R_PPC64_GOT_TLSGD16_HI,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_TLSGD16_HI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like GOT_TLSGD16_HI, but adjust for low 16 bits. */
HOWTO (R_PPC64_GOT_TLSGD16_HA,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_TLSGD16_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Allocates two contiguous entries in the GOT to hold a tls_index structure,
with values (sym+add)@dtpmod and zero, and computes the offset to the
first entry relative to the TOC base (r2). */
HOWTO (R_PPC64_GOT_TLSLD16,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_TLSLD16", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like GOT_TLSLD16, but no overflow. */
HOWTO (R_PPC64_GOT_TLSLD16_LO,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_TLSLD16_LO", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like GOT_TLSLD16_LO, but next higher group of 16 bits. */
HOWTO (R_PPC64_GOT_TLSLD16_HI,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_TLSLD16_HI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like GOT_TLSLD16_HI, but adjust for low 16 bits. */
HOWTO (R_PPC64_GOT_TLSLD16_HA,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_TLSLD16_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Allocates an entry in the GOT with value (sym+add)@dtprel, and computes
the offset to the entry relative to the TOC base (r2). */
HOWTO (R_PPC64_GOT_DTPREL16_DS,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_DTPREL16_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like GOT_DTPREL16_DS, but no overflow. */
HOWTO (R_PPC64_GOT_DTPREL16_LO_DS,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_DTPREL16_LO_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like GOT_DTPREL16_LO_DS, but next higher group of 16 bits. */
HOWTO (R_PPC64_GOT_DTPREL16_HI,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_DTPREL16_HI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like GOT_DTPREL16_HI, but adjust for low 16 bits. */
HOWTO (R_PPC64_GOT_DTPREL16_HA,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_DTPREL16_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Allocates an entry in the GOT with value (sym+add)@tprel, and computes the
offset to the entry relative to the TOC base (r2). */
HOWTO (R_PPC64_GOT_TPREL16_DS,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_TPREL16_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like GOT_TPREL16_DS, but no overflow. */
HOWTO (R_PPC64_GOT_TPREL16_LO_DS,
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_TPREL16_LO_DS", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xfffc, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like GOT_TPREL16_LO_DS, but next higher group of 16 bits. */
HOWTO (R_PPC64_GOT_TPREL16_HI,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_TPREL16_HI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like GOT_TPREL16_HI, but adjust for low 16 bits. */
HOWTO (R_PPC64_GOT_TPREL16_HA,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_GOT_TPREL16_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_PPC64_JMP_IREL, /* type */
0, /* rightshift */
0, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_JMP_IREL", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_PPC64_IRELATIVE, /* type */
0, /* rightshift */
4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
64, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_IRELATIVE", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
ONES (64), /* dst_mask */
FALSE), /* pcrel_offset */
/* A 16 bit relative relocation. */
HOWTO (R_PPC64_REL16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_REL16", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
TRUE), /* pcrel_offset */
/* A 16 bit relative relocation without overflow. */
HOWTO (R_PPC64_REL16_LO, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_REL16_LO", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
TRUE), /* pcrel_offset */
/* The high order 16 bits of a relative address. */
HOWTO (R_PPC64_REL16_HI, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_REL16_HI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
TRUE), /* pcrel_offset */
/* The high order 16 bits of a relative address, plus 1 if the contents of
the low 16 bits, treated as a signed number, is negative. */
HOWTO (R_PPC64_REL16_HA, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_ha_reloc, /* special_function */
"R_PPC64_REL16_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
TRUE), /* pcrel_offset */
/* Like R_PPC64_REL16_HA but for split field in addpcis. */
HOWTO (R_PPC64_REL16DX_HA, /* type */
16, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
ppc64_elf_ha_reloc, /* special_function */
"R_PPC64_REL16DX_HA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0x1fffc1, /* dst_mask */
TRUE), /* pcrel_offset */
/* Like R_PPC64_ADDR16_HI, but no overflow. */
HOWTO (R_PPC64_ADDR16_HIGH, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_ADDR16_HIGH", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_ADDR16_HA, but no overflow. */
HOWTO (R_PPC64_ADDR16_HIGHA, /* type */
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_ha_reloc, /* special_function */
"R_PPC64_ADDR16_HIGHA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_DTPREL16_HI, but no overflow. */
HOWTO (R_PPC64_DTPREL16_HIGH,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPREL16_HIGH", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_DTPREL16_HA, but no overflow. */
HOWTO (R_PPC64_DTPREL16_HIGHA,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_DTPREL16_HIGHA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_TPREL16_HI, but no overflow. */
HOWTO (R_PPC64_TPREL16_HIGH,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_TPREL16_HIGH", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like R_PPC64_TPREL16_HA, but no overflow. */
HOWTO (R_PPC64_TPREL16_HIGHA,
16, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
ppc64_elf_unhandled_reloc, /* special_function */
"R_PPC64_TPREL16_HIGHA", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* Marker reloc on ELFv2 large-model function entry. */
HOWTO (R_PPC64_ENTRY,
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_ENTRY", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
/* Like ADDR64, but use local entry point of function. */
HOWTO (R_PPC64_ADDR64_LOCAL, /* type */
0, /* rightshift */
4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
64, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC64_ADDR64_LOCAL", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
ONES (64), /* dst_mask */
FALSE), /* pcrel_offset */
/* GNU extension to record C++ vtable hierarchy. */
HOWTO (R_PPC64_GNU_VTINHERIT, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
NULL, /* special_function */
"R_PPC64_GNU_VTINHERIT", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
/* GNU extension to record C++ vtable member usage. */
HOWTO (R_PPC64_GNU_VTENTRY, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
NULL, /* special_function */
"R_PPC64_GNU_VTENTRY", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
FALSE), /* pcrel_offset */
};
/* Initialize the ppc64_elf_howto_table, so that linear accesses can
be done. */
static void
ppc_howto_init (void)
{
unsigned int i, type;
for (i = 0; i < ARRAY_SIZE (ppc64_elf_howto_raw); i++)
{
type = ppc64_elf_howto_raw[i].type;
BFD_ASSERT (type < ARRAY_SIZE (ppc64_elf_howto_table));
ppc64_elf_howto_table[type] = &ppc64_elf_howto_raw[i];
}
}
static reloc_howto_type *
ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
bfd_reloc_code_real_type code)
{
enum elf_ppc64_reloc_type r = R_PPC64_NONE;
if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
/* Initialize howto table if needed. */
ppc_howto_init ();
switch (code)
{
default:
return NULL;
case BFD_RELOC_NONE: r = R_PPC64_NONE;
break;
case BFD_RELOC_32: r = R_PPC64_ADDR32;
break;
case BFD_RELOC_PPC_BA26: r = R_PPC64_ADDR24;
break;
case BFD_RELOC_16: r = R_PPC64_ADDR16;
break;
case BFD_RELOC_LO16: r = R_PPC64_ADDR16_LO;
break;
case BFD_RELOC_HI16: r = R_PPC64_ADDR16_HI;
break;
case BFD_RELOC_PPC64_ADDR16_HIGH: r = R_PPC64_ADDR16_HIGH;
break;
case BFD_RELOC_HI16_S: r = R_PPC64_ADDR16_HA;
break;
case BFD_RELOC_PPC64_ADDR16_HIGHA: r = R_PPC64_ADDR16_HIGHA;
break;
case BFD_RELOC_PPC_BA16: r = R_PPC64_ADDR14;
break;
case BFD_RELOC_PPC_BA16_BRTAKEN: r = R_PPC64_ADDR14_BRTAKEN;
break;
case BFD_RELOC_PPC_BA16_BRNTAKEN: r = R_PPC64_ADDR14_BRNTAKEN;
break;
case BFD_RELOC_PPC_B26: r = R_PPC64_REL24;
break;
case BFD_RELOC_PPC_B16: r = R_PPC64_REL14;
break;
case BFD_RELOC_PPC_B16_BRTAKEN: r = R_PPC64_REL14_BRTAKEN;
break;
case BFD_RELOC_PPC_B16_BRNTAKEN: r = R_PPC64_REL14_BRNTAKEN;
break;
case BFD_RELOC_16_GOTOFF: r = R_PPC64_GOT16;
break;
case BFD_RELOC_LO16_GOTOFF: r = R_PPC64_GOT16_LO;
break;
case BFD_RELOC_HI16_GOTOFF: r = R_PPC64_GOT16_HI;
break;
case BFD_RELOC_HI16_S_GOTOFF: r = R_PPC64_GOT16_HA;
break;
case BFD_RELOC_PPC_COPY: r = R_PPC64_COPY;
break;
case BFD_RELOC_PPC_GLOB_DAT: r = R_PPC64_GLOB_DAT;
break;
case BFD_RELOC_32_PCREL: r = R_PPC64_REL32;
break;
case BFD_RELOC_32_PLTOFF: r = R_PPC64_PLT32;
break;
case BFD_RELOC_32_PLT_PCREL: r = R_PPC64_PLTREL32;
break;
case BFD_RELOC_LO16_PLTOFF: r = R_PPC64_PLT16_LO;
break;
case BFD_RELOC_HI16_PLTOFF: r = R_PPC64_PLT16_HI;
break;
case BFD_RELOC_HI16_S_PLTOFF: r = R_PPC64_PLT16_HA;
break;
case BFD_RELOC_16_BASEREL: r = R_PPC64_SECTOFF;
break;
case BFD_RELOC_LO16_BASEREL: r = R_PPC64_SECTOFF_LO;
break;
case BFD_RELOC_HI16_BASEREL: r = R_PPC64_SECTOFF_HI;
break;
case BFD_RELOC_HI16_S_BASEREL: r = R_PPC64_SECTOFF_HA;
break;
case BFD_RELOC_CTOR: r = R_PPC64_ADDR64;
break;
case BFD_RELOC_64: r = R_PPC64_ADDR64;
break;
case BFD_RELOC_PPC64_HIGHER: r = R_PPC64_ADDR16_HIGHER;
break;
case BFD_RELOC_PPC64_HIGHER_S: r = R_PPC64_ADDR16_HIGHERA;
break;
case BFD_RELOC_PPC64_HIGHEST: r = R_PPC64_ADDR16_HIGHEST;
break;
case BFD_RELOC_PPC64_HIGHEST_S: r = R_PPC64_ADDR16_HIGHESTA;
break;
case BFD_RELOC_64_PCREL: r = R_PPC64_REL64;
break;
case BFD_RELOC_64_PLTOFF: r = R_PPC64_PLT64;
break;
case BFD_RELOC_64_PLT_PCREL: r = R_PPC64_PLTREL64;
break;
case BFD_RELOC_PPC_TOC16: r = R_PPC64_TOC16;
break;
case BFD_RELOC_PPC64_TOC16_LO: r = R_PPC64_TOC16_LO;
break;
case BFD_RELOC_PPC64_TOC16_HI: r = R_PPC64_TOC16_HI;
break;
case BFD_RELOC_PPC64_TOC16_HA: r = R_PPC64_TOC16_HA;
break;
case BFD_RELOC_PPC64_TOC: r = R_PPC64_TOC;
break;
case BFD_RELOC_PPC64_PLTGOT16: r = R_PPC64_PLTGOT16;
break;
case BFD_RELOC_PPC64_PLTGOT16_LO: r = R_PPC64_PLTGOT16_LO;
break;
case BFD_RELOC_PPC64_PLTGOT16_HI: r = R_PPC64_PLTGOT16_HI;
break;
case BFD_RELOC_PPC64_PLTGOT16_HA: r = R_PPC64_PLTGOT16_HA;
break;
case BFD_RELOC_PPC64_ADDR16_DS: r = R_PPC64_ADDR16_DS;
break;
case BFD_RELOC_PPC64_ADDR16_LO_DS: r = R_PPC64_ADDR16_LO_DS;
break;
case BFD_RELOC_PPC64_GOT16_DS: r = R_PPC64_GOT16_DS;
break;
case BFD_RELOC_PPC64_GOT16_LO_DS: r = R_PPC64_GOT16_LO_DS;
break;
case BFD_RELOC_PPC64_PLT16_LO_DS: r = R_PPC64_PLT16_LO_DS;
break;
case BFD_RELOC_PPC64_SECTOFF_DS: r = R_PPC64_SECTOFF_DS;
break;
case BFD_RELOC_PPC64_SECTOFF_LO_DS: r = R_PPC64_SECTOFF_LO_DS;
break;
case BFD_RELOC_PPC64_TOC16_DS: r = R_PPC64_TOC16_DS;
break;
case BFD_RELOC_PPC64_TOC16_LO_DS: r = R_PPC64_TOC16_LO_DS;
break;
case BFD_RELOC_PPC64_PLTGOT16_DS: r = R_PPC64_PLTGOT16_DS;
break;
case BFD_RELOC_PPC64_PLTGOT16_LO_DS: r = R_PPC64_PLTGOT16_LO_DS;
break;
case BFD_RELOC_PPC_TLS: r = R_PPC64_TLS;
break;
case BFD_RELOC_PPC_TLSGD: r = R_PPC64_TLSGD;
break;
case BFD_RELOC_PPC_TLSLD: r = R_PPC64_TLSLD;
break;
case BFD_RELOC_PPC_DTPMOD: r = R_PPC64_DTPMOD64;
break;
case BFD_RELOC_PPC_TPREL16: r = R_PPC64_TPREL16;
break;
case BFD_RELOC_PPC_TPREL16_LO: r = R_PPC64_TPREL16_LO;
break;
case BFD_RELOC_PPC_TPREL16_HI: r = R_PPC64_TPREL16_HI;
break;
case BFD_RELOC_PPC64_TPREL16_HIGH: r = R_PPC64_TPREL16_HIGH;
break;
case BFD_RELOC_PPC_TPREL16_HA: r = R_PPC64_TPREL16_HA;
break;
case BFD_RELOC_PPC64_TPREL16_HIGHA: r = R_PPC64_TPREL16_HIGHA;
break;
case BFD_RELOC_PPC_TPREL: r = R_PPC64_TPREL64;
break;
case BFD_RELOC_PPC_DTPREL16: r = R_PPC64_DTPREL16;
break;
case BFD_RELOC_PPC_DTPREL16_LO: r = R_PPC64_DTPREL16_LO;
break;
case BFD_RELOC_PPC_DTPREL16_HI: r = R_PPC64_DTPREL16_HI;
break;
case BFD_RELOC_PPC64_DTPREL16_HIGH: r = R_PPC64_DTPREL16_HIGH;
break;
case BFD_RELOC_PPC_DTPREL16_HA: r = R_PPC64_DTPREL16_HA;
break;
case BFD_RELOC_PPC64_DTPREL16_HIGHA: r = R_PPC64_DTPREL16_HIGHA;
break;
case BFD_RELOC_PPC_DTPREL: r = R_PPC64_DTPREL64;
break;
case BFD_RELOC_PPC_GOT_TLSGD16: r = R_PPC64_GOT_TLSGD16;
break;
case BFD_RELOC_PPC_GOT_TLSGD16_LO: r = R_PPC64_GOT_TLSGD16_LO;
break;
case BFD_RELOC_PPC_GOT_TLSGD16_HI: r = R_PPC64_GOT_TLSGD16_HI;
break;
case BFD_RELOC_PPC_GOT_TLSGD16_HA: r = R_PPC64_GOT_TLSGD16_HA;
break;
case BFD_RELOC_PPC_GOT_TLSLD16: r = R_PPC64_GOT_TLSLD16;
break;
case BFD_RELOC_PPC_GOT_TLSLD16_LO: r = R_PPC64_GOT_TLSLD16_LO;
break;
case BFD_RELOC_PPC_GOT_TLSLD16_HI: r = R_PPC64_GOT_TLSLD16_HI;
break;
case BFD_RELOC_PPC_GOT_TLSLD16_HA: r = R_PPC64_GOT_TLSLD16_HA;
break;
case BFD_RELOC_PPC_GOT_TPREL16: r = R_PPC64_GOT_TPREL16_DS;
break;
case BFD_RELOC_PPC_GOT_TPREL16_LO: r = R_PPC64_GOT_TPREL16_LO_DS;
break;
case BFD_RELOC_PPC_GOT_TPREL16_HI: r = R_PPC64_GOT_TPREL16_HI;
break;
case BFD_RELOC_PPC_GOT_TPREL16_HA: r = R_PPC64_GOT_TPREL16_HA;
break;
case BFD_RELOC_PPC_GOT_DTPREL16: r = R_PPC64_GOT_DTPREL16_DS;
break;
case BFD_RELOC_PPC_GOT_DTPREL16_LO: r = R_PPC64_GOT_DTPREL16_LO_DS;
break;
case BFD_RELOC_PPC_GOT_DTPREL16_HI: r = R_PPC64_GOT_DTPREL16_HI;
break;
case BFD_RELOC_PPC_GOT_DTPREL16_HA: r = R_PPC64_GOT_DTPREL16_HA;
break;
case BFD_RELOC_PPC64_TPREL16_DS: r = R_PPC64_TPREL16_DS;
break;
case BFD_RELOC_PPC64_TPREL16_LO_DS: r = R_PPC64_TPREL16_LO_DS;
break;
case BFD_RELOC_PPC64_TPREL16_HIGHER: r = R_PPC64_TPREL16_HIGHER;
break;
case BFD_RELOC_PPC64_TPREL16_HIGHERA: r = R_PPC64_TPREL16_HIGHERA;
break;
case BFD_RELOC_PPC64_TPREL16_HIGHEST: r = R_PPC64_TPREL16_HIGHEST;
break;
case BFD_RELOC_PPC64_TPREL16_HIGHESTA: r = R_PPC64_TPREL16_HIGHESTA;
break;
case BFD_RELOC_PPC64_DTPREL16_DS: r = R_PPC64_DTPREL16_DS;
break;
case BFD_RELOC_PPC64_DTPREL16_LO_DS: r = R_PPC64_DTPREL16_LO_DS;
break;
case BFD_RELOC_PPC64_DTPREL16_HIGHER: r = R_PPC64_DTPREL16_HIGHER;
break;
case BFD_RELOC_PPC64_DTPREL16_HIGHERA: r = R_PPC64_DTPREL16_HIGHERA;
break;
case BFD_RELOC_PPC64_DTPREL16_HIGHEST: r = R_PPC64_DTPREL16_HIGHEST;
break;
case BFD_RELOC_PPC64_DTPREL16_HIGHESTA: r = R_PPC64_DTPREL16_HIGHESTA;
break;
case BFD_RELOC_16_PCREL: r = R_PPC64_REL16;
break;
case BFD_RELOC_LO16_PCREL: r = R_PPC64_REL16_LO;
break;
case BFD_RELOC_HI16_PCREL: r = R_PPC64_REL16_HI;
break;
case BFD_RELOC_HI16_S_PCREL: r = R_PPC64_REL16_HA;
break;
case BFD_RELOC_PPC_REL16DX_HA: r = R_PPC64_REL16DX_HA;
break;
case BFD_RELOC_PPC64_ENTRY: r = R_PPC64_ENTRY;
break;
case BFD_RELOC_PPC64_ADDR64_LOCAL: r = R_PPC64_ADDR64_LOCAL;
break;
case BFD_RELOC_VTABLE_INHERIT: r = R_PPC64_GNU_VTINHERIT;
break;
case BFD_RELOC_VTABLE_ENTRY: r = R_PPC64_GNU_VTENTRY;
break;
}
return ppc64_elf_howto_table[r];
};
static reloc_howto_type *
ppc64_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
const char *r_name)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE (ppc64_elf_howto_raw); i++)
if (ppc64_elf_howto_raw[i].name != NULL
&& strcasecmp (ppc64_elf_howto_raw[i].name, r_name) == 0)
return &ppc64_elf_howto_raw[i];
return NULL;
}
/* Set the howto pointer for a PowerPC ELF reloc. */
static void
ppc64_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
Elf_Internal_Rela *dst)
{
unsigned int type;
/* Initialize howto table if needed. */
if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
ppc_howto_init ();
type = ELF64_R_TYPE (dst->r_info);
if (type >= ARRAY_SIZE (ppc64_elf_howto_table))
{
(*_bfd_error_handler) (_("%B: invalid relocation type %d"),
abfd, (int) type);
type = R_PPC64_NONE;
}
cache_ptr->howto = ppc64_elf_howto_table[type];
}
/* Handle the R_PPC64_ADDR16_HA and similar relocs. */
static bfd_reloc_status_type
ppc64_elf_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
void *data, asection *input_section,
bfd *output_bfd, char **error_message)
{
enum elf_ppc64_reloc_type r_type;
long insn;
bfd_size_type octets;
bfd_vma value;
/* If this is a relocatable link (output_bfd test tells us), just
call the generic function. Any adjustment will be done at final
link time. */
if (output_bfd != NULL)
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
/* Adjust the addend for sign extension of the low 16 bits.
We won't actually be using the low 16 bits, so trashing them
doesn't matter. */
reloc_entry->addend += 0x8000;
r_type = reloc_entry->howto->type;
if (r_type != R_PPC64_REL16DX_HA)
return bfd_reloc_continue;
value = 0;
if (!bfd_is_com_section (symbol->section))
value = symbol->value;
value += (reloc_entry->addend
+ symbol->section->output_offset
+ symbol->section->output_section->vma);
value -= (reloc_entry->address
+ input_section->output_offset
+ input_section->output_section->vma);
value = (bfd_signed_vma) value >> 16;
octets = reloc_entry->address * bfd_octets_per_byte (abfd);
insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
insn &= ~0x1fffc1;
insn |= (value & 0xffc1) | ((value & 0x3e) << 15);
bfd_put_32 (abfd, insn, (bfd_byte *) data + octets);
if (value + 0x8000 > 0xffff)
return bfd_reloc_overflow;
return bfd_reloc_ok;
}
static bfd_reloc_status_type
ppc64_elf_branch_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
void *data, asection *input_section,
bfd *output_bfd, char **error_message)
{
if (output_bfd != NULL)
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
if (strcmp (symbol->section->name, ".opd") == 0
&& (symbol->section->owner->flags & DYNAMIC) == 0)
{
bfd_vma dest = opd_entry_value (symbol->section,
symbol->value + reloc_entry->addend,
NULL, NULL, FALSE);
if (dest != (bfd_vma) -1)
reloc_entry->addend = dest - (symbol->value
+ symbol->section->output_section->vma
+ symbol->section->output_offset);
}
else
{
elf_symbol_type *elfsym = (elf_symbol_type *) symbol;
if (symbol->section->owner != abfd
&& symbol->section->owner != NULL
&& abiversion (symbol->section->owner) >= 2)
{
unsigned int i;
for (i = 0; i < symbol->section->owner->symcount; ++i)
{
asymbol *symdef = symbol->section->owner->outsymbols[i];
if (strcmp (symdef->name, symbol->name) == 0)
{
elfsym = (elf_symbol_type *) symdef;
break;
}
}
}
reloc_entry->addend
+= PPC64_LOCAL_ENTRY_OFFSET (elfsym->internal_elf_sym.st_other);
}
return bfd_reloc_continue;
}
static bfd_reloc_status_type
ppc64_elf_brtaken_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
void *data, asection *input_section,
bfd *output_bfd, char **error_message)
{
long insn;
enum elf_ppc64_reloc_type r_type;
bfd_size_type octets;
/* Assume 'at' branch hints. */
bfd_boolean is_isa_v2 = TRUE;
/* If this is a relocatable link (output_bfd test tells us), just
call the generic function. Any adjustment will be done at final
link time. */
if (output_bfd != NULL)
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
octets = reloc_entry->address * bfd_octets_per_byte (abfd);
insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
insn &= ~(0x01 << 21);
r_type = reloc_entry->howto->type;
if (r_type == R_PPC64_ADDR14_BRTAKEN
|| r_type == R_PPC64_REL14_BRTAKEN)
insn |= 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field. */
if (is_isa_v2)
{
/* Set 'a' bit. This is 0b00010 in BO field for branch
on CR(BI) insns (BO == 001at or 011at), and 0b01000
for branch on CTR insns (BO == 1a00t or 1a01t). */
if ((insn & (0x14 << 21)) == (0x04 << 21))
insn |= 0x02 << 21;
else if ((insn & (0x14 << 21)) == (0x10 << 21))
insn |= 0x08 << 21;
else
goto out;
}
else
{
bfd_vma target = 0;
bfd_vma from;
if (!bfd_is_com_section (symbol->section))
target = symbol->value;
target += symbol->section->output_section->vma;
target += symbol->section->output_offset;
target += reloc_entry->addend;
from = (reloc_entry->address
+ input_section->output_offset
+ input_section->output_section->vma);
/* Invert 'y' bit if not the default. */
if ((bfd_signed_vma) (target - from) < 0)
insn ^= 0x01 << 21;
}
bfd_put_32 (abfd, insn, (bfd_byte *) data + octets);
out:
return ppc64_elf_branch_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
}
static bfd_reloc_status_type
ppc64_elf_sectoff_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
void *data, asection *input_section,
bfd *output_bfd, char **error_message)
{
/* If this is a relocatable link (output_bfd test tells us), just
call the generic function. Any adjustment will be done at final
link time. */
if (output_bfd != NULL)
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
/* Subtract the symbol section base address. */
reloc_entry->addend -= symbol->section->output_section->vma;
return bfd_reloc_continue;
}
static bfd_reloc_status_type
ppc64_elf_sectoff_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
void *data, asection *input_section,
bfd *output_bfd, char **error_message)
{
/* If this is a relocatable link (output_bfd test tells us), just
call the generic function. Any adjustment will be done at final
link time. */
if (output_bfd != NULL)
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
/* Subtract the symbol section base address. */
reloc_entry->addend -= symbol->section->output_section->vma;
/* Adjust the addend for sign extension of the low 16 bits. */
reloc_entry->addend += 0x8000;
return bfd_reloc_continue;
}
static bfd_reloc_status_type
ppc64_elf_toc_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
void *data, asection *input_section,
bfd *output_bfd, char **error_message)
{
bfd_vma TOCstart;
/* If this is a relocatable link (output_bfd test tells us), just
call the generic function. Any adjustment will be done at final
link time. */
if (output_bfd != NULL)
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
if (TOCstart == 0)
TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner);
/* Subtract the TOC base address. */
reloc_entry->addend -= TOCstart + TOC_BASE_OFF;
return bfd_reloc_continue;
}
static bfd_reloc_status_type
ppc64_elf_toc_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
void *data, asection *input_section,
bfd *output_bfd, char **error_message)
{
bfd_vma TOCstart;
/* If this is a relocatable link (output_bfd test tells us), just
call the generic function. Any adjustment will be done at final
link time. */
if (output_bfd != NULL)
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
if (TOCstart == 0)
TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner);
/* Subtract the TOC base address. */
reloc_entry->addend -= TOCstart + TOC_BASE_OFF;
/* Adjust the addend for sign extension of the low 16 bits. */
reloc_entry->addend += 0x8000;
return bfd_reloc_continue;
}
static bfd_reloc_status_type
ppc64_elf_toc64_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
void *data, asection *input_section,
bfd *output_bfd, char **error_message)
{
bfd_vma TOCstart;
bfd_size_type octets;
/* If this is a relocatable link (output_bfd test tells us), just
call the generic function. Any adjustment will be done at final
link time. */
if (output_bfd != NULL)
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
if (TOCstart == 0)
TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner);
octets = reloc_entry->address * bfd_octets_per_byte (abfd);
bfd_put_64 (abfd, TOCstart + TOC_BASE_OFF, (bfd_byte *) data + octets);
return bfd_reloc_ok;
}
static bfd_reloc_status_type
ppc64_elf_unhandled_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
void *data, asection *input_section,
bfd *output_bfd, char **error_message)
{
/* If this is a relocatable link (output_bfd test tells us), just
call the generic function. Any adjustment will be done at final
link time. */
if (output_bfd != NULL)
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
if (error_message != NULL)
{
static char buf[60];
sprintf (buf, "generic linker can't handle %s",
reloc_entry->howto->name);
*error_message = buf;
}
return bfd_reloc_dangerous;
}
/* Track GOT entries needed for a given symbol. We might need more
than one got entry per symbol. */
struct got_entry
{
struct got_entry *next;
/* The symbol addend that we'll be placing in the GOT. */
bfd_vma addend;
/* Unlike other ELF targets, we use separate GOT entries for the same
symbol referenced from different input files. This is to support
automatic multiple TOC/GOT sections, where the TOC base can vary
from one input file to another. After partitioning into TOC groups
we merge entries within the group.
Point to the BFD owning this GOT entry. */
bfd *owner;
/* Zero for non-tls entries, or TLS_TLS and one of TLS_GD, TLS_LD,
TLS_TPREL or TLS_DTPREL for tls entries. */
unsigned char tls_type;
/* Non-zero if got.ent points to real entry. */
unsigned char is_indirect;
/* Reference count until size_dynamic_sections, GOT offset thereafter. */
union
{
bfd_signed_vma refcount;
bfd_vma offset;
struct got_entry *ent;
} got;
};
/* The same for PLT. */
struct plt_entry
{
struct plt_entry *next;
bfd_vma addend;
union
{
bfd_signed_vma refcount;
bfd_vma offset;
} plt;
};
struct ppc64_elf_obj_tdata
{
struct elf_obj_tdata elf;
/* Shortcuts to dynamic linker sections. */
asection *got;
asection *relgot;
/* Used during garbage collection. We attach global symbols defined
on removed .opd entries to this section so that the sym is removed. */
asection *deleted_section;
/* TLS local dynamic got entry handling. Support for multiple GOT
sections means we potentially need one of these for each input bfd. */
struct got_entry tlsld_got;
union {
/* A copy of relocs before they are modified for --emit-relocs. */