elf_elfheader (abfd)->e_flags |= ver & EF_PPC64_ABI;
}
\f
-#define ONES(n) (((bfd_vma) 1 << ((n) - 1) << 1) - 1)
-
/* Relocation HOWTO's. */
+/* Like other ELF RELA targets that don't apply multiple
+ field-altering relocations to the same localation, src_mask is
+ always zero and pcrel_offset is the same as pc_relative.
+ PowerPC can always use a zero bitpos, even when the field is not at
+ the LSB. For example, a REL24 could use rightshift=2, bisize=24
+ and bitpos=2 which matches the ABI description, or as we do here,
+ rightshift=0, bitsize=26 and bitpos=0. */
+#define HOW(type, size, bitsize, mask, rightshift, pc_relative, \
+ complain, special_func) \
+ HOWTO (type, rightshift, size, bitsize, pc_relative, 0, \
+ complain_overflow_ ## complain, special_func, \
+ #type, FALSE, 0, mask, pc_relative)
+
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 */
+ HOW (R_PPC64_NONE, 3, 0, 0, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR32, 2, 32, 0xffffffff, 0, FALSE, bitfield,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR24, 2, 26, 0x03fffffc, 0, FALSE, bitfield,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR16, 1, 16, 0xffff, 0, FALSE, bitfield,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR16_HI, 1, 16, 0xffff, 16, FALSE, signed,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR16_HA, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_ha_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR14, 2, 16, 0x0000fffc, 0, FALSE, signed,
+ ppc64_elf_branch_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR14_BRTAKEN, 2, 16, 0x0000fffc, 0, FALSE, signed,
+ ppc64_elf_brtaken_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR14_BRNTAKEN, 2, 16, 0x0000fffc, 0, FALSE, signed,
+ ppc64_elf_brtaken_reloc),
/* 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 */
+ HOW (R_PPC64_REL24, 2, 26, 0x03fffffc, 0, TRUE, signed,
+ ppc64_elf_branch_reloc),
/* A variant of R_PPC64_REL24, used when r2 is not the toc pointer. */
- HOWTO (R_PPC64_REL24_NOTOC, /* 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_NOTOC", /* name */
- FALSE, /* partial_inplace */
- 0, /* src_mask */
- 0x03fffffc, /* dst_mask */
- TRUE), /* pcrel_offset */
+ HOW (R_PPC64_REL24_NOTOC, 2, 26, 0x03fffffc, 0, TRUE, signed,
+ ppc64_elf_branch_reloc),
/* 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 */
+ HOW (R_PPC64_REL14, 2, 16, 0x0000fffc, 0, TRUE, signed,
+ ppc64_elf_branch_reloc),
/* 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 */
+ HOW (R_PPC64_REL14_BRTAKEN, 2, 16, 0x0000fffc, 0, TRUE, signed,
+ ppc64_elf_brtaken_reloc),
/* 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 */
+ HOW (R_PPC64_REL14_BRNTAKEN, 2, 16, 0x0000fffc, 0, TRUE, signed,
+ ppc64_elf_brtaken_reloc),
/* 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 */
+ HOW (R_PPC64_GOT16, 1, 16, 0xffff, 0, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT16_HI, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT16_HA, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_COPY, 0, 0, 0, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GLOB_DAT, 4, 64, 0xffffffffffffffffULL, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_JMP_SLOT, 0, 0, 0, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_RELATIVE, 4, 64, 0xffffffffffffffffULL, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_UADDR32, 2, 32, 0xffffffff, 0, FALSE, bitfield,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_UADDR16, 1, 16, 0xffff, 0, FALSE, bitfield,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_REL32, 2, 32, 0xffffffff, 0, TRUE, signed,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_PLT32, 2, 32, 0xffffffff, 0, FALSE, bitfield,
+ ppc64_elf_unhandled_reloc),
/* 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 */
- ppc64_elf_unhandled_reloc, /* special_function */
- "R_PPC64_PLTREL32", /* name */
- FALSE, /* partial_inplace */
- 0, /* src_mask */
- 0xffffffff, /* dst_mask */
- TRUE), /* pcrel_offset */
+ HOW (R_PPC64_PLTREL32, 2, 32, 0xffffffff, 0, TRUE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_PLT16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_PLT16_HI, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_PLT16_HA, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_SECTOFF, 1, 16, 0xffff, 0, FALSE, signed,
+ ppc64_elf_sectoff_reloc),
/* 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 */
+ HOW (R_PPC64_SECTOFF_LO, 1, 16, 0xffff, 0, FALSE, dont,
+ ppc64_elf_sectoff_reloc),
/* 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 */
+ HOW (R_PPC64_SECTOFF_HI, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_sectoff_reloc),
/* 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 */
+ HOW (R_PPC64_SECTOFF_HA, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_sectoff_ha_reloc),
/* 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 */
+ HOW (R_PPC64_REL30, 2, 30, 0xfffffffc, 2, TRUE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR64, 4, 64, 0xffffffffffffffffULL, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR16_HIGHER, 1, 16, 0xffff, 32, FALSE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR16_HIGHERA, 1, 16, 0xffff, 32, FALSE, dont,
+ ppc64_elf_ha_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR16_HIGHEST, 1, 16, 0xffff, 48, FALSE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR16_HIGHESTA, 1, 16, 0xffff, 48, FALSE, dont,
+ ppc64_elf_ha_reloc),
/* 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 */
+ HOW (R_PPC64_UADDR64, 4, 64, 0xffffffffffffffffULL, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_REL64, 4, 64, 0xffffffffffffffffULL, 0, TRUE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_PLT64, 4, 64, 0xffffffffffffffffULL, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_PLTREL64, 4, 64, 0xffffffffffffffffULL, 0, TRUE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TOC16, 1, 16, 0xffff, 0, FALSE, signed,
+ ppc64_elf_toc_reloc),
/* 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 */
+ HOW (R_PPC64_TOC16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+ ppc64_elf_toc_reloc),
/* 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 */
+ HOW (R_PPC64_TOC16_HI, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_toc_reloc),
/* 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 */
+ HOW (R_PPC64_TOC16_HA, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_toc_ha_reloc),
/* 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 */
+ HOW (R_PPC64_TOC, 4, 64, 0xffffffffffffffffULL, 0, FALSE, dont,
+ ppc64_elf_toc64_reloc),
/* Like R_PPC64_GOT16, but also informs the link editor that the
value to relocate may (!) refer to a PLT entry which the link
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 */
+ HOW (R_PPC64_PLTGOT16, 1, 16, 0xffff, 0, FALSE,signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_PLTGOT16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_PLTGOT16_HI, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_PLTGOT16_HA, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR16_DS, 1, 16, 0xfffc, 0, FALSE, signed,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR16_LO_DS, 1, 16, 0xfffc, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_GOT16_DS, 1, 16, 0xfffc, 0, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT16_LO_DS, 1, 16, 0xfffc, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_PLT16_LO_DS, 1, 16, 0xfffc, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_SECTOFF_DS, 1, 16, 0xfffc, 0, FALSE, signed,
+ ppc64_elf_sectoff_reloc),
/* 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 */
+ HOW (R_PPC64_SECTOFF_LO_DS, 1, 16, 0xfffc, 0, FALSE, dont,
+ ppc64_elf_sectoff_reloc),
/* 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 */
+ HOW (R_PPC64_TOC16_DS, 1, 16, 0xfffc, 0, FALSE, signed,
+ ppc64_elf_toc_reloc),
/* 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 */
+ HOW (R_PPC64_TOC16_LO_DS, 1, 16, 0xfffc, 0, FALSE, dont,
+ ppc64_elf_toc_reloc),
/* 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 */
+ HOW (R_PPC64_PLTGOT16_DS, 1, 16, 0xfffc, 0, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_PLTGOT16_LO_DS, 1, 16, 0xfffc, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TLS, 2, 32, 0, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
+
+ HOW (R_PPC64_TLSGD, 2, 32, 0, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
+
+ HOW (R_PPC64_TLSLD, 2, 32, 0, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
/* Marker reloc for optimizing r2 save in prologue rather than on
each plt call stub. */
- 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 */
+ HOW (R_PPC64_TOCSAVE, 2, 32, 0, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
/* Marker relocs on inline plt call instructions. */
- HOWTO (R_PPC64_PLTSEQ,
- 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_PLTSEQ", /* name */
- FALSE, /* partial_inplace */
- 0, /* src_mask */
- 0, /* dst_mask */
- FALSE), /* pcrel_offset */
-
- HOWTO (R_PPC64_PLTCALL,
- 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_PLTCALL", /* name */
- FALSE, /* partial_inplace */
- 0, /* src_mask */
- 0, /* dst_mask */
- FALSE), /* pcrel_offset */
+ HOW (R_PPC64_PLTSEQ, 2, 32, 0, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
+
+ HOW (R_PPC64_PLTCALL, 2, 32, 0, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_DTPMOD64, 4, 64, 0xffffffffffffffffULL, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_DTPREL64, 4, 64, 0xffffffffffffffffULL, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_DTPREL16, 1, 16, 0xffff, 0, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_DTPREL16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_DTPREL16_HI, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_DTPREL16_HA, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_DTPREL16_HIGHER, 1, 16, 0xffff, 32, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_DTPREL16_HIGHERA, 1, 16, 0xffff, 32, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_DTPREL16_HIGHEST, 1, 16, 0xffff, 48, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_DTPREL16_HIGHESTA, 1, 16, 0xffff, 48, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_DTPREL16_DS, 1, 16, 0xfffc, 0, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_DTPREL16_LO_DS, 1, 16, 0xfffc, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TPREL64, 4, 64, 0xffffffffffffffffULL, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TPREL16, 1, 16, 0xffff, 0, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TPREL16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TPREL16_HI, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TPREL16_HA, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TPREL16_HIGHER, 1, 16, 0xffff, 32, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TPREL16_HIGHERA, 1, 16, 0xffff, 32, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TPREL16_HIGHEST, 1, 16, 0xffff, 48, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TPREL16_HIGHESTA, 1, 16, 0xffff, 48, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TPREL16_DS, 1, 16, 0xfffc, 0, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TPREL16_LO_DS, 1, 16, 0xfffc, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_TLSGD16, 1, 16, 0xffff, 0, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_TLSGD16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_TLSGD16_HI, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_TLSGD16_HA, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_TLSLD16, 1, 16, 0xffff, 0, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_TLSLD16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_TLSLD16_HI, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_TLSLD16_HA, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_DTPREL16_DS, 1, 16, 0xfffc, 0, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_DTPREL16_LO_DS, 1, 16, 0xfffc, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_DTPREL16_HI, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_DTPREL16_HA, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_TPREL16_DS, 1, 16, 0xfffc, 0, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_TPREL16_LO_DS, 1, 16, 0xfffc, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_TPREL16_HI, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_GOT_TPREL16_HA, 1, 16, 0xffff, 16, FALSE, signed,
+ ppc64_elf_unhandled_reloc),
+
+ HOW (R_PPC64_JMP_IREL, 0, 0, 0, 0, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
+
+ HOW (R_PPC64_IRELATIVE, 4, 64, 0xffffffffffffffffULL, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_REL16, 1, 16, 0xffff, 0, TRUE, signed,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_REL16_LO, 1, 16, 0xffff, 0, TRUE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_REL16_HI, 1, 16, 0xffff, 16, TRUE, signed,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_REL16_HA, 1, 16, 0xffff, 16, TRUE, signed,
+ ppc64_elf_ha_reloc),
+
+ HOW (R_PPC64_REL16_HIGH, 1, 16, 0xffff, 16, TRUE, dont,
+ bfd_elf_generic_reloc),
+
+ HOW (R_PPC64_REL16_HIGHA, 1, 16, 0xffff, 16, TRUE, dont,
+ ppc64_elf_ha_reloc),
+
+ HOW (R_PPC64_REL16_HIGHER, 1, 16, 0xffff, 32, TRUE, dont,
+ bfd_elf_generic_reloc),
+
+ HOW (R_PPC64_REL16_HIGHERA, 1, 16, 0xffff, 32, TRUE, dont,
+ ppc64_elf_ha_reloc),
+
+ HOW (R_PPC64_REL16_HIGHEST, 1, 16, 0xffff, 48, TRUE, dont,
+ bfd_elf_generic_reloc),
+
+ HOW (R_PPC64_REL16_HIGHESTA, 1, 16, 0xffff, 48, TRUE, dont,
+ ppc64_elf_ha_reloc),
/* 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 */
+ HOW (R_PPC64_REL16DX_HA, 2, 16, 0x1fffc1, 16, TRUE, signed,
+ ppc64_elf_ha_reloc),
/* A split-field reloc for addpcis, non-relative (gas internal use only). */
- HOWTO (R_PPC64_16DX_HA, /* type */
- 16, /* rightshift */
- 2, /* 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_16DX_HA", /* name */
- FALSE, /* partial_inplace */
- 0, /* src_mask */
- 0x1fffc1, /* dst_mask */
- FALSE), /* pcrel_offset */
+ HOW (R_PPC64_16DX_HA, 2, 16, 0x1fffc1, 16, FALSE, signed,
+ ppc64_elf_ha_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR16_HIGH, 1, 16, 0xffff, 16, FALSE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR16_HIGHA, 1, 16, 0xffff, 16, FALSE, dont,
+ ppc64_elf_ha_reloc),
/* 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 */
+ HOW (R_PPC64_DTPREL16_HIGH, 1, 16, 0xffff, 16, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_DTPREL16_HIGHA, 1, 16, 0xffff, 16, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TPREL16_HIGH, 1, 16, 0xffff, 16, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_TPREL16_HIGHA, 1, 16, 0xffff, 16, FALSE, dont,
+ ppc64_elf_unhandled_reloc),
/* 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 */
+ HOW (R_PPC64_ENTRY, 2, 32, 0, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_ADDR64_LOCAL, 4, 64, 0xffffffffffffffffULL, 0, FALSE, dont,
+ bfd_elf_generic_reloc),
/* 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 */
+ HOW (R_PPC64_GNU_VTINHERIT, 0, 0, 0, 0, FALSE, dont,
+ NULL),
/* 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 */
+ HOW (R_PPC64_GNU_VTENTRY, 0, 0, 0, 0, FALSE, dont,
+ NULL),
};
\f
{
default:
/* xgettext:c-format */
- _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, (int) code);
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd,
+ (int) code);
bfd_set_error (bfd_error_bad_value);
return NULL;
break;
case BFD_RELOC_HI16_S_PCREL: r = R_PPC64_REL16_HA;
break;
+ case BFD_RELOC_PPC64_REL16_HIGH: r = R_PPC64_REL16_HIGH;
+ break;
+ case BFD_RELOC_PPC64_REL16_HIGHA: r = R_PPC64_REL16_HIGHA;
+ break;
+ case BFD_RELOC_PPC64_REL16_HIGHER: r = R_PPC64_REL16_HIGHER;
+ break;
+ case BFD_RELOC_PPC64_REL16_HIGHERA: r = R_PPC64_REL16_HIGHERA;
+ break;
+ case BFD_RELOC_PPC64_REL16_HIGHEST: r = R_PPC64_REL16_HIGHEST;
+ break;
+ case BFD_RELOC_PPC64_REL16_HIGHESTA: r = R_PPC64_REL16_HIGHESTA;
+ break;
case BFD_RELOC_PPC_16DX_HA: r = R_PPC64_16DX_HA;
break;
case BFD_RELOC_PPC_REL16DX_HA: r = R_PPC64_REL16DX_HA;
&& strcasecmp (ppc64_elf_howto_raw[i].name, r_name) == 0)
return &ppc64_elf_howto_raw[i];
-
return NULL;
}
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
-
+
return TRUE;
}
/* Reference count until size_dynamic_sections, GOT offset thereafter. */
union
- {
- bfd_signed_vma refcount;
- bfd_vma offset;
- struct got_entry *ent;
- } got;
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ struct got_entry *ent;
+ } got;
};
/* The same for PLT. */
bfd_vma addend;
union
- {
- bfd_signed_vma refcount;
- bfd_vma offset;
- } plt;
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } plt;
};
struct ppc64_elf_obj_tdata
sections means we potentially need one of these for each input bfd. */
struct got_entry tlsld_got;
- union {
+ union
+ {
/* A copy of relocs before they are modified for --emit-relocs. */
Elf_Internal_Rela *relocs;
/* Add extra PPC sections. */
-static const struct bfd_elf_special_section ppc64_elf_special_sections[]=
+static const struct bfd_elf_special_section ppc64_elf_special_sections[] =
{
{ STRING_COMMA_LEN (".plt"), 0, SHT_NOBITS, 0 },
{ STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
static int
compare_symbols (const void *ap, const void *bp)
{
- const asymbol *a = * (const asymbol **) ap;
- const asymbol *b = * (const asymbol **) bp;
+ const asymbol *a = *(const asymbol **) ap;
+ const asymbol *b = *(const asymbol **) bp;
/* Section symbols first. */
if ((a->flags & BSF_SECTION_SYM) && !(b->flags & BSF_SECTION_SYM))
}
/* then other code symbols. */
- if ((a->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
- == (SEC_CODE | SEC_ALLOC)
- && (b->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
- != (SEC_CODE | SEC_ALLOC))
+ if (((a->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
+ == (SEC_CODE | SEC_ALLOC))
+ && ((b->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
+ != (SEC_CODE | SEC_ALLOC)))
return -1;
- if ((a->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
- != (SEC_CODE | SEC_ALLOC)
- && (b->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
- == (SEC_CODE | SEC_ALLOC))
+ if (((a->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
+ != (SEC_CODE | SEC_ALLOC))
+ && ((b->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
+ == (SEC_CODE | SEC_ALLOC)))
return 1;
if (synthetic_relocatable)
opdsymend = i;
for (; i < symcount; ++i)
- if ((syms[i]->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
+ if (((syms[i]->section->flags
+ & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL)))
!= (SEC_CODE | SEC_ALLOC))
break;
symcount = i;
insn ^= B_DOT;
if ((insn & ~0x3fffffc) == 0)
{
- resolv_vma = glink_vma + off + (insn ^ 0x2000000) - 0x2000000;
+ resolv_vma
+ = glink_vma + off + (insn ^ 0x2000000) - 0x2000000;
break;
}
off += 4;
if (relplt != NULL)
{
slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
- if (! (*slurp_relocs) (abfd, relplt, dyn_syms, TRUE))
+ if (!(*slurp_relocs) (abfd, relplt, dyn_syms, TRUE))
goto free_contents_and_exit_err;
plt_count = relplt->size / sizeof (Elf64_External_Rela);
s->section = glink;
s->value = resolv_vma - glink->vma;
s->name = names;
- memcpy (names, "__glink_PLTresolve", sizeof ("__glink_PLTresolve"));
+ memcpy (names, "__glink_PLTresolve",
+ sizeof ("__glink_PLTresolve"));
names += sizeof ("__glink_PLTresolve");
s++;
count++;
. 1:
. mflr %r11
. mtlr %r12
- . lis %r12,xxx-1b@highest
- . ori %r12,xxx-1b@higher
- . sldi %r12,%r12,32
- . oris %r12,%r12,xxx-1b@hi
- . ori %r12,%r12,xxx-1b@l
- . add %r12,%r11,%r12
+ . addis %r12,%r11,dest-1b@ha
+ . addi %r12,%r12,dest-1b@l
. b dest
ppc_stub_plt_branch_notoc:
. mflr %r11
. mtlr %r12
. lis %r12,xxx-1b@highest
- . ori %r12,xxx-1b@higher
+ . ori %r12,%r12,xxx-1b@higher
. sldi %r12,%r12,32
- . oris %r12,%r12,xxx-1b@hi
+ . oris %r12,%r12,xxx-1b@high
. ori %r12,%r12,xxx-1b@l
. add %r12,%r11,%r12
. mtctr %r12
. mflr %r11
. mtlr %r12
. lis %r12,xxx-1b@highest
- . ori %r12,xxx-1b@higher
+ . ori %r12,%r12,xxx-1b@higher
. sldi %r12,%r12,32
- . oris %r12,%r12,xxx-1b@hi
+ . oris %r12,%r12,xxx-1b@high
. ori %r12,%r12,xxx-1b@l
. ldx %r12,%r11,%r12
. mtctr %r12
hierarchy of long branch and plt branch stubs for local call
linkage. */
-enum ppc_stub_type {
+enum ppc_stub_type
+{
ppc_stub_none,
ppc_stub_long_branch,
ppc_stub_long_branch_r2off,
/* Whether to emit a copy of register save/restore functions in this
group. */
int needs_save_res;
- /* The offset of the __tls_get_addr_opt plt stub bctrl in this group,
- or -1u if no such stub with bctrl exists. */
- unsigned int tls_get_addr_opt_bctrl;
+ /* Current offset within stubs after the insn restoring lr in a
+ _notoc or _both stub using bcl for pc-relative addressing, or
+ after the insn restoring lr in a __tls_get_addr_opt plt stub. */
+ unsigned int lr_restore;
+ /* Accumulated size of EH info emitted to describe return address
+ if stubs modify lr. Does not include 17 byte FDE header. */
+ unsigned int eh_size;
+ /* Offset in glink_eh_frame to the start of EH info for this group. */
+ unsigned int eh_base;
};
-struct ppc_stub_hash_entry {
-
+struct ppc_stub_hash_entry
+{
/* Base hash table entry structure. */
struct bfd_hash_entry root;
unsigned char other;
};
-struct ppc_branch_hash_entry {
-
+struct ppc_branch_hash_entry
+{
/* Base hash table entry structure. */
struct bfd_hash_entry root;
{
struct elf_link_hash_entry elf;
- union {
+ union
+ {
/* A pointer to the most recently used stub hash entry against this
symbol. */
struct ppc_stub_hash_entry *stub_cache;
return entry;
}
-struct tocsave_entry {
+struct tocsave_entry
+{
asection *sec;
bfd_vma offset;
};
htab->sfpr = bfd_make_section_anyway_with_flags (dynobj, ".sfpr",
flags);
if (htab->sfpr == NULL
- || ! bfd_set_section_alignment (dynobj, htab->sfpr, 2))
+ || !bfd_set_section_alignment (dynobj, htab->sfpr, 2))
return FALSE;
}
htab->glink = bfd_make_section_anyway_with_flags (dynobj, ".glink",
flags);
if (htab->glink == NULL
- || ! bfd_set_section_alignment (dynobj, htab->glink, 3))
+ || !bfd_set_section_alignment (dynobj, htab->glink, 3))
return FALSE;
/* The part of .glink used by global entry stubs, separate so that
htab->global_entry = bfd_make_section_anyway_with_flags (dynobj, ".glink",
flags);
if (htab->global_entry == NULL
- || ! bfd_set_section_alignment (dynobj, htab->global_entry, 2))
+ || !bfd_set_section_alignment (dynobj, htab->global_entry, 2))
return FALSE;
if (!info->no_ld_generated_unwind_info)
flags = SEC_ALLOC | SEC_LINKER_CREATED;
htab->elf.iplt = bfd_make_section_anyway_with_flags (dynobj, ".iplt", flags);
if (htab->elf.iplt == NULL
- || ! bfd_set_section_alignment (dynobj, htab->elf.iplt, 3))
+ || !bfd_set_section_alignment (dynobj, htab->elf.iplt, 3))
return FALSE;
flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
htab->elf.irelplt
= bfd_make_section_anyway_with_flags (dynobj, ".rela.iplt", flags);
if (htab->elf.irelplt == NULL
- || ! bfd_set_section_alignment (dynobj, htab->elf.irelplt, 3))
+ || !bfd_set_section_alignment (dynobj, htab->elf.irelplt, 3))
return FALSE;
/* Create branch lookup table for plt_branch stubs. */
htab->brlt = bfd_make_section_anyway_with_flags (dynobj, ".branch_lt",
flags);
if (htab->brlt == NULL
- || ! bfd_set_section_alignment (dynobj, htab->brlt, 3))
+ || !bfd_set_section_alignment (dynobj, htab->brlt, 3))
return FALSE;
/* Local plt entries, put in .branch_lt but a separate section for
htab->pltlocal = bfd_make_section_anyway_with_flags (dynobj, ".branch_lt",
flags);
if (htab->pltlocal == NULL
- || ! bfd_set_section_alignment (dynobj, htab->pltlocal, 3))
+ || !bfd_set_section_alignment (dynobj, htab->pltlocal, 3))
return FALSE;
if (!bfd_link_pic (info))
htab->relbrlt
= bfd_make_section_anyway_with_flags (dynobj, ".rela.branch_lt", flags);
if (htab->relbrlt == NULL
- || ! bfd_set_section_alignment (dynobj, htab->relbrlt, 3))
+ || !bfd_set_section_alignment (dynobj, htab->relbrlt, 3))
return FALSE;
htab->relpltlocal
= bfd_make_section_anyway_with_flags (dynobj, ".rela.branch_lt", flags);
if (htab->relpltlocal == NULL
- || ! bfd_set_section_alignment (dynobj, htab->relpltlocal, 3))
+ || !bfd_set_section_alignment (dynobj, htab->relpltlocal, 3))
return FALSE;
return TRUE;
relgot = bfd_make_section_anyway_with_flags (abfd, ".rela.got",
flags | SEC_READONLY);
if (!relgot
- || ! bfd_set_section_alignment (abfd, relgot, 3))
+ || !bfd_set_section_alignment (abfd, relgot, 3))
return FALSE;
ppc64_elf_tdata (abfd)->got = got;
&& (eh->elf.ref_regular
|| eh->elf.def_regular))
{
- if (! bfd_elf_link_record_dynamic_symbol (info, &fdh->elf))
+ if (!bfd_elf_link_record_dynamic_symbol (info, &fdh->elf))
return FALSE;
}
}
case R_PPC64_REL16_LO:
case R_PPC64_REL16_HI:
case R_PPC64_REL16_HA:
+ case R_PPC64_REL16_HIGH:
+ case R_PPC64_REL16_HIGHA:
+ case R_PPC64_REL16_HIGHER:
+ case R_PPC64_REL16_HIGHERA:
+ case R_PPC64_REL16_HIGHEST:
+ case R_PPC64_REL16_HIGHESTA:
case R_PPC64_REL16DX_HA:
break;
|| info->export_dynamic
|| (eh->elf.dynamic
&& d != NULL
- && (*d->match) (&d->head, NULL, eh->elf.root.root.string)))
+ && (*d->match) (&d->head, NULL,
+ eh->elf.root.root.string)))
&& (eh->elf.versioned >= versioned
|| !bfd_hide_sym_by_version (info->version_info,
eh->elf.root.root.string)))))
{
const char name[12];
unsigned char lo, hi;
- bfd_byte * (*write_ent) (bfd *, bfd_byte *, int);
- bfd_byte * (*write_tail) (bfd *, bfd_byte *, int);
+ bfd_byte *(*write_ent) (bfd *, bfd_byte *, int);
+ bfd_byte *(*write_tail) (bfd *, bfd_byte *, int);
};
/* Auto-generate _save*, _rest* functions in .sfpr.
writing = TRUE;
if (htab->sfpr->contents == NULL)
{
- htab->sfpr->contents = bfd_alloc (htab->elf.dynobj, SFPR_MAX);
+ htab->sfpr->contents
+ = bfd_alloc (htab->elf.dynobj, SFPR_MAX);
if (htab->sfpr->contents == NULL)
return FALSE;
}
htab->elf.hgot->root.linker_def = 1;
}
htab->elf.hgot->type = STT_OBJECT;
- htab->elf.hgot->other = ((htab->elf.hgot->other & ~ELF_ST_VISIBILITY (-1))
- | STV_HIDDEN);
+ htab->elf.hgot->other
+ = (htab->elf.hgot->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
}
if (htab->need_func_desc_adj)
if (readonly_dynrelocs (&eh->elf))
return TRUE;
eh = (struct ppc_link_hash_entry *) eh->elf.u.alias;
- } while (eh != NULL && &eh->elf != h);
+ }
+ while (eh != NULL && &eh->elf != h);
return FALSE;
}
if (p == NULL)
return FALSE;
- if (! bfd_get_section_contents (need_pad->owner, need_pad,
- p, 0, need_pad->size))
+ if (!bfd_get_section_contents (need_pad->owner, need_pad,
+ p, 0, need_pad->size))
return FALSE;
need_pad->contents = p;
if (elf_section_data (sec)->relocs != relstart)
free (relstart);
if (local_syms != NULL
- && symtab_hdr->contents != (unsigned char *) local_syms)
+ && symtab_hdr->contents != (bfd_byte *) local_syms)
free (local_syms);
return FALSE;
}
if (!bfd_elf_link_record_dynamic_symbol (info, opt_fd))
return NULL;
}
- htab->tls_get_addr_fd = (struct ppc_link_hash_entry *) opt_fd;
+ htab->tls_get_addr_fd
+ = (struct ppc_link_hash_entry *) opt_fd;
tga = &htab->tls_get_addr->elf;
if (opt != NULL && tga != NULL)
{
&& is_plt_seq_reloc (ELF64_R_TYPE (rel[1].r_info)))
{
if (pass != 0
- && ELF64_R_TYPE (rel[1].r_info) != R_PPC64_PLTSEQ)
+ && (ELF64_R_TYPE (rel[1].r_info)
+ != R_PPC64_PLTSEQ))
{
r_symndx = ELF64_R_SYM (rel[1].r_info);
if (!get_sym_h (&h, NULL, NULL, NULL, &locsyms,
- r_symndx, ibfd))
+ r_symndx, ibfd))
goto err_free_rel;
if (h != NULL)
{
case of R_PPC64_TLS, and after checking for
tls_get_addr for the TOC16 relocs. */
if (toc_ref == NULL)
- toc_ref = bfd_zmalloc (toc->output_section->rawsize / 8);
+ toc_ref
+ = bfd_zmalloc (toc->output_section->rawsize / 8);
if (toc_ref == NULL)
goto err_free_rel;
struct bfd_link_info *info = (struct bfd_link_info *) inf;
info->flags |= DF_TEXTREL;
- info->callbacks->minfo
- (_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\n"),
- sec->owner, h->root.root.string, sec);
+ info->callbacks->minfo (_("%pB: dynamic relocation against `%pT'"
+ " in read-only section `%pA'\n"),
+ sec->owner, h->root.root.string, sec);
/* Not an error, just cut short the traversal. */
return FALSE;
return ppc_stub_none;
}
-/* Builds a 64-bit offset in r12 then adds it to r11 (LOAD false) or
- loads r12 from r11+r12 (LOAD true).
+/* Gets the address of a label (1:) in r11 and builds an offset in r12,
+ then adds it to r11 (LOAD false) or loads r12 from r11+r12 (LOAD true).
+ . mflr %r12
+ . bcl 20,31,1f
+ .1: mflr %r11
+ . mtlr %r12
. lis %r12,xxx-1b@highest
- . ori %r12,xxx-1b@higher
+ . ori %r12,%r12,xxx-1b@higher
. sldi %r12,%r12,32
- . oris %r12,%r12,xxx-1b@hi
+ . oris %r12,%r12,xxx-1b@high
. ori %r12,%r12,xxx-1b@l
- . add %r12,%r11,%r12 */
+ . add/ldx %r12,%r11,%r12 */
static bfd_byte *
build_offset (bfd *abfd, bfd_byte *p, bfd_vma off, bfd_boolean load)
{
+ bfd_put_32 (abfd, MFLR_R12, p);
+ p += 4;
+ bfd_put_32 (abfd, BCL_20_31, p);
+ p += 4;
+ bfd_put_32 (abfd, MFLR_R11, p);
+ p += 4;
+ bfd_put_32 (abfd, MTLR_R12, p);
+ p += 4;
if (off + 0x8000 < 0x10000)
{
if (load)
size += 4;
size += 4;
}
- return size;
+ return size + 16;
+}
+
+/* Emit .eh_frame opcode to advance pc by DELTA. */
+
+static bfd_byte *
+eh_advance (bfd *abfd, bfd_byte *eh, unsigned int delta)
+{
+ delta /= 4;
+ if (delta < 64)
+ *eh++ = DW_CFA_advance_loc + delta;
+ else if (delta < 256)
+ {
+ *eh++ = DW_CFA_advance_loc1;
+ *eh++ = delta;
+ }
+ else if (delta < 65536)
+ {
+ *eh++ = DW_CFA_advance_loc2;
+ bfd_put_16 (abfd, delta, eh);
+ eh += 2;
+ }
+ else
+ {
+ *eh++ = DW_CFA_advance_loc4;
+ bfd_put_32 (abfd, delta, eh);
+ eh += 4;
+ }
+ return eh;
+}
+
+/* Size of required .eh_frame opcode to advance pc by DELTA. */
+
+static unsigned int
+eh_advance_size (unsigned int delta)
+{
+ if (delta < 64 * 4)
+ /* DW_CFA_advance_loc+[1..63]. */
+ return 1;
+ if (delta < 256 * 4)
+ /* DW_CFA_advance_loc1, byte. */
+ return 2;
+ if (delta < 65536 * 4)
+ /* DW_CFA_advance_loc2, 2 bytes. */
+ return 3;
+ /* DW_CFA_advance_loc4, 4 bytes. */
+ return 5;
}
/* With power7 weakly ordered memory model, it is possible for ld.so
if (stub_entry->stub_type >= ppc_stub_plt_call_notoc)
{
- size = 24 + size_offset (off);
+ size = 8 + size_offset (off - 8);
if (stub_entry->stub_type > ppc_stub_plt_call_notoc)
size += 4;
return size;
bfd_byte *p, bfd_vma offset, Elf_Internal_Rela *r)
{
bfd *obfd = htab->params->stub_bfd;
+ bfd_byte *loc = p;
bfd_put_32 (obfd, LD_R11_0R3 + 0, p), p += 4;
bfd_put_32 (obfd, LD_R12_0R3 + 8, p), p += 4;
bfd_put_32 (obfd, MTLR_R11, p), p += 4;
bfd_put_32 (obfd, BLR, p), p += 4;
+ if (htab->glink_eh_frame != NULL
+ && htab->glink_eh_frame->size != 0)
+ {
+ bfd_byte *base, *eh;
+ unsigned int lr_used, delta;
+
+ base = htab->glink_eh_frame->contents + stub_entry->group->eh_base + 17;
+ eh = base + stub_entry->group->eh_size;
+ lr_used = stub_entry->stub_offset + (p - 20 - loc);
+ delta = lr_used - stub_entry->group->lr_restore;
+ stub_entry->group->lr_restore = lr_used + 16;
+ eh = eh_advance (htab->elf.dynobj, eh, delta);
+ *eh++ = DW_CFA_offset_extended_sf;
+ *eh++ = 65;
+ *eh++ = -(STK_LINKER (htab) / 8) & 0x7f;
+ *eh++ = DW_CFA_advance_loc + 4;
+ *eh++ = DW_CFA_restore_extended;
+ *eh++ = 65;
+ stub_entry->group->eh_size = eh - base;
+ }
return p;
}
if (strcmp (opd->name, ".opd") != 0
|| opd->reloc_count != 0)
{
- info->callbacks->einfo (_("%P: cannot find opd entry toc for `%pT'\n"),
- stub_entry->h->elf.root.root.string);
+ info->callbacks->einfo
+ (_("%P: cannot find opd entry toc for `%pT'\n"),
+ stub_entry->h->elf.root.root.string);
bfd_set_error (bfd_error_bad_value);
return (bfd_vma) -1;
}
case ppc_stub_plt_call_notoc:
case ppc_stub_plt_call_both:
p = loc;
- off = (8 + stub_entry->stub_offset
+ off = (stub_entry->stub_offset
+ stub_entry->group->stub_sec->output_offset
+ stub_entry->group->stub_sec->output_section->vma);
if (stub_entry->stub_type == ppc_stub_long_branch_both
+ stub_entry->target_section->output_offset
+ stub_entry->target_section->output_section->vma);
off = targ - off;
- bfd_put_32 (htab->params->stub_bfd, MFLR_R12, p);
- p += 4;
- bfd_put_32 (htab->params->stub_bfd, BCL_20_31, p);
- p += 4;
- bfd_put_32 (htab->params->stub_bfd, MFLR_R11, p);
- p += 4;
- bfd_put_32 (htab->params->stub_bfd, MTLR_R12, p);
- p += 4;
+
+ /* The notoc stubs calculate their target (either a PLT entry or
+ the global entry point of a function) relative to the PC
+ returned by the "bcl" two instructions past the start of the
+ sequence emitted by build_offset. The offset is therefore 8
+ less than calculated from the start of the sequence. */
+ off -= 8;
p = build_offset (htab->params->stub_bfd, p, off,
stub_entry->stub_type >= ppc_stub_plt_call_notoc);
- if (stub_entry->stub_type == ppc_stub_long_branch_notoc)
+ if (stub_entry->stub_type <= ppc_stub_long_branch_both)
{
- off += 8;
+ bfd_vma from;
+ from = (stub_entry->stub_offset
+ + stub_entry->group->stub_sec->output_offset
+ + stub_entry->group->stub_sec->output_section->vma
+ + (p - loc));
bfd_put_32 (htab->params->stub_bfd,
- B_DOT | ((off - (p - loc)) & 0x3fffffc), p);
- }
- else if (stub_entry->stub_type == ppc_stub_long_branch_both)
- {
- off += 12;
- bfd_put_32 (htab->params->stub_bfd,
- B_DOT | ((off - (p - loc)) & 0x3fffffc), p);
+ B_DOT | ((targ - from) & 0x3fffffc), p);
}
else
{
bfd_put_32 (htab->params->stub_bfd, BCTR, p);
}
p += 4;
+
+ if (htab->glink_eh_frame != NULL
+ && htab->glink_eh_frame->size != 0)
+ {
+ bfd_byte *base, *eh;
+ unsigned int lr_used, delta;
+
+ base = (htab->glink_eh_frame->contents
+ + stub_entry->group->eh_base + 17);
+ eh = base + stub_entry->group->eh_size;
+ lr_used = stub_entry->stub_offset + 8;
+ if (stub_entry->stub_type == ppc_stub_long_branch_both
+ || stub_entry->stub_type == ppc_stub_plt_branch_both
+ || stub_entry->stub_type == ppc_stub_plt_call_both)
+ lr_used += 4;
+ delta = lr_used - stub_entry->group->lr_restore;
+ stub_entry->group->lr_restore = lr_used + 8;
+ eh = eh_advance (htab->elf.dynobj, eh, delta);
+ *eh++ = DW_CFA_register;
+ *eh++ = 65;
+ *eh++ = 12;
+ *eh++ = DW_CFA_advance_loc + 2;
+ *eh++ = DW_CFA_restore_extended;
+ *eh++ = 65;
+ stub_entry->group->eh_size = eh - base;
+ }
break;
case ppc_stub_plt_call:
struct ppc_stub_hash_entry *stub_entry;
struct bfd_link_info *info;
struct ppc_link_hash_table *htab;
- bfd_vma targ, off;
- int size;
+ asection *plt;
+ bfd_vma targ, off, r2off;
+ unsigned int size, extra, lr_used, delta;
/* Massage our args to the form they really have. */
stub_entry = (struct ppc_stub_hash_entry *) gen_entry;
return TRUE;
}
- if (stub_entry->stub_type >= ppc_stub_plt_call
- && stub_entry->stub_type <= ppc_stub_plt_call_both)
- {
- asection *plt;
- targ = stub_entry->plt_ent->plt.offset & ~(bfd_vma) 1;
- if (targ >= (bfd_vma) -2)
- abort ();
- plt = htab->elf.splt;
- if (!htab->elf.dynamic_sections_created
- || stub_entry->h == NULL
- || stub_entry->h->elf.dynindx == -1)
- {
- if (stub_entry->symtype == STT_GNU_IFUNC)
- plt = htab->elf.iplt;
- else
- plt = htab->pltlocal;
- }
- targ += plt->output_offset + plt->output_section->vma;
-
- if (stub_entry->stub_type >= ppc_stub_plt_call_notoc)
- {
- off = (8 + stub_entry->stub_offset
- + stub_entry->group->stub_sec->output_offset
- + stub_entry->group->stub_sec->output_section->vma);
- if (stub_entry->stub_type > ppc_stub_plt_call_notoc)
- off += 4;
- }
- else
- off = (elf_gp (info->output_bfd)
- + htab->sec_info[stub_entry->group->link_sec->id].toc_off);
-
- if (htab->params->plt_stub_align != 0)
- {
- unsigned pad = plt_stub_pad (htab, stub_entry, targ - off);
-
- stub_entry->group->stub_sec->size += pad;
- stub_entry->stub_offset = stub_entry->group->stub_sec->size;
- if (stub_entry->stub_type >= ppc_stub_plt_call_notoc)
- off += pad;
- }
-
- off = targ - off;
- size = plt_stub_size (htab, stub_entry, off);
-
- if (stub_entry->stub_type < ppc_stub_plt_call_notoc)
- {
- if (stub_entry->h != NULL
- && (stub_entry->h == htab->tls_get_addr_fd
- || stub_entry->h == htab->tls_get_addr)
- && htab->params->tls_get_addr_opt
- && stub_entry->stub_type == ppc_stub_plt_call_r2save)
- stub_entry->group->tls_get_addr_opt_bctrl
- = stub_entry->stub_offset + size - 5 * 4;
-
- if (info->emitrelocations)
- {
- stub_entry->group->stub_sec->reloc_count
- += ((PPC_HA (off) != 0)
- + (htab->opd_abi
- ? 2 + (htab->params->plt_static_chain
- && PPC_HA (off + 16) == PPC_HA (off))
- : 1));
- stub_entry->group->stub_sec->flags |= SEC_RELOC;
- }
- }
- }
- else
+ switch (stub_entry->stub_type)
{
- /* ppc_stub_long_branch or ppc_stub_plt_branch, or their r2off
- variants. */
- bfd_vma r2off = 0;
- bfd_vma local_off = 0;
-
+ case ppc_stub_plt_branch:
+ case ppc_stub_plt_branch_r2off:
+ /* Reset the stub type from the plt branch variant in case we now
+ can reach with a shorter stub. */
+ stub_entry->stub_type += ppc_stub_long_branch - ppc_stub_plt_branch;
+ /* Fall through. */
+ case ppc_stub_long_branch:
+ case ppc_stub_long_branch_r2off:
targ = (stub_entry->target_value
+ stub_entry->target_section->output_offset
+ stub_entry->target_section->output_section->vma);
+ targ += PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
off = (stub_entry->stub_offset
+ stub_entry->group->stub_sec->output_offset
+ stub_entry->group->stub_sec->output_section->vma);
- /* Reset the stub type from the plt variant in case we now
- can reach with a shorter stub. */
- if (stub_entry->stub_type >= ppc_stub_plt_branch)
- stub_entry->stub_type += ppc_stub_long_branch - ppc_stub_plt_branch;
-
size = 4;
+ r2off = 0;
if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
{
r2off = get_r2off (info, stub_entry);
size += 4;
off += size - 4;
}
- else if (stub_entry->stub_type >= ppc_stub_long_branch_notoc)
- {
- size = 20 + size_offset (targ - (off + 8));
- if (stub_entry->stub_type > ppc_stub_long_branch_notoc)
- size += 4;
- off += size - 4;
- }
off = targ - off;
- if (stub_entry->stub_type >= ppc_stub_long_branch_notoc)
+ /* If the branch offset is too big, use a ppc_stub_plt_branch.
+ Do the same for -R objects without function descriptors. */
+ if ((stub_entry->stub_type == ppc_stub_long_branch_r2off
+ && r2off == 0
+ && htab->sec_info[stub_entry->target_section->id].toc_off == 0)
+ || off + (1 << 25) >= (bfd_vma) (1 << 26))
{
- if (off + (1 << 25) >= (bfd_vma) (1 << 26))
+ struct ppc_branch_hash_entry *br_entry;
+
+ br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
+ stub_entry->root.string + 9,
+ TRUE, FALSE);
+ if (br_entry == NULL)
{
- stub_entry->stub_type += (ppc_stub_plt_branch_notoc
- - ppc_stub_long_branch_notoc);
- size += 4;
+ _bfd_error_handler (_("can't build branch stub `%s'"),
+ stub_entry->root.string);
+ htab->stub_error = TRUE;
+ return FALSE;
}
- }
- else
- {
- local_off = PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
-
- /* If the branch offset is too big, use a ppc_stub_plt_branch.
- Do the same for -R objects without function descriptors. */
- if ((stub_entry->stub_type == ppc_stub_long_branch_r2off
- && r2off == 0
- && htab->sec_info[stub_entry->target_section->id].toc_off == 0)
- || off + (1 << 25) >= (bfd_vma) (1 << 26) - local_off)
- {
- struct ppc_branch_hash_entry *br_entry;
- br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
- stub_entry->root.string + 9,
- TRUE, FALSE);
- if (br_entry == NULL)
- {
- _bfd_error_handler (_("can't build branch stub `%s'"),
- stub_entry->root.string);
- htab->stub_error = TRUE;
- return FALSE;
- }
+ if (br_entry->iter != htab->stub_iteration)
+ {
+ br_entry->iter = htab->stub_iteration;
+ br_entry->offset = htab->brlt->size;
+ htab->brlt->size += 8;
- if (br_entry->iter != htab->stub_iteration)
+ if (htab->relbrlt != NULL)
+ htab->relbrlt->size += sizeof (Elf64_External_Rela);
+ else if (info->emitrelocations)
{
- br_entry->iter = htab->stub_iteration;
- br_entry->offset = htab->brlt->size;
- htab->brlt->size += 8;
-
- if (htab->relbrlt != NULL)
- htab->relbrlt->size += sizeof (Elf64_External_Rela);
- else if (info->emitrelocations)
- {
- htab->brlt->reloc_count += 1;
- htab->brlt->flags |= SEC_RELOC;
- }
+ htab->brlt->reloc_count += 1;
+ htab->brlt->flags |= SEC_RELOC;
}
+ }
- targ = (br_entry->offset
- + htab->brlt->output_offset
- + htab->brlt->output_section->vma);
- off = (elf_gp (info->output_bfd)
- + htab->sec_info[stub_entry->group->link_sec->id].toc_off);
- off = targ - off;
+ targ = (br_entry->offset
+ + htab->brlt->output_offset
+ + htab->brlt->output_section->vma);
+ off = (elf_gp (info->output_bfd)
+ + htab->sec_info[stub_entry->group->link_sec->id].toc_off);
+ off = targ - off;
- if (info->emitrelocations)
- {
- stub_entry->group->stub_sec->reloc_count
- += 1 + (PPC_HA (off) != 0);
- stub_entry->group->stub_sec->flags |= SEC_RELOC;
- }
+ if (info->emitrelocations)
+ {
+ stub_entry->group->stub_sec->reloc_count
+ += 1 + (PPC_HA (off) != 0);
+ stub_entry->group->stub_sec->flags |= SEC_RELOC;
+ }
- stub_entry->stub_type
- += ppc_stub_plt_branch - ppc_stub_long_branch;
- if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
- {
- size = 12;
- if (PPC_HA (off) != 0)
- size = 16;
- }
- else
- {
- size = 16;
- if (PPC_HA (off) != 0)
- size += 4;
-
- if (PPC_HA (r2off) != 0)
- size += 4;
- if (PPC_LO (r2off) != 0)
- size += 4;
- }
+ stub_entry->stub_type += ppc_stub_plt_branch - ppc_stub_long_branch;
+ if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
+ {
+ size = 12;
+ if (PPC_HA (off) != 0)
+ size = 16;
}
- else if (info->emitrelocations)
+ else
{
- stub_entry->group->stub_sec->reloc_count += 1;
- stub_entry->group->stub_sec->flags |= SEC_RELOC;
+ size = 16;
+ if (PPC_HA (off) != 0)
+ size += 4;
+
+ if (PPC_HA (r2off) != 0)
+ size += 4;
+ if (PPC_LO (r2off) != 0)
+ size += 4;
}
}
+ else if (info->emitrelocations)
+ {
+ stub_entry->group->stub_sec->reloc_count += 1;
+ stub_entry->group->stub_sec->flags |= SEC_RELOC;
+ }
+ break;
+
+ case ppc_stub_plt_branch_notoc:
+ case ppc_stub_plt_branch_both:
+ stub_entry->stub_type += ppc_stub_long_branch - ppc_stub_plt_branch;
+ /* Fall through. */
+ case ppc_stub_long_branch_notoc:
+ case ppc_stub_long_branch_both:
+ off = (stub_entry->stub_offset
+ + stub_entry->group->stub_sec->output_offset
+ + stub_entry->group->stub_sec->output_section->vma);
+ size = 0;
+ if (stub_entry->stub_type == ppc_stub_long_branch_both)
+ size = 4;
+ off += size;
+ targ = (stub_entry->target_value
+ + stub_entry->target_section->output_offset
+ + stub_entry->target_section->output_section->vma);
+ off = targ - off;
+
+ extra = size_offset (off - 8);
+ /* Include branch insn plus those in the offset sequence. */
+ size += 4 + extra;
+ /* The branch insn is at the end, or "extra" bytes along. So
+ its offset will be "extra" bytes less that that already
+ calculated. */
+ off -= extra;
+
+ /* After the bcl, lr has been modified so we need to emit
+ .eh_frame info saying the return address is in r12. */
+ lr_used = stub_entry->stub_offset + 8;
+ if (stub_entry->stub_type == ppc_stub_long_branch_both)
+ lr_used += 4;
+ /* The eh_frame info will consist of a DW_CFA_advance_loc or
+ variant, DW_CFA_register, 65, 12, DW_CFA_advance_loc+2,
+ DW_CFA_restore_extended 65. */
+ delta = lr_used - stub_entry->group->lr_restore;
+ stub_entry->group->eh_size += eh_advance_size (delta) + 6;
+ stub_entry->group->lr_restore = lr_used + 8;
+
+ /* If the branch can't reach, use a plt_branch. */
+ if (off + (1 << 25) >= (bfd_vma) (1 << 26))
+ {
+ stub_entry->stub_type += (ppc_stub_plt_branch_notoc
+ - ppc_stub_long_branch_notoc);
+ size += 4;
+ }
+ break;
+
+ case ppc_stub_plt_call_notoc:
+ case ppc_stub_plt_call_both:
+ off = (stub_entry->stub_offset
+ + stub_entry->group->stub_sec->output_offset
+ + stub_entry->group->stub_sec->output_section->vma);
+ if (stub_entry->stub_type == ppc_stub_plt_call_both)
+ off += 4;
+ targ = stub_entry->plt_ent->plt.offset & ~1;
+ if (targ >= (bfd_vma) -2)
+ abort ();
+
+ plt = htab->elf.splt;
+ if (!htab->elf.dynamic_sections_created
+ || stub_entry->h == NULL
+ || stub_entry->h->elf.dynindx == -1)
+ {
+ if (stub_entry->symtype == STT_GNU_IFUNC)
+ plt = htab->elf.iplt;
+ else
+ plt = htab->pltlocal;
+ }
+ targ += plt->output_offset + plt->output_section->vma;
+ off = targ - off;
+
+ if (htab->params->plt_stub_align != 0)
+ {
+ unsigned pad = plt_stub_pad (htab, stub_entry, off);
+
+ stub_entry->group->stub_sec->size += pad;
+ stub_entry->stub_offset = stub_entry->group->stub_sec->size;
+ off -= pad;
+ }
+
+ size = plt_stub_size (htab, stub_entry, off);
+
+ /* After the bcl, lr has been modified so we need to emit
+ .eh_frame info saying the return address is in r12. */
+ lr_used = stub_entry->stub_offset + 8;
+ if (stub_entry->stub_type == ppc_stub_plt_call_both)
+ lr_used += 4;
+ /* The eh_frame info will consist of a DW_CFA_advance_loc or
+ variant, DW_CFA_register, 65, 12, DW_CFA_advance_loc+2,
+ DW_CFA_restore_extended 65. */
+ delta = lr_used - stub_entry->group->lr_restore;
+ stub_entry->group->eh_size += eh_advance_size (delta) + 6;
+ stub_entry->group->lr_restore = lr_used + 8;
+ break;
+
+ case ppc_stub_plt_call:
+ case ppc_stub_plt_call_r2save:
+ targ = stub_entry->plt_ent->plt.offset & ~(bfd_vma) 1;
+ if (targ >= (bfd_vma) -2)
+ abort ();
+ plt = htab->elf.splt;
+ if (!htab->elf.dynamic_sections_created
+ || stub_entry->h == NULL
+ || stub_entry->h->elf.dynindx == -1)
+ {
+ if (stub_entry->symtype == STT_GNU_IFUNC)
+ plt = htab->elf.iplt;
+ else
+ plt = htab->pltlocal;
+ }
+ targ += plt->output_offset + plt->output_section->vma;
+
+ off = (elf_gp (info->output_bfd)
+ + htab->sec_info[stub_entry->group->link_sec->id].toc_off);
+ off = targ - off;
+
+ if (htab->params->plt_stub_align != 0)
+ {
+ unsigned pad = plt_stub_pad (htab, stub_entry, off);
+
+ stub_entry->group->stub_sec->size += pad;
+ stub_entry->stub_offset = stub_entry->group->stub_sec->size;
+ }
+
+ if (info->emitrelocations)
+ {
+ stub_entry->group->stub_sec->reloc_count
+ += ((PPC_HA (off) != 0)
+ + (htab->opd_abi
+ ? 2 + (htab->params->plt_static_chain
+ && PPC_HA (off + 16) == PPC_HA (off))
+ : 1));
+ stub_entry->group->stub_sec->flags |= SEC_RELOC;
+ }
+
+ size = plt_stub_size (htab, stub_entry, off);
+
+ if (stub_entry->h != NULL
+ && (stub_entry->h == htab->tls_get_addr_fd
+ || stub_entry->h == htab->tls_get_addr)
+ && htab->params->tls_get_addr_opt
+ && stub_entry->stub_type == ppc_stub_plt_call_r2save)
+ {
+ /* After the bctrl, lr has been modified so we need to
+ emit .eh_frame info saying the return address is
+ on the stack. In fact we put the EH info specifying
+ that the return address is on the stack *at* the
+ call rather than after it, because the EH info for a
+ call needs to be specified by that point.
+ See libgcc/unwind-dw2.c execute_cfa_program. */
+ lr_used = stub_entry->stub_offset + size - 20;
+ /* The eh_frame info will consist of a DW_CFA_advance_loc
+ or variant, DW_CFA_offset_externed_sf, 65, -stackoff,
+ DW_CFA_advance_loc+4, DW_CFA_restore_extended, 65. */
+ delta = lr_used - stub_entry->group->lr_restore;
+ stub_entry->group->eh_size += eh_advance_size (delta) + 6;
+ stub_entry->group->lr_restore = size - 4;
+ }
+ break;
+
+ default:
+ BFD_FAIL ();
+ return FALSE;
}
stub_entry->group->stub_sec->size += size;
group->link_sec = curr;
group->stub_sec = NULL;
group->needs_save_res = 0;
- group->tls_get_addr_opt_bctrl = -1u;
+ group->lr_restore = 0;
+ group->eh_size = 0;
+ group->eh_base = 0;
group->next = htab->group;
htab->group = group;
do
&& ((total += tail->output_offset - prev->output_offset)
< (ppc64_elf_section_data (prev) != NULL
&& ppc64_elf_section_data (prev)->has_14bit_branch
- ? (group_size = stub_group_size >> 10) : group_size))
+ ? (group_size = stub_group_size >> 10)
+ : group_size))
&& htab->sec_info[prev->id].toc_off == curr_toc)
{
tail = prev;
DW_CFA_def_cfa, 1, 0 /* def_cfa: r1 offset 0. */
};
-static size_t
-stub_eh_frame_size (struct map_stub *group, size_t align)
-{
- size_t this_size = 17;
- if (group->tls_get_addr_opt_bctrl != -1u)
- {
- unsigned int to_bctrl = group->tls_get_addr_opt_bctrl / 4;
- if (to_bctrl < 64)
- this_size += 1;
- else if (to_bctrl < 256)
- this_size += 2;
- else if (to_bctrl < 65536)
- this_size += 3;
- else
- this_size += 5;
- this_size += 6;
- }
- this_size = (this_size + align - 1) & -align;
- return this_size;
-}
-
/* Stripping output sections is normally done before dynamic section
symbols have been allocated. This function is called later, and
handles cases like htab->brlt which is mapped to its own output
/* We may have added some stubs. Find out the new size of the
stub sections. */
for (group = htab->group; group != NULL; group = group->next)
- if (group->stub_sec != NULL)
- {
- asection *stub_sec = group->stub_sec;
-
- if (htab->stub_iteration <= STUB_SHRINK_ITER
- || stub_sec->rawsize < stub_sec->size)
- /* Past STUB_SHRINK_ITER, rawsize is the max size seen. */
- stub_sec->rawsize = stub_sec->size;
- stub_sec->size = 0;
- stub_sec->reloc_count = 0;
- stub_sec->flags &= ~SEC_RELOC;
- }
+ {
+ group->lr_restore = 0;
+ group->eh_size = 0;
+ if (group->stub_sec != NULL)
+ {
+ asection *stub_sec = group->stub_sec;
+
+ if (htab->stub_iteration <= STUB_SHRINK_ITER
+ || stub_sec->rawsize < stub_sec->size)
+ /* Past STUB_SHRINK_ITER, rawsize is the max size seen. */
+ stub_sec->rawsize = stub_sec->size;
+ stub_sec->size = 0;
+ stub_sec->reloc_count = 0;
+ stub_sec->flags &= ~SEC_RELOC;
+ }
+ }
if (htab->stub_iteration <= STUB_SHRINK_ITER
|| htab->brlt->rawsize < htab->brlt->size)
size_t size = 0, align = 4;
for (group = htab->group; group != NULL; group = group->next)
- if (group->stub_sec != NULL)
- size += stub_eh_frame_size (group, align);
+ if (group->eh_size != 0)
+ size += (group->eh_size + 17 + align - 1) & -align;
if (htab->glink != NULL && htab->glink->size != 0)
size += (24 + align - 1) & -align;
if (size != 0)
size_t last_fde_len, size, align, pad;
struct map_stub *group;
+ /* It is necessary to at least have a rough outline of the
+ linker generated CIEs and FDEs written before
+ bfd_elf_discard_info is run, in order for these FDEs to be
+ indexed in .eh_frame_hdr. */
p = bfd_zalloc (htab->glink_eh_frame->owner, htab->glink_eh_frame->size);
if (p == NULL)
return FALSE;
p += last_fde_len + 4;
for (group = htab->group; group != NULL; group = group->next)
- if (group->stub_sec != NULL)
+ if (group->eh_size != 0)
{
+ group->eh_base = p - htab->glink_eh_frame->contents;
last_fde = p;
- last_fde_len = stub_eh_frame_size (group, align) - 4;
+ last_fde_len = ((group->eh_size + 17 + align - 1) & -align) - 4;
/* FDE length. */
bfd_put_32 (htab->elf.dynobj, last_fde_len, p);
p += 4;
p += 4;
/* Augmentation. */
p += 1;
- if (group->tls_get_addr_opt_bctrl != -1u)
- {
- unsigned int to_bctrl = group->tls_get_addr_opt_bctrl / 4;
-
- /* This FDE needs more than just the default.
- Describe __tls_get_addr_opt stub LR. */
- if (to_bctrl < 64)
- *p++ = DW_CFA_advance_loc + to_bctrl;
- else if (to_bctrl < 256)
- {
- *p++ = DW_CFA_advance_loc1;
- *p++ = to_bctrl;
- }
- else if (to_bctrl < 65536)
- {
- *p++ = DW_CFA_advance_loc2;
- bfd_put_16 (htab->elf.dynobj, to_bctrl, p);
- p += 2;
- }
- else
- {
- *p++ = DW_CFA_advance_loc4;
- bfd_put_32 (htab->elf.dynobj, to_bctrl, p);
- p += 4;
- }
- *p++ = DW_CFA_offset_extended_sf;
- *p++ = 65;
- *p++ = -(STK_LINKER (htab) / 8) & 0x7f;
- *p++ = DW_CFA_advance_loc + 4;
- *p++ = DW_CFA_restore_extended;
- *p++ = 65;
- }
- /* Pad. */
+ /* Make sure we don't have all nops. This is enough for
+ elf-eh-frame.c to detect the last non-nop opcode. */
+ p[group->eh_size - 1] = DW_CFA_advance_loc + 1;
p = last_fde + last_fde_len + 4;
}
if (htab->glink != NULL && htab->glink->size != 0)
/* Allocate memory to hold the linker stubs. */
for (group = htab->group; group != NULL; group = group->next)
- if ((stub_sec = group->stub_sec) != NULL
- && stub_sec->size != 0)
- {
- stub_sec->contents = bfd_zalloc (htab->params->stub_bfd, stub_sec->size);
- if (stub_sec->contents == NULL)
- return FALSE;
- stub_sec->size = 0;
- }
+ {
+ group->eh_size = 0;
+ group->lr_restore = 0;
+ if ((stub_sec = group->stub_sec) != NULL
+ && stub_sec->size != 0)
+ {
+ stub_sec->contents = bfd_zalloc (htab->params->stub_bfd,
+ stub_sec->size);
+ if (stub_sec->contents == NULL)
+ return FALSE;
+ stub_sec->size = 0;
+ }
+ }
if (htab->glink != NULL && htab->glink->size != 0)
{
}
}
+ if (htab->glink_eh_frame != NULL
+ && htab->glink_eh_frame->size != 0)
+ {
+ bfd_vma val;
+ size_t align = 4;
+
+ p = htab->glink_eh_frame->contents;
+ p += (sizeof (glink_eh_frame_cie) + align - 1) & -align;
+
+ for (group = htab->group; group != NULL; group = group->next)
+ if (group->eh_size != 0)
+ {
+ /* Offset to stub section. */
+ val = (group->stub_sec->output_section->vma
+ + group->stub_sec->output_offset);
+ val -= (htab->glink_eh_frame->output_section->vma
+ + htab->glink_eh_frame->output_offset
+ + (p + 8 - htab->glink_eh_frame->contents));
+ if (val + 0x80000000 > 0xffffffff)
+ {
+ _bfd_error_handler
+ (_("%s offset too large for .eh_frame sdata4 encoding"),
+ group->stub_sec->name);
+ return FALSE;
+ }
+ bfd_put_32 (htab->elf.dynobj, val, p + 8);
+ p += (group->eh_size + 17 + 3) & -4;
+ }
+ if (htab->glink != NULL && htab->glink->size != 0)
+ {
+ /* Offset to .glink. */
+ val = (htab->glink->output_section->vma
+ + htab->glink->output_offset
+ + 8);
+ val -= (htab->glink_eh_frame->output_section->vma
+ + htab->glink_eh_frame->output_offset
+ + (p + 8 - htab->glink_eh_frame->contents));
+ if (val + 0x80000000 > 0xffffffff)
+ {
+ _bfd_error_handler
+ (_("%s offset too large for .eh_frame sdata4 encoding"),
+ htab->glink->name);
+ return FALSE;
+ }
+ bfd_put_32 (htab->elf.dynobj, val, p + 8);
+ p += (24 + align - 1) & -align;
+ }
+ }
+
for (group = htab->group; group != NULL; group = group->next)
if ((stub_sec = group->stub_sec) != NULL)
{
stub_entry = NULL;
if (stub_entry != NULL
- && (stub_entry->stub_type == ppc_stub_plt_call
- || stub_entry->stub_type == ppc_stub_plt_call_r2save
- || stub_entry->stub_type == ppc_stub_plt_call_both
+ && ((stub_entry->stub_type >= ppc_stub_plt_call
+ && stub_entry->stub_type <= ppc_stub_plt_call_both)
|| stub_entry->stub_type == ppc_stub_plt_branch_r2off
|| stub_entry->stub_type == ppc_stub_plt_branch_both
|| stub_entry->stub_type == ppc_stub_long_branch_r2off
info->callbacks->einfo
/* xgettext:c-format */
(_("%H: call to `%pT' lacks nop, can't restore toc; "
- "recompile with -fPIC\n"),
+ "(plt call stub)\n"),
input_bfd, input_section, rel->r_offset, sym_name);
else
info->callbacks->einfo
/* xgettext:c-format */
(_("%H: call to `%pT' lacks nop, can't restore toc; "
- "(-mcmodel=small toc adjust stub)\n"),
+ "(toc save/adjust stub)\n"),
input_bfd, input_section, rel->r_offset, sym_name);
bfd_set_error (bfd_error_bad_value);
+ plt->output_offset
+ ent->plt.offset);
if (r_type == R_PPC64_PLT16_HA
- || r_type ==R_PPC64_PLT16_HI
- || r_type ==R_PPC64_PLT16_LO
- || r_type ==R_PPC64_PLT16_LO_DS)
+ || r_type == R_PPC64_PLT16_HI
+ || r_type == R_PPC64_PLT16_LO
+ || r_type == R_PPC64_PLT16_LO_DS)
{
got = (elf_gp (output_bfd)
+ htab->sec_info[input_section->id].toc_off);
case R_PPC64_REL16_LO:
case R_PPC64_REL16_HI:
case R_PPC64_REL16_HA:
+ case R_PPC64_REL16_HIGH:
+ case R_PPC64_REL16_HIGHA:
+ case R_PPC64_REL16_HIGHER:
+ case R_PPC64_REL16_HIGHERA:
+ case R_PPC64_REL16_HIGHEST:
+ case R_PPC64_REL16_HIGHESTA:
case R_PPC64_REL16DX_HA:
break;
be computed at runtime, so there's no need to do
anything now. However, for the sake of prelink ensure
that the section contents are a known value. */
- if (! relocate)
+ if (!relocate)
{
unresolved_reloc = FALSE;
/* The value chosen here is quite arbitrary as ld.so
break;
case R_PPC64_REL16_HA:
+ case R_PPC64_REL16_HIGHA:
+ case R_PPC64_REL16_HIGHERA:
+ case R_PPC64_REL16_HIGHESTA:
case R_PPC64_REL16DX_HA:
case R_PPC64_ADDR16_HA:
case R_PPC64_ADDR16_HIGHA:
htab->elf.sgot->contents);
/* Set .got entry size. */
- elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 8;
+ elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
+ = 8;
}
if (htab->elf.splt != NULL && htab->elf.splt->size != 0
NULL))
return FALSE;
- if (htab->glink_eh_frame != NULL
- && htab->glink_eh_frame->size != 0)
- {
- bfd_vma val;
- bfd_byte *p;
- struct map_stub *group;
- size_t align = 4;
-
- p = htab->glink_eh_frame->contents;
- p += (sizeof (glink_eh_frame_cie) + align - 1) & -align;
-
- for (group = htab->group; group != NULL; group = group->next)
- if (group->stub_sec != NULL)
- {
- /* Offset to stub section. */
- val = (group->stub_sec->output_section->vma
- + group->stub_sec->output_offset);
- val -= (htab->glink_eh_frame->output_section->vma
- + htab->glink_eh_frame->output_offset
- + (p + 8 - htab->glink_eh_frame->contents));
- if (val + 0x80000000 > 0xffffffff)
- {
- _bfd_error_handler
- (_("%s offset too large for .eh_frame sdata4 encoding"),
- group->stub_sec->name);
- return FALSE;
- }
- bfd_put_32 (dynobj, val, p + 8);
- p += stub_eh_frame_size (group, align);
- }
- if (htab->glink != NULL && htab->glink->size != 0)
- {
- /* Offset to .glink. */
- val = (htab->glink->output_section->vma
- + htab->glink->output_offset
- + 8);
- val -= (htab->glink_eh_frame->output_section->vma
- + htab->glink_eh_frame->output_offset
- + (p + 8 - htab->glink_eh_frame->contents));
- if (val + 0x80000000 > 0xffffffff)
- {
- _bfd_error_handler
- (_("%s offset too large for .eh_frame sdata4 encoding"),
- htab->glink->name);
- return FALSE;
- }
- bfd_put_32 (dynobj, val, p + 8);
- p += (24 + align - 1) & -align;
- }
- if (htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
- && !_bfd_elf_write_section_eh_frame (output_bfd, info,
- htab->glink_eh_frame,
- htab->glink_eh_frame->contents))
- return FALSE;
- }
+ if (htab->glink_eh_frame != NULL
+ && htab->glink_eh_frame->size != 0
+ && htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
+ && !_bfd_elf_write_section_eh_frame (output_bfd, info,
+ htab->glink_eh_frame,
+ htab->glink_eh_frame->contents))
+ return FALSE;
/* We need to handle writing out multiple GOT sections ourselves,
since we didn't add them to DYNOBJ. We know dynobj is the first