/* Meta support for 32-bit ELF
- Copyright (C) 2013-2015 Free Software Foundation, Inc.
+ Copyright (C) 2013-2021 Free Software Foundation, Inc.
Contributed by Imagination Technologies Ltd.
This file is part of BFD, the Binary File Descriptor library.
/* Variable names follow a coding style.
Please follow this (Apps Hungarian) style:
- Structure/Variable Prefix
- elf_link_hash_table "etab"
- elf_link_hash_entry "eh"
+ Structure/Variable Prefix
+ elf_link_hash_table "etab"
+ elf_link_hash_entry "eh"
- elf_metag_link_hash_table "htab"
- elf_metag_link_hash_entry "hh"
+ elf_metag_link_hash_table "htab"
+ elf_metag_link_hash_entry "hh"
- bfd_link_hash_table "btab"
- bfd_link_hash_entry "bh"
+ bfd_link_hash_table "btab"
+ bfd_link_hash_entry "bh"
bfd_hash_table containing stubs "bstab"
- elf_metag_stub_hash_entry "hsh"
-
- elf_metag_dyn_reloc_entry "hdh"
+ elf_metag_stub_hash_entry "hsh"
Always remember to use GNU Coding Style. */
16, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_HIADDR16", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* Low order 16 bit absolute. */
HOWTO (R_METAG_LOADDR16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_LOADDR16", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* 32 bit absolute. */
HOWTO (R_METAG_ADDR32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_ADDR32", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0x00000000, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* No relocation. */
HOWTO (R_METAG_NONE, /* type */
0, /* rightshift */
3, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_NONE", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* 19 bit pc relative */
HOWTO (R_METAG_RELBRANCH, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
19, /* bitsize */
- TRUE, /* pc_relative */
+ true, /* pc_relative */
5, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_RELBRANCH", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x00ffffe0, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* GET/SET offset */
HOWTO (R_METAG_GETSETOFF, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
7, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_GETSETOFF", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
EMPTY_HOWTO (6),
EMPTY_HOWTO (7),
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
NULL, /* special_function */
"R_METAG_GNU_VTINHERIT", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_GNU_VTENTRY, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_elf_rel_vtable_reloc_fn, /* special_function */
"R_METAG_GNU_VTENTRY", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* High order 16 bit GOT offset */
HOWTO (R_METAG_HI16_GOTOFF, /* type */
16, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_HI16_GOTOFF", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* Low order 16 bit GOT offset */
HOWTO (R_METAG_LO16_GOTOFF, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_LO16_GOTOFF", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* GET/SET GOT offset */
HOWTO (R_METAG_GETSET_GOTOFF, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
7, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_GETSET_GOTOFF", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* GET/SET GOT relative */
HOWTO (R_METAG_GETSET_GOT, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
7, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_GETSET_GOT", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* High order 16 bit GOT reference */
HOWTO (R_METAG_HI16_GOTPC, /* type */
16, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_HI16_GOTPC", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* Low order 16 bit GOT reference */
HOWTO (R_METAG_LO16_GOTPC, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_LO16_GOTPC", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* High order 16 bit PLT */
HOWTO (R_METAG_HI16_PLT, /* type */
16, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_HI16_PLT", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* Low order 16 bit PLT */
HOWTO (R_METAG_LO16_PLT, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_LO16_PLT", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_RELBRANCH_PLT, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
19, /* bitsize */
- TRUE, /* pc_relative */
+ true, /* pc_relative */
5, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_RELBRANCH_PLT", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x00ffffe0, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* Dummy relocs used by the linker internally. */
HOWTO (R_METAG_GOTOFF, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_GOTOFF", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_PLT, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_GOTOFF", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* This is used only by the dynamic linker. The symbol should exist
both in the object being run and in some shared library. The
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_COPY", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* Marks a procedure linkage table entry for a symbol. */
HOWTO (R_METAG_JMP_SLOT, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_JMP_SLOT", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* Used only by the dynamic linker. When the object is run, this
longword is set to the load address of the object, plus the
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_RELATIVE", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_GLOB_DAT, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_GLOB_DAT", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_TLS_GD, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_GD", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_TLS_LDM, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_LDM", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_TLS_LDO_HI16, /* type */
16, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_LDO_HI16", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_TLS_LDO_LO16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_LDO_LO16", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* Dummy reloc used by the linker internally. */
HOWTO (R_METAG_TLS_LDO, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_LDO", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_TLS_IE, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
12, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
7, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_IE", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007ff80, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* Dummy reloc used by the linker internally. */
HOWTO (R_METAG_TLS_IENONPIC, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_IENONPIC", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_TLS_IENONPIC_HI16,/* type */
16, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_IENONPIC_HI16", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_TLS_IENONPIC_LO16,/* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_IENONPIC_LO16", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_TLS_TPOFF, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_TPOFF", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_TLS_DTPMOD, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_DTPMOD", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_TLS_DTPOFF, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_DTPOFF", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* Dummy reloc used by the linker internally. */
HOWTO (R_METAG_TLS_LE, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_LE", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_TLS_LE_HI16, /* type */
16, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_LE_HI16", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
HOWTO (R_METAG_TLS_LE_LO16, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
3, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_METAG_TLS_LE_LO16", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0x0007fff8, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
};
static const struct metag_reloc_map metag_reloc_map [] =
{
- { BFD_RELOC_NONE, R_METAG_NONE },
- { BFD_RELOC_32, R_METAG_ADDR32 },
- { BFD_RELOC_METAG_HIADDR16, R_METAG_HIADDR16 },
- { BFD_RELOC_METAG_LOADDR16, R_METAG_LOADDR16 },
+ { BFD_RELOC_NONE, R_METAG_NONE },
+ { BFD_RELOC_32, R_METAG_ADDR32 },
+ { BFD_RELOC_METAG_HIADDR16, R_METAG_HIADDR16 },
+ { BFD_RELOC_METAG_LOADDR16, R_METAG_LOADDR16 },
{ BFD_RELOC_METAG_RELBRANCH, R_METAG_RELBRANCH },
{ BFD_RELOC_METAG_GETSETOFF, R_METAG_GETSETOFF },
- { BFD_RELOC_VTABLE_INHERIT, R_METAG_GNU_VTINHERIT },
- { BFD_RELOC_VTABLE_ENTRY, R_METAG_GNU_VTENTRY },
- { BFD_RELOC_METAG_REL8, R_METAG_REL8 },
- { BFD_RELOC_METAG_REL16, R_METAG_REL16 },
+ { BFD_RELOC_VTABLE_INHERIT, R_METAG_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_METAG_GNU_VTENTRY },
+ { BFD_RELOC_METAG_REL8, R_METAG_REL8 },
+ { BFD_RELOC_METAG_REL16, R_METAG_REL16 },
{ BFD_RELOC_METAG_HI16_GOTOFF, R_METAG_HI16_GOTOFF },
{ BFD_RELOC_METAG_LO16_GOTOFF, R_METAG_LO16_GOTOFF },
{ BFD_RELOC_METAG_GETSET_GOTOFF, R_METAG_GETSET_GOTOFF },
{ BFD_RELOC_METAG_GETSET_GOT, R_METAG_GETSET_GOT },
{ BFD_RELOC_METAG_HI16_GOTPC, R_METAG_HI16_GOTPC },
{ BFD_RELOC_METAG_LO16_GOTPC, R_METAG_LO16_GOTPC },
- { BFD_RELOC_METAG_HI16_PLT, R_METAG_HI16_PLT },
- { BFD_RELOC_METAG_LO16_PLT, R_METAG_LO16_PLT },
+ { BFD_RELOC_METAG_HI16_PLT, R_METAG_HI16_PLT },
+ { BFD_RELOC_METAG_LO16_PLT, R_METAG_LO16_PLT },
{ BFD_RELOC_METAG_RELBRANCH_PLT, R_METAG_RELBRANCH_PLT },
- { BFD_RELOC_METAG_GOTOFF, R_METAG_GOTOFF },
- { BFD_RELOC_METAG_PLT, R_METAG_PLT },
- { BFD_RELOC_METAG_COPY, R_METAG_COPY },
- { BFD_RELOC_METAG_JMP_SLOT, R_METAG_JMP_SLOT },
- { BFD_RELOC_METAG_RELATIVE, R_METAG_RELATIVE },
- { BFD_RELOC_METAG_GLOB_DAT, R_METAG_GLOB_DAT },
- { BFD_RELOC_METAG_TLS_GD, R_METAG_TLS_GD },
- { BFD_RELOC_METAG_TLS_LDM, R_METAG_TLS_LDM },
+ { BFD_RELOC_METAG_GOTOFF, R_METAG_GOTOFF },
+ { BFD_RELOC_METAG_PLT, R_METAG_PLT },
+ { BFD_RELOC_METAG_COPY, R_METAG_COPY },
+ { BFD_RELOC_METAG_JMP_SLOT, R_METAG_JMP_SLOT },
+ { BFD_RELOC_METAG_RELATIVE, R_METAG_RELATIVE },
+ { BFD_RELOC_METAG_GLOB_DAT, R_METAG_GLOB_DAT },
+ { BFD_RELOC_METAG_TLS_GD, R_METAG_TLS_GD },
+ { BFD_RELOC_METAG_TLS_LDM, R_METAG_TLS_LDM },
{ BFD_RELOC_METAG_TLS_LDO_HI16, R_METAG_TLS_LDO_HI16 },
{ BFD_RELOC_METAG_TLS_LDO_LO16, R_METAG_TLS_LDO_LO16 },
- { BFD_RELOC_METAG_TLS_LDO, R_METAG_TLS_LDO },
- { BFD_RELOC_METAG_TLS_IE, R_METAG_TLS_IE },
+ { BFD_RELOC_METAG_TLS_LDO, R_METAG_TLS_LDO },
+ { BFD_RELOC_METAG_TLS_IE, R_METAG_TLS_IE },
{ BFD_RELOC_METAG_TLS_IENONPIC, R_METAG_TLS_IENONPIC },
{ BFD_RELOC_METAG_TLS_IENONPIC_HI16, R_METAG_TLS_IENONPIC_HI16 },
{ BFD_RELOC_METAG_TLS_IENONPIC_LO16, R_METAG_TLS_IENONPIC_LO16 },
{ BFD_RELOC_METAG_TLS_TPOFF, R_METAG_TLS_TPOFF },
{ BFD_RELOC_METAG_TLS_DTPMOD, R_METAG_TLS_DTPMOD },
{ BFD_RELOC_METAG_TLS_DTPOFF, R_METAG_TLS_DTPOFF },
- { BFD_RELOC_METAG_TLS_LE, R_METAG_TLS_LE },
+ { BFD_RELOC_METAG_TLS_LE, R_METAG_TLS_LE },
{ BFD_RELOC_METAG_TLS_LE_HI16, R_METAG_TLS_LE_HI16 },
{ BFD_RELOC_METAG_TLS_LE_LO16, R_METAG_TLS_LE_LO16 },
};
symbol. */
struct elf_metag_stub_hash_entry *hsh_cache;
- /* Used to count relocations for delayed sizing of relocation
- sections. */
- struct elf_metag_dyn_reloc_entry {
-
- /* Next relocation in the chain. */
- struct elf_metag_dyn_reloc_entry *hdh_next;
-
- /* The input section of the reloc. */
- asection *sec;
-
- /* Number of relocs copied in this section. */
- bfd_size_type count;
-
- /* Number of relative relocs copied for the input section. */
- bfd_size_type relative_count;
- } *dyn_relocs;
-
enum
{
GOT_UNKNOWN = 0, GOT_NORMAL = 1, GOT_TLS_IE = 2, GOT_TLS_LDM = 4, GOT_TLS_GD = 8
/* Assorted information used by elf_metag_size_stubs. */
unsigned int bfd_count;
- int top_index;
+ unsigned int top_index;
asection **input_list;
Elf_Internal_Sym **all_local_syms;
- /* Short-cuts to get to dynamic linker sections. */
- asection *sgot;
- asection *sgotplt;
- asection *srelgot;
- asection *splt;
- asection *srelplt;
- asection *sdynbss;
- asection *srelbss;
-
- /* Small local sym cache. */
- struct sym_cache sym_cache;
-
/* Data for LDM relocations. */
union
{
elf_hash_table (info)->tls_sec->alignment_power));
}
-static void
-metag_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+static bool
+metag_info_to_howto_rela (bfd *abfd,
arelent *cache_ptr,
Elf_Internal_Rela *dst)
{
r_type = ELF32_R_TYPE (dst->r_info);
if (r_type >= (unsigned int) R_METAG_MAX)
{
- _bfd_error_handler (_("%B: invalid METAG reloc number: %d"), abfd, r_type);
- r_type = 0;
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
}
cache_ptr->howto = & elf_metag_howto_table [r_type];
+ return true;
}
static reloc_howto_type *
/* Various hash macros and functions. */
#define metag_link_hash_table(p) \
- (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
- == METAG_ELF_DATA ? ((struct elf_metag_link_hash_table *) ((p)->hash)) : NULL)
+ ((is_elf_hash_table ((p)->hash) \
+ && elf_hash_table_id (elf_hash_table (p)) == METAG_ELF_DATA) \
+ ? (struct elf_metag_link_hash_table *) (p)->hash : NULL)
#define metag_elf_hash_entry(ent) \
((struct elf_metag_link_hash_entry *)(ent))
/* Initialize the local fields. */
hh = (struct elf_metag_link_hash_entry *) entry;
hh->hsh_cache = NULL;
- hh->dyn_relocs = NULL;
hh->tls_type = GOT_UNKNOWN;
}
elf_metag_link_hash_table_create (bfd *abfd)
{
struct elf_metag_link_hash_table *htab;
- bfd_size_type amt = sizeof (*htab);
+ size_t amt = sizeof (*htab);
htab = bfd_zmalloc (amt);
if (htab == NULL)
return NULL;
}
htab->etab.root.hash_table_free = elf_metag_link_hash_table_free;
+ htab->etab.dt_pltgot_required = true;
return &htab->etab.root;
}
return NULL;
hsh = metag_stub_hash_lookup (&htab->bstab,
- stub_name, FALSE, FALSE);
+ stub_name, false, false);
if (hh != NULL)
hh->hsh_cache = hsh;
/* Enter this entry into the linker stub hash table. */
hsh = metag_stub_hash_lookup (&htab->bstab, stub_name,
- TRUE, FALSE);
+ true, false);
if (hsh == NULL)
{
- (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
- section->owner,
- stub_name);
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: cannot create stub entry %s"),
+ section->owner, stub_name);
return NULL;
}
/* Check a signed integer value can be represented in the given number
of bits. */
-static bfd_boolean
+static bool
within_signed_range (int value, unsigned int bits)
{
int min_val = -(1 << (bits - 1));
rel, relend, howto, contents) \
{ \
_bfd_clear_contents (howto, input_bfd, input_section, \
- contents + rel->r_offset); \
+ contents, rel->r_offset); \
\
- if (info->relocatable \
+ if (bfd_link_relocatable (info) \
&& (input_section->flags & SEC_DEBUGGING)) \
{ \
/* Only remove relocations in debug sections since other \
section, which means that the addend must be adjusted
accordingly. */
-static bfd_boolean
+static int
elf_metag_relocate_section (bfd *output_bfd,
struct bfd_link_info *info,
bfd *input_bfd,
name = bfd_elf_string_from_elf_section
(input_bfd, symtab_hdr->sh_link, sym->st_name);
- name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+ name = name == NULL ? bfd_section_name (sec) : name;
}
else
{
struct elf_link_hash_entry *eh;
- bfd_boolean unresolved_reloc, warned, ignored;
+ bool unresolved_reloc, warned, ignored;
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
r_symndx, symtab_hdr, eh_syms,
METAG_RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
rel, relend, howto, contents);
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
continue;
switch (r_type)
if ((input_section->flags & SEC_ALLOC) == 0)
break;
- if ((info->shared
+ if ((bfd_link_pic (info)
&& r_symndx != STN_UNDEF
&& (input_section->flags & SEC_ALLOC) != 0
&& (r_type != R_METAG_RELBRANCH
|| !SYMBOL_CALLS_LOCAL (info, &hh->eh)))
- || (!info->shared
+ || (!bfd_link_pic (info)
&& hh != NULL
&& hh->eh.dynindx != -1
&& !hh->eh.non_got_ref
|| hh->eh.root.type == bfd_link_hash_undefined)))
{
Elf_Internal_Rela outrel;
- bfd_boolean skip, relocate;
+ bool skip, relocate;
bfd_byte *loc;
/* When generating a shared object, these relocations
sreloc = elf_section_data (input_section)->sreloc;
BFD_ASSERT (sreloc != NULL);
- skip = FALSE;
- relocate = FALSE;
+ skip = false;
+ relocate = false;
outrel.r_offset = _bfd_elf_section_offset (output_bfd,
info,
input_section,
rel->r_offset);
if (outrel.r_offset == (bfd_vma) -1)
- skip = TRUE;
+ skip = true;
else if (outrel.r_offset == (bfd_vma) -2)
- skip = TRUE, relocate = TRUE;
+ skip = true, relocate = true;
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
|| ((info->symbolic || hh->eh.dynindx == -1)
&& hh->eh.def_regular))
{
- relocate = TRUE;
+ relocate = true;
outrel.r_info = ELF32_R_INFO (0, R_METAG_RELATIVE);
outrel.r_addend = relocation + rel->r_addend;
}
if (hh->eh.forced_local)
break;
- if (hh->eh.plt.offset == (bfd_vma) -1 ||
- htab->splt == NULL)
+ if (hh->eh.plt.offset == (bfd_vma) -1 || htab->etab.splt == NULL)
{
/* We didn't make a PLT entry for this symbol. This
happens when statically linking PIC code, or when
break;
}
- relocation = (htab->splt->output_section->vma
- + htab->splt->output_offset
+ relocation = (htab->etab.splt->output_section->vma
+ + htab->etab.splt->output_offset
+ hh->eh.plt.offset);
break;
case R_METAG_HI16_GOTPC:
case R_METAG_LO16_GOTPC:
- BFD_ASSERT (htab->sgot != NULL);
+ BFD_ASSERT (htab->etab.sgot != NULL);
- relocation = (htab->sgot->output_section->vma +
- htab->sgot->output_offset);
+ relocation = (htab->etab.sgot->output_section->vma +
+ htab->etab.sgot->output_offset);
relocation += GOT_REG_OFFSET;
relocation -= (input_section->output_section->vma
+ input_section->output_offset
case R_METAG_HI16_GOTOFF:
case R_METAG_LO16_GOTOFF:
case R_METAG_GETSET_GOTOFF:
- BFD_ASSERT (htab->sgot != NULL);
+ BFD_ASSERT (htab->etab.sgot != NULL);
- relocation -= (htab->sgot->output_section->vma +
- htab->sgot->output_offset);
+ relocation -= (htab->etab.sgot->output_section->vma +
+ htab->etab.sgot->output_offset);
relocation -= GOT_REG_OFFSET;
break;
case R_METAG_GETSET_GOT:
{
bfd_vma off;
- bfd_boolean do_got = 0;
+ bool do_got = 0;
/* Relocation is to the entry for this symbol in the
global offset table. */
if (hh != NULL)
{
- bfd_boolean dyn;
+ bool dyn;
off = hh->eh.got.offset;
dyn = htab->etab.dynamic_sections_created;
- if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared,
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+ bfd_link_pic (info),
&hh->eh))
{
/* If we aren't going to call finish_dynamic_symbol,
if (do_got)
{
- if (info->shared)
+ if (bfd_link_pic (info))
{
/* Output a dynamic relocation for this GOT entry.
In this case it is relative to the base of the
object because the symbol index is zero. */
Elf_Internal_Rela outrel;
bfd_byte *loc;
- asection *s = htab->srelgot;
+ asection *s = htab->etab.srelgot;
outrel.r_offset = (off
- + htab->sgot->output_offset
- + htab->sgot->output_section->vma);
+ + htab->etab.sgot->output_offset
+ + htab->etab.sgot->output_section->vma);
outrel.r_info = ELF32_R_INFO (0, R_METAG_RELATIVE);
outrel.r_addend = relocation;
loc = s->contents;
}
else
bfd_put_32 (output_bfd, relocation,
- htab->sgot->contents + off);
+ htab->etab.sgot->contents + off);
}
if (off >= (bfd_vma) -2)
int indx;
char tls_type;
- if (htab->sgot == NULL)
+ if (htab->etab.sgot == NULL)
abort();
indx = 0;
if (hh != NULL)
{
- bfd_boolean dyn;
+ bool dyn;
dyn = htab->etab.dynamic_sections_created;
- if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, &hh->eh)
- && (!info->shared
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+ bfd_link_pic (info),
+ &hh->eh)
+ && (!bfd_link_pic (info)
|| !SYMBOL_REFERENCES_LOCAL (info, &hh->eh)))
{
indx = hh->eh.dynindx;
}
if (tls_type == GOT_UNKNOWN)
- abort();
+ abort ();
if ((off & 1) != 0)
off &= ~1;
else
{
- bfd_boolean need_relocs = FALSE;
+ bool need_relocs = false;
Elf_Internal_Rela outrel;
bfd_byte *loc = NULL;
int cur_off = off;
now, and emit any relocations. If both an IE GOT and a
GD GOT are necessary, we emit the GD first. */
- if ((info->shared || indx != 0)
+ if ((bfd_link_pic (info) || indx != 0)
&& (hh == NULL
|| ELF_ST_VISIBILITY (hh->eh.other) == STV_DEFAULT
|| hh->eh.root.type != bfd_link_hash_undefweak))
{
- need_relocs = TRUE;
- loc = htab->srelgot->contents;
+ need_relocs = true;
+ loc = htab->etab.srelgot->contents;
/* FIXME (CAO): Should this be reloc_count++ ? */
- loc += htab->srelgot->reloc_count * sizeof (Elf32_External_Rela);
+ loc += htab->etab.srelgot->reloc_count * sizeof (Elf32_External_Rela);
}
if (tls_type & GOT_TLS_GD)
if (need_relocs)
{
outrel.r_offset = (cur_off
- + htab->sgot->output_section->vma
- + htab->sgot->output_offset);
+ + htab->etab.sgot->output_section->vma
+ + htab->etab.sgot->output_offset);
outrel.r_info = ELF32_R_INFO (indx, R_METAG_TLS_DTPMOD);
outrel.r_addend = 0;
- bfd_put_32 (output_bfd, 0, htab->sgot->contents + cur_off);
+ bfd_put_32 (output_bfd, 0, htab->etab.sgot->contents + cur_off);
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
- htab->srelgot->reloc_count++;
+ htab->etab.srelgot->reloc_count++;
loc += sizeof (Elf32_External_Rela);
if (indx == 0)
bfd_put_32 (output_bfd, 0,
- htab->sgot->contents + cur_off + 4);
+ htab->etab.sgot->contents + cur_off + 4);
else
{
bfd_put_32 (output_bfd, 0,
- htab->sgot->contents + cur_off + 4);
+ htab->etab.sgot->contents + cur_off + 4);
outrel.r_info = ELF32_R_INFO (indx,
R_METAG_TLS_DTPOFF);
outrel.r_offset += 4;
bfd_elf32_swap_reloca_out (output_bfd,
&outrel, loc);
- htab->srelgot->reloc_count++;
+ htab->etab.srelgot->reloc_count++;
loc += sizeof (Elf32_External_Rela);
}
}
else
{
/* We don't support changing the TLS model. */
- abort ();
+ /* PR 20675 */
+ if (bfd_link_pic (info))
+ _bfd_error_handler (_("%pB(%pA): multiple TLS models are not supported"),
+ input_bfd, input_section);
+ else
+ _bfd_error_handler (_("%pB(%pA): shared library symbol %s encountered whilst performing a static link"),
+ input_bfd, input_section, name);
+ return false;
}
cur_off += 8;
if (need_relocs)
{
outrel.r_offset = (cur_off
- + htab->sgot->output_section->vma
- + htab->sgot->output_offset);
+ + htab->etab.sgot->output_section->vma
+ + htab->etab.sgot->output_offset);
outrel.r_info = ELF32_R_INFO (indx, R_METAG_TLS_TPOFF);
if (indx == 0)
outrel.r_addend = 0;
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
- htab->srelgot->reloc_count++;
+ htab->etab.srelgot->reloc_count++;
loc += sizeof (Elf32_External_Rela);
}
else
bfd_put_32 (output_bfd, tpoff (info, relocation),
- htab->sgot->contents + cur_off);
+ htab->etab.sgot->contents + cur_off);
cur_off += 4;
}
case R_METAG_TLS_IENONPIC_LO16:
case R_METAG_TLS_LE_HI16:
case R_METAG_TLS_LE_LO16:
- if (info->shared)
+ if (bfd_link_pic (info))
{
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): R_METAG_TLS_LE/IENONPIC relocation not permitted in shared object"),
- input_bfd, input_section,
- (long) rel->r_offset, howto->name);
- return FALSE;
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): "
+ "%s relocation not permitted in shared object"),
+ input_bfd, input_section, (uint64_t) rel->r_offset,
+ howto->name);
+ return false;
}
else
relocation = tpoff (info, relocation);
break;
case R_METAG_TLS_LDO_HI16:
case R_METAG_TLS_LDO_LO16:
- if (! info->shared)
+ if (! bfd_link_pic (info))
relocation = tpoff (info, relocation);
else
relocation -= dtpoff_base (info);
{
bfd_vma off;
- if (htab->sgot == NULL)
+ if (htab->etab.sgot == NULL)
abort();
off = htab->tls_ldm_got.offset;
if (off & 1)
bfd_byte *loc;
outrel.r_offset = (off
- + htab->sgot->output_section->vma
- + htab->sgot->output_offset);
+ + htab->etab.sgot->output_section->vma
+ + htab->etab.sgot->output_offset);
outrel.r_addend = 0;
outrel.r_info = ELF32_R_INFO (0, R_METAG_TLS_DTPMOD);
- loc = htab->srelgot->contents;
- loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ loc = htab->etab.srelgot->contents;
+ loc += htab->etab.srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
htab->tls_ldm_got.offset |= 1;
}
switch (r)
{
case bfd_reloc_overflow:
- r = info->callbacks->reloc_overflow
+ (*info->callbacks->reloc_overflow)
(info, (hh ? &hh->eh.root : NULL), name, howto->name,
(bfd_vma) 0, input_bfd, input_section, rel->r_offset);
break;
case bfd_reloc_undefined:
- r = info->callbacks->undefined_symbol
- (info, name, input_bfd, input_section, rel->r_offset,
- TRUE);
+ (*info->callbacks->undefined_symbol)
+ (info, name, input_bfd, input_section, rel->r_offset, true);
break;
case bfd_reloc_outofrange:
}
if (msg)
- r = info->callbacks->warning
- (info, msg, name, input_bfd, input_section, rel->r_offset);
-
- if (! r)
- return FALSE;
+ (*info->callbacks->warning) (info, msg, name, input_bfd,
+ input_section, rel->r_offset);
}
}
- return TRUE;
+ return true;
}
/* Create the .plt and .got sections, and set up our hash table
short-cuts to various dynamic sections. */
-static bfd_boolean
+static bool
elf_metag_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
{
struct elf_metag_link_hash_table *htab;
/* Don't try to create the .plt and .got twice. */
htab = metag_link_hash_table (info);
- if (htab->splt != NULL)
- return TRUE;
+ if (htab->etab.splt != NULL)
+ return true;
/* Call the generic code to do most of the work. */
if (! _bfd_elf_create_dynamic_sections (abfd, info))
- return FALSE;
-
- htab->sgot = bfd_get_linker_section (abfd, ".got");
- if (! htab->sgot)
- return FALSE;
-
- htab->sgotplt = bfd_make_section_with_flags (abfd, ".got.plt",
- (SEC_ALLOC | SEC_LOAD |
- SEC_HAS_CONTENTS |
- SEC_IN_MEMORY |
- SEC_LINKER_CREATED));
- if (htab->sgotplt == NULL
- || !bfd_set_section_alignment (abfd, htab->sgotplt, 2))
- return FALSE;
-
- /* Define the symbol __GLOBAL_OFFSET_TABLE__ at the start of the .got
- section. We don't do this in the linker script because we don't want
- to define the symbol if we are not creating a global offset table. */
+ return false;
+
+ /* The header goes at the start of the dynamic .got section, which
+ is placed after the dynamic .got.plt section. ie. The header is
+ not necessarily at the start of the output .got section. */
+ htab->etab.sgot->size += 12;
+
+ /* Define the symbol __GLOBAL_OFFSET_TABLE__ on the header. */
bh = NULL;
if (!(_bfd_generic_link_add_one_symbol
- (info, abfd, "__GLOBAL_OFFSET_TABLE__", BSF_GLOBAL, htab->sgot,
- (bfd_vma) 0, NULL, FALSE, bed->collect, &bh)))
- return FALSE;
+ (info, abfd, "__GLOBAL_OFFSET_TABLE__", BSF_GLOBAL, htab->etab.sgot,
+ (bfd_vma) 0, NULL, false, bed->collect, &bh)))
+ return false;
eh = (struct elf_link_hash_entry *) bh;
eh->def_regular = 1;
eh->type = STT_OBJECT;
eh->other = STV_HIDDEN;
- if (! info->executable
+ if (! bfd_link_executable (info)
&& ! bfd_elf_link_record_dynamic_symbol (info, eh))
- return FALSE;
-
- elf_hash_table (info)->hgot = eh;
-
- htab->splt = bfd_get_linker_section (abfd, ".plt");
- htab->srelplt = bfd_get_linker_section (abfd, ".rela.plt");
+ return false;
- htab->srelgot = bfd_get_linker_section (abfd, ".rela.got");
+ htab->etab.hgot = eh;
- htab->sdynbss = bfd_get_linker_section (abfd, ".dynbss");
- htab->srelbss = bfd_get_linker_section (abfd, ".rela.bss");
-
- return TRUE;
+ return true;
}
/* Look through the relocs for a section during the first phase, and
table, and dynamic reloc sections. At this point we haven't
necessarily read all the input files. */
-static bfd_boolean
+static bool
elf_metag_check_relocs (bfd *abfd,
struct bfd_link_info *info,
asection *sec,
bfd *dynobj;
int tls_type = GOT_UNKNOWN, old_tls_type = GOT_UNKNOWN;
- if (info->relocatable)
- return TRUE;
+ if (bfd_link_relocatable (info))
+ return true;
htab = metag_link_hash_table (info);
dynobj = htab->etab.dynobj;
sreloc = NULL;
if (htab == NULL)
- return FALSE;
+ return false;
rel_end = relocs + sec->reloc_count;
for (rel = relocs; rel < rel_end; rel++)
if (r_symndx < symtab_hdr->sh_info)
{
/* A local symbol. */
- isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ isym = bfd_sym_from_r_symndx (&htab->etab.sym_cache,
abfd, r_symndx);
if (isym == NULL)
- return FALSE;
+ return false;
hh = NULL;
}
while (hh->eh.root.type == bfd_link_hash_indirect
|| hh->eh.root.type == bfd_link_hash_warning)
hh = (struct elf_metag_link_hash_entry *) hh->eh.root.u.i.link;
-
- /* PR15323, ref flags aren't set for references in the same
- object. */
- hh->eh.root.non_ir_ref = 1;
}
/* Some relocs require a global offset table. */
- if (htab->sgot == NULL)
+ if (htab->etab.sgot == NULL)
{
switch (r_type)
{
case R_METAG_TLS_GD:
case R_METAG_TLS_LDM:
case R_METAG_TLS_IE:
- if (info->shared)
+ if (bfd_link_pic (info))
info->flags |= DF_STATIC_TLS;
/* Fall through. */
if (dynobj == NULL)
htab->etab.dynobj = dynobj = abfd;
if (!elf_metag_create_dynamic_sections (dynobj, info))
- return FALSE;
+ return false;
break;
default:
local_got_refcounts = ((bfd_signed_vma *)
bfd_zalloc (abfd, size));
if (local_got_refcounts == NULL)
- return FALSE;
+ return false;
elf_local_got_refcounts (abfd) = local_got_refcounts;
memset (metag_elf_local_got_tls_type (abfd),
GOT_UNKNOWN, symtab_hdr->sh_info);
cannot be used in shared libs. Don't error out for
sections we don't care about, such as debug sections or
non-constant sections. */
- if (info->shared
+ if (bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0
&& (sec->flags & SEC_READONLY) != 0)
{
name = hh->eh.root.root.string;
else
name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
- (*_bfd_error_handler)
- (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
abfd, elf_metag_howto_table[r_type].name, name);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
}
/* Fall through. */
case R_METAG_ADDR32:
case R_METAG_RELBRANCH:
case R_METAG_GETSETOFF:
- if (hh != NULL && !info->shared)
+ if (hh != NULL && !bfd_link_pic (info))
{
hh->eh.non_got_ref = 1;
hh->eh.plt.refcount += 1;
may need to keep relocations for symbols satisfied by a
dynamic library if we manage to avoid copy relocs for the
symbol. */
- if ((info->shared
+ if ((bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0
&& (r_type != R_METAG_RELBRANCH
|| (hh != NULL
&& (! info->symbolic
|| hh->eh.root.type == bfd_link_hash_defweak
|| !hh->eh.def_regular))))
- || (!info->shared
+ || (!bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0
&& hh != NULL
&& (hh->eh.root.type == bfd_link_hash_defweak
|| !hh->eh.def_regular)))
{
- struct elf_metag_dyn_reloc_entry *hdh_p;
- struct elf_metag_dyn_reloc_entry **hdh_head;
+ struct elf_dyn_relocs *hdh_p;
+ struct elf_dyn_relocs **hdh_head;
if (dynobj == NULL)
htab->etab.dynobj = dynobj = abfd;
if (sreloc == NULL)
{
sreloc = _bfd_elf_make_dynamic_reloc_section
- (sec, htab->etab.dynobj, 2, abfd, /*rela?*/ TRUE);
+ (sec, htab->etab.dynobj, 2, abfd, /*rela?*/ true);
if (sreloc == NULL)
{
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
}
elf_section_data (sec)->sreloc = sreloc;
/* If this is a global symbol, we count the number of
relocations we need for this symbol. */
if (hh != NULL)
- hdh_head = &((struct elf_metag_link_hash_entry *) hh)->dyn_relocs;
+ hdh_head = &hh->eh.dyn_relocs;
else
{
/* Track dynamic relocs needed for local syms too. */
sr = sec;
vpp = &elf_section_data (sr)->local_dynrel;
- hdh_head = (struct elf_metag_dyn_reloc_entry **) vpp;
+ hdh_head = (struct elf_dyn_relocs **) vpp;
}
hdh_p = *hdh_head;
if (hdh_p == NULL || hdh_p->sec != sec)
{
- hdh_p = ((struct elf_metag_dyn_reloc_entry *)
+ hdh_p = ((struct elf_dyn_relocs *)
bfd_alloc (dynobj, sizeof *hdh_p));
if (hdh_p == NULL)
- return FALSE;
- hdh_p->hdh_next = *hdh_head;
+ return false;
+ hdh_p->next = *hdh_head;
*hdh_head = hdh_p;
hdh_p->sec = sec;
hdh_p->count = 0;
- hdh_p->relative_count = 0;
+ hdh_p->pc_count = 0;
}
hdh_p->count += 1;
if (ELF32_R_TYPE (rel->r_info) == R_METAG_RELBRANCH)
- hdh_p->relative_count += 1;
+ hdh_p->pc_count += 1;
}
break;
case R_METAG_GNU_VTINHERIT:
if (!bfd_elf_gc_record_vtinherit (abfd, sec, &hh->eh,
rel->r_offset))
- return FALSE;
+ return false;
break;
/* This relocation describes which C++ vtable entries are actually
used. Record for later use during GC. */
case R_METAG_GNU_VTENTRY:
- BFD_ASSERT (hh != NULL);
- if (hh != NULL
- && !bfd_elf_gc_record_vtentry (abfd, sec, &hh->eh, rel->r_addend))
- return FALSE;
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, &hh->eh, rel->r_addend))
+ return false;
break;
}
}
- return TRUE;
+ return true;
}
/* Copy the extra info we tack onto an elf_link_hash_entry. */
hh_dir = metag_elf_hash_entry (eh_dir);
hh_ind = metag_elf_hash_entry (eh_ind);
- if (hh_ind->dyn_relocs != NULL)
- {
- if (hh_dir->dyn_relocs != NULL)
- {
- struct elf_metag_dyn_reloc_entry **hdh_pp;
- struct elf_metag_dyn_reloc_entry *hdh_p;
-
- if (eh_ind->root.type == bfd_link_hash_indirect)
- abort ();
-
- /* Add reloc counts against the weak sym to the strong sym
- list. Merge any entries against the same section. */
- for (hdh_pp = &hh_ind->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
- {
- struct elf_metag_dyn_reloc_entry *hdh_q;
-
- for (hdh_q = hh_dir->dyn_relocs; hdh_q != NULL;
- hdh_q = hdh_q->hdh_next)
- if (hdh_q->sec == hdh_p->sec)
- {
- hdh_q->relative_count += hdh_p->relative_count;
- hdh_q->count += hdh_p->count;
- *hdh_pp = hdh_p->hdh_next;
- break;
- }
- if (hdh_q == NULL)
- hdh_pp = &hdh_p->hdh_next;
- }
- *hdh_pp = hh_dir->dyn_relocs;
- }
-
- hh_dir->dyn_relocs = hh_ind->dyn_relocs;
- hh_ind->dyn_relocs = NULL;
- }
-
if (eh_ind->root.type == bfd_link_hash_indirect
&& eh_dir->got.refcount <= 0)
{
change the definition to something the rest of the link can
understand. */
-static bfd_boolean
+static bool
elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *eh)
{
struct elf_metag_link_hash_table *htab;
- struct elf_metag_link_hash_entry *hh;
- struct elf_metag_dyn_reloc_entry *hdh_p;
- asection *s;
+ asection *s, *srel;
/* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later,
eh->needs_plt = 0;
}
- return TRUE;
+ return true;
}
else
eh->plt.offset = (bfd_vma) -1;
/* If this is a weak symbol, and there is a real definition, the
processor independent code will have arranged for us to see the
real definition first, and we can just use the same value. */
- if (eh->u.weakdef != NULL)
+ if (eh->is_weakalias)
{
- if (eh->u.weakdef->root.type != bfd_link_hash_defined
- && eh->u.weakdef->root.type != bfd_link_hash_defweak)
- abort ();
- eh->root.u.def.section = eh->u.weakdef->root.u.def.section;
- eh->root.u.def.value = eh->u.weakdef->root.u.def.value;
- eh->non_got_ref = eh->u.weakdef->non_got_ref;
- return TRUE;
+ struct elf_link_hash_entry *def = weakdef (eh);
+ BFD_ASSERT (def->root.type == bfd_link_hash_defined);
+ eh->root.u.def.section = def->root.u.def.section;
+ eh->root.u.def.value = def->root.u.def.value;
+ eh->non_got_ref = def->non_got_ref;
+ return true;
}
/* This is a reference to a symbol defined by a dynamic object which
only references to the symbol are via the global offset table.
For such cases we need not do anything here; the relocations will
be handled correctly by relocate_section. */
- if (info->shared)
- return TRUE;
+ if (bfd_link_pic (info))
+ return true;
/* If there are no references to this symbol that do not use the
GOT, we don't need to generate a copy reloc. */
if (!eh->non_got_ref)
- return TRUE;
+ return true;
/* If -z nocopyreloc was given, we won't generate them either. */
if (info->nocopyreloc)
{
eh->non_got_ref = 0;
- return TRUE;
- }
-
- hh = (struct elf_metag_link_hash_entry *) eh;
- for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next)
- {
- s = hdh_p->sec->output_section;
- if (s != NULL && (s->flags & SEC_READONLY) != 0)
- break;
+ return true;
}
- /* If we didn't find any dynamic relocs in read-only sections, then
+ /* If we don't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */
- if (hdh_p == NULL)
+ if (!_bfd_elf_readonly_dynrelocs (eh))
{
eh->non_got_ref = 0;
- return TRUE;
+ return true;
}
/* We must allocate the symbol in our .dynbss section, which will
/* We must generate a COPY reloc to tell the dynamic linker to
copy the initial value out of the dynamic object and into the
runtime process image. */
+ if ((eh->root.u.def.section->flags & SEC_READONLY) != 0)
+ {
+ s = htab->etab.sdynrelro;
+ srel = htab->etab.sreldynrelro;
+ }
+ else
+ {
+ s = htab->etab.sdynbss;
+ srel = htab->etab.srelbss;
+ }
if ((eh->root.u.def.section->flags & SEC_ALLOC) != 0 && eh->size != 0)
{
- htab->srelbss->size += sizeof (Elf32_External_Rela);
+ srel->size += sizeof (Elf32_External_Rela);
eh->needs_copy = 1;
}
- s = htab->sdynbss;
-
return _bfd_elf_adjust_dynamic_copy (info, eh, s);
}
/* Allocate space in .plt, .got and associated reloc sections for
global syms. */
-static bfd_boolean
+static bool
allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
{
struct bfd_link_info *info;
struct elf_metag_link_hash_table *htab;
- struct elf_metag_link_hash_entry *hh;
- struct elf_metag_dyn_reloc_entry *hdh_p;
+ struct elf_dyn_relocs *hdh_p;
if (eh->root.type == bfd_link_hash_indirect)
- return TRUE;
+ return true;
if (eh->root.type == bfd_link_hash_warning)
eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
&& !eh->forced_local)
{
if (! bfd_elf_link_record_dynamic_symbol (info, eh))
- return FALSE;
+ return false;
}
- if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, eh))
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), eh))
{
- asection *s = htab->splt;
+ asection *s = htab->etab.splt;
/* If this is the first .plt entry, make room for the special
first entry. */
location in the .plt. This is required to make function
pointers compare as equal between the normal executable and
the shared library. */
- if (! info->shared
+ if (! bfd_link_pic (info)
&& !eh->def_regular)
{
eh->root.u.def.section = s;
/* We also need to make an entry in the .got.plt section, which
will be placed in the .got section by the linker script. */
- htab->sgotplt->size += 4;
+ htab->etab.sgotplt->size += 4;
/* We also need to make an entry in the .rel.plt section. */
- htab->srelplt->size += sizeof (Elf32_External_Rela);
+ htab->etab.srelplt->size += sizeof (Elf32_External_Rela);
}
else
{
if (eh->got.refcount > 0)
{
asection *s;
- bfd_boolean dyn;
+ bool dyn;
int tls_type = metag_elf_hash_entry (eh)->tls_type;
/* Make sure this symbol is output as a dynamic symbol.
&& !eh->forced_local)
{
if (! bfd_elf_link_record_dynamic_symbol (info, eh))
- return FALSE;
+ return false;
}
- s = htab->sgot;
+ s = htab->etab.sgot;
eh->got.offset = s->size;
s->size += 4;
R_METAG_TLS_GD needs one if local symbol and two if global. */
if ((tls_type == GOT_TLS_GD && eh->dynindx == -1)
|| (tls_type == GOT_TLS_IE && dyn))
- htab->srelgot->size += sizeof (Elf32_External_Rela);
+ htab->etab.srelgot->size += sizeof (Elf32_External_Rela);
else if (tls_type == GOT_TLS_GD)
- htab->srelgot->size += 2 * sizeof (Elf32_External_Rela);
- else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, eh))
- htab->srelgot->size += sizeof (Elf32_External_Rela);
+ htab->etab.srelgot->size += 2 * sizeof (Elf32_External_Rela);
+ else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+ bfd_link_pic (info),
+ eh))
+ htab->etab.srelgot->size += sizeof (Elf32_External_Rela);
}
else
eh->got.offset = (bfd_vma) -1;
- hh = (struct elf_metag_link_hash_entry *) eh;
- if (hh->dyn_relocs == NULL)
- return TRUE;
+ if (eh->dyn_relocs == NULL)
+ return true;
/* If this is a -Bsymbolic shared link, then we need to discard all
space allocated for dynamic pc-relative relocs against symbols
defined in a regular object. For the normal shared case, discard
space for relocs that have become local due to symbol visibility
changes. */
- if (info->shared)
+ if (bfd_link_pic (info))
{
if (SYMBOL_CALLS_LOCAL (info, eh))
{
- struct elf_metag_dyn_reloc_entry **hdh_pp;
+ struct elf_dyn_relocs **hdh_pp;
- for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
+ for (hdh_pp = &eh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
{
- hdh_p->count -= hdh_p->relative_count;
- hdh_p->relative_count = 0;
+ hdh_p->count -= hdh_p->pc_count;
+ hdh_p->pc_count = 0;
if (hdh_p->count == 0)
- *hdh_pp = hdh_p->hdh_next;
+ *hdh_pp = hdh_p->next;
else
- hdh_pp = &hdh_p->hdh_next;
+ hdh_pp = &hdh_p->next;
}
}
/* Also discard relocs on undefined weak syms with non-default
visibility. */
- if (hh->dyn_relocs != NULL
+ if (eh->dyn_relocs != NULL
&& eh->root.type == bfd_link_hash_undefweak)
{
if (ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT)
- hh->dyn_relocs = NULL;
+ eh->dyn_relocs = NULL;
/* Make sure undefined weak symbols are output as a dynamic
symbol in PIEs. */
&& !eh->forced_local)
{
if (! bfd_elf_link_record_dynamic_symbol (info, eh))
- return FALSE;
+ return false;
}
}
}
&& !eh->forced_local)
{
if (! bfd_elf_link_record_dynamic_symbol (info, eh))
- return FALSE;
+ return false;
}
/* If that succeeded, we know we'll be keeping all the
goto keep;
}
- hh->dyn_relocs = NULL;
- return TRUE;
+ eh->dyn_relocs = NULL;
+ return true;
keep: ;
}
/* Finally, allocate space. */
- for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next)
+ for (hdh_p = eh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->next)
{
asection *sreloc = elf_section_data (hdh_p->sec)->sreloc;
sreloc->size += hdh_p->count * sizeof (Elf32_External_Rela);
}
- return TRUE;
-}
-
-/* Find any dynamic relocs that apply to read-only sections. */
-
-static bfd_boolean
-readonly_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
-{
- struct elf_metag_link_hash_entry *hh;
- struct elf_metag_dyn_reloc_entry *hdh_p;
-
- if (eh->root.type == bfd_link_hash_warning)
- eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
-
- hh = (struct elf_metag_link_hash_entry *) eh;
- for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next)
- {
- asection *s = hdh_p->sec->output_section;
-
- if (s != NULL && (s->flags & SEC_READONLY) != 0)
- {
- struct bfd_link_info *info = inf;
-
- info->flags |= DF_TEXTREL;
-
- /* Not an error, just cut short the traversal. */
- return FALSE;
- }
- }
- return TRUE;
+ return true;
}
/* Set the sizes of the dynamic sections. */
-static bfd_boolean
+static bool
elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
struct bfd_link_info *info)
{
bfd *dynobj;
bfd *ibfd;
asection *s;
- bfd_boolean relocs;
+ bool relocs;
htab = metag_link_hash_table (info);
dynobj = htab->etab.dynobj;
if (htab->etab.dynamic_sections_created)
{
/* Set the contents of the .interp section to the interpreter. */
- if (info->executable)
+ if (bfd_link_executable (info) && !info->nointerp)
{
s = bfd_get_linker_section (dynobj, ".interp");
if (s == NULL)
for (s = ibfd->sections; s != NULL; s = s->next)
{
- struct elf_metag_dyn_reloc_entry *hdh_p;
+ struct elf_dyn_relocs *hdh_p;
- for (hdh_p = ((struct elf_metag_dyn_reloc_entry *)
+ for (hdh_p = ((struct elf_dyn_relocs *)
elf_section_data (s)->local_dynrel);
hdh_p != NULL;
- hdh_p = hdh_p->hdh_next)
+ hdh_p = hdh_p->next)
{
if (!bfd_is_abs_section (hdh_p->sec)
&& bfd_is_abs_section (hdh_p->sec->output_section))
locsymcount = symtab_hdr->sh_info;
end_local_got = local_got + locsymcount;
local_tls_type = metag_elf_local_got_tls_type (ibfd);
- s = htab->sgot;
- srel = htab->srelgot;
+ s = htab->etab.sgot;
+ srel = htab->etab.srelgot;
for (; local_got < end_local_got; ++local_got)
{
if (*local_got > 0)
/* R_METAG_TLS_GD relocs need 2 consecutive GOT entries. */
if (*local_tls_type == GOT_TLS_GD)
s->size += 4;
- if (info->shared)
+ if (bfd_link_pic (info))
srel->size += sizeof (Elf32_External_Rela);
}
else
{
/* Allocate 2 got entries and 1 dynamic reloc for R_METAG_TLS_LDM
reloc. */
- htab->tls_ldm_got.offset = htab->sgot->size;
- htab->sgot->size += 8;
- htab->srelgot->size += sizeof (Elf32_External_Rela);
+ htab->tls_ldm_got.offset = htab->etab.sgot->size;
+ htab->etab.sgot->size += 8;
+ htab->etab.srelgot->size += sizeof (Elf32_External_Rela);
}
else
htab->tls_ldm_got.offset = -1;
/* We now have determined the sizes of the various dynamic sections.
Allocate memory for them. */
- relocs = FALSE;
+ relocs = false;
for (s = dynobj->sections; s != NULL; s = s->next)
{
- bfd_boolean reloc_section = FALSE;
+ bool reloc_section = false;
if ((s->flags & SEC_LINKER_CREATED) == 0)
continue;
- if (s == htab->splt
- || s == htab->sgot
- || s == htab->sgotplt
- || s == htab->sdynbss)
+ if (s == htab->etab.splt
+ || s == htab->etab.sgot
+ || s == htab->etab.sgotplt
+ || s == htab->etab.sdynbss
+ || s == htab->etab.sdynrelro)
{
/* Strip this section if we don't need it; see the
comment below. */
}
- else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
+ else if (startswith (bfd_section_name (s), ".rela"))
{
- if (s->size != 0 && s != htab->srelplt)
- relocs = TRUE;
+ if (s->size != 0 && s != htab->etab.srelplt)
+ relocs = true;
/* We use the reloc_count field as a counter if we need
to copy relocs into the output file. */
s->reloc_count = 0;
- reloc_section = TRUE;
+ reloc_section = true;
}
else
{
/* Allocate memory for the section contents. */
s->contents = bfd_zalloc (dynobj, s->size);
if (s->contents == NULL)
- return FALSE;
+ return false;
else if (reloc_section)
{
unsigned char *contents = s->contents;
}
}
- if (htab->etab.dynamic_sections_created)
- {
- /* Add some entries to the .dynamic section. We fill in the
- values later, in elf_metag_finish_dynamic_sections, but we
- must add the entries now so that we get the correct size for
- the .dynamic section. The DT_DEBUG entry is filled in by the
- dynamic linker and used by the debugger. */
-#define add_dynamic_entry(TAG, VAL) \
- _bfd_elf_add_dynamic_entry (info, TAG, VAL)
-
- if (!add_dynamic_entry (DT_PLTGOT, 0))
- return FALSE;
-
- if (info->executable)
- {
- if (!add_dynamic_entry (DT_DEBUG, 0))
- return FALSE;
- }
-
- if (htab->srelplt->size != 0)
- {
- if (!add_dynamic_entry (DT_PLTRELSZ, 0)
- || !add_dynamic_entry (DT_PLTREL, DT_RELA)
- || !add_dynamic_entry (DT_JMPREL, 0))
- return FALSE;
- }
-
- if (relocs)
- {
- if (!add_dynamic_entry (DT_RELA, 0)
- || !add_dynamic_entry (DT_RELASZ, 0)
- || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
- return FALSE;
-
- /* If any dynamic relocs apply to a read-only section,
- then we need a DT_TEXTREL entry. */
- if ((info->flags & DF_TEXTREL) == 0)
- elf_link_hash_traverse (&htab->etab, readonly_dynrelocs, info);
-
- if ((info->flags & DF_TEXTREL) != 0)
- {
- if (!add_dynamic_entry (DT_TEXTREL, 0))
- return FALSE;
- }
- }
- }
-#undef add_dynamic_entry
-
- return TRUE;
+ return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs);
}
/* Finish up dynamic symbol handling. We set the contents of various
dynamic sections here. */
-static bfd_boolean
+static bool
elf_metag_finish_dynamic_symbol (bfd *output_bfd,
struct bfd_link_info *info,
struct elf_link_hash_entry *eh,
BFD_ASSERT (eh->dynindx != -1);
- splt = htab->splt;
- sgot = htab->sgotplt;
- srela = htab->srelplt;
+ splt = htab->etab.splt;
+ sgot = htab->etab.sgotplt;
+ srela = htab->etab.srelplt;
BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
/* Get the index in the procedure linkage table which
BFD_ASSERT (plt_index < (1 << 16));
/* Fill in the entry in the procedure linkage table. */
- if (! info->shared)
+ if (! bfd_link_pic (info))
{
bfd_put_32 (output_bfd,
(plt_entry[0]
+ got_offset);
rel.r_info = ELF32_R_INFO (eh->dynindx, R_METAG_JMP_SLOT);
rel.r_addend = 0;
- loc = htab->srelplt->contents;
+ loc = htab->etab.srelplt->contents;
loc += plt_index * sizeof(Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
up. */
rel.r_offset = ((eh->got.offset &~ (bfd_vma) 1)
- + htab->sgot->output_offset
- + htab->sgot->output_section->vma);
+ + htab->etab.sgot->output_offset
+ + htab->etab.sgot->output_section->vma);
/* If this is a -Bsymbolic link and the symbol is defined
locally or was forced to be local because of a version file,
we just want to emit a RELATIVE reloc. The entry in the
global offset table will already have been initialized in the
relocate_section function. */
- if (info->shared
+ if (bfd_link_pic (info)
&& (info->symbolic || eh->dynindx == -1)
&& eh->def_regular)
{
{
if ((eh->got.offset & 1) != 0)
abort ();
- bfd_put_32 (output_bfd, 0, htab->sgot->contents + eh->got.offset);
+ bfd_put_32 (output_bfd, 0, htab->etab.sgot->contents + eh->got.offset);
rel.r_info = ELF32_R_INFO (eh->dynindx, R_METAG_GLOB_DAT);
rel.r_addend = 0;
}
- loc = htab->srelgot->contents;
- loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ loc = htab->etab.srelgot->contents;
+ loc += htab->etab.srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
}
|| eh->root.type == bfd_link_hash_defweak)))
abort ();
- s = htab->srelbss;
-
rel.r_offset = (eh->root.u.def.value
+ eh->root.u.def.section->output_offset
+ eh->root.u.def.section->output_section->vma);
rel.r_addend = 0;
rel.r_info = ELF32_R_INFO (eh->dynindx, R_METAG_COPY);
+ if (eh->root.u.def.section == htab->etab.sdynrelro)
+ s = htab->etab.sreldynrelro;
+ else
+ s = htab->etab.srelbss;
loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
}
sym->st_shndx = SHN_ABS;
}
- return TRUE;
+ return true;
}
/* Set the Meta ELF ABI version. */
-static void
-elf_metag_post_process_headers (bfd * abfd, struct bfd_link_info * link_info)
+static bool
+elf_metag_init_file_header (bfd *abfd, struct bfd_link_info *link_info)
{
Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */
- _bfd_elf_post_process_headers (abfd, link_info);
+ if (!_bfd_elf_init_file_header (abfd, link_info))
+ return false;
+
i_ehdrp = elf_elfheader (abfd);
i_ehdrp->e_ident[EI_ABIVERSION] = METAG_ELF_ABI_VERSION;
+ return true;
}
/* Used to decide how to sort relocs in an optimal manner for the
/* Finish up the dynamic sections. */
-static bfd_boolean
+static bool
elf_metag_finish_dynamic_sections (bfd *output_bfd,
struct bfd_link_info *info)
{
continue;
case DT_PLTGOT:
- s = htab->sgot->output_section;
- BFD_ASSERT (s != NULL);
- dyn.d_un.d_ptr = s->vma + htab->sgot->output_offset;
+ s = htab->etab.sgot;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
case DT_JMPREL:
- s = htab->srelplt->output_section;
- BFD_ASSERT (s != NULL);
- dyn.d_un.d_ptr = s->vma;
+ s = htab->etab.srelplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
case DT_PLTRELSZ:
- s = htab->srelplt;
+ s = htab->etab.srelplt;
dyn.d_un.d_val = s->size;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
-
- case DT_RELASZ:
- /* Don't count procedure linkage table relocs in the
- overall reloc count. */
- if (htab->srelplt) {
- s = htab->srelplt;
- dyn.d_un.d_val -= s->size;
- }
- bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
- break;
-
- case DT_RELA:
- /* We may not be using the standard ELF linker script.
- If .rela.plt is the first .rela section, we adjust
- DT_RELA to not include it. */
- if (htab->srelplt) {
- s = htab->srelplt;
- if (dyn.d_un.d_ptr == s->output_section->vma + s->output_offset)
- dyn.d_un.d_ptr += s->size;
- }
- bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
- break;
}
}
/* Fill in the first entry in the procedure linkage table. */
- splt = htab->splt;
+ splt = htab->etab.splt;
if (splt && splt->size > 0)
{
unsigned long addr;
/* addr = .got + 4 */
- addr = htab->sgot->output_section->vma +
- htab->sgot->output_offset + 4;
- if (info->shared)
+ addr = (htab->etab.sgot->output_section->vma
+ + htab->etab.sgot->output_offset + 4);
+ if (bfd_link_pic (info))
{
addr -= splt->output_section->vma + splt->output_offset;
bfd_put_32 (output_bfd,
}
}
- if (htab->sgot != NULL && htab->sgot->size != 0)
+ if (htab->etab.sgot != NULL && htab->etab.sgot->size != 0)
{
/* Fill in the first entry in the global offset table.
We use it to point to our dynamic section, if we have one. */
bfd_put_32 (output_bfd,
sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0,
- htab->sgot->contents);
+ htab->etab.sgot->contents);
/* The second entry is reserved for use by the dynamic linker. */
- memset (htab->sgot->contents + GOT_ENTRY_SIZE, 0, GOT_ENTRY_SIZE);
+ memset (htab->etab.sgot->contents + GOT_ENTRY_SIZE, 0, GOT_ENTRY_SIZE);
/* Set .got entry size. */
- elf_section_data (htab->sgot->output_section)
+ elf_section_data (htab->etab.sgot->output_section)
->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
}
- return TRUE;
+ return true;
}
/* Return the section that should be marked against GC for a given
return _bfd_elf_gc_mark_hook (sec, info, rela, hh, sym);
}
-/* Update the got and plt entry reference counts for the section being
- removed. */
-
-static bfd_boolean
-elf_metag_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
- struct bfd_link_info *info ATTRIBUTE_UNUSED,
- asection *sec ATTRIBUTE_UNUSED,
- const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
-{
- Elf_Internal_Shdr *symtab_hdr;
- struct elf_link_hash_entry **eh_syms;
- bfd_signed_vma *local_got_refcounts;
- bfd_signed_vma *local_plt_refcounts;
- const Elf_Internal_Rela *rel, *relend;
-
- if (info->relocatable)
- return TRUE;
-
- elf_section_data (sec)->local_dynrel = NULL;
-
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- eh_syms = elf_sym_hashes (abfd);
- local_got_refcounts = elf_local_got_refcounts (abfd);
- local_plt_refcounts = local_got_refcounts;
- if (local_plt_refcounts != NULL)
- local_plt_refcounts += symtab_hdr->sh_info;
-
- relend = relocs + sec->reloc_count;
- for (rel = relocs; rel < relend; rel++)
- {
- unsigned long r_symndx;
- unsigned int r_type;
- struct elf_link_hash_entry *eh = NULL;
-
- r_symndx = ELF32_R_SYM (rel->r_info);
- if (r_symndx >= symtab_hdr->sh_info)
- {
- struct elf_metag_link_hash_entry *hh;
- struct elf_metag_dyn_reloc_entry **hdh_pp;
- struct elf_metag_dyn_reloc_entry *hdh_p;
-
- eh = eh_syms[r_symndx - symtab_hdr->sh_info];
- while (eh->root.type == bfd_link_hash_indirect
- || eh->root.type == bfd_link_hash_warning)
- eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
- hh = (struct elf_metag_link_hash_entry *) eh;
-
- for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL;
- hdh_pp = &hdh_p->hdh_next)
- if (hdh_p->sec == sec)
- {
- /* Everything must go for SEC. */
- *hdh_pp = hdh_p->hdh_next;
- break;
- }
- }
-
- r_type = ELF32_R_TYPE (rel->r_info);
- switch (r_type)
- {
- case R_METAG_TLS_LDM:
- if (metag_link_hash_table (info)->tls_ldm_got.refcount > 0)
- metag_link_hash_table (info)->tls_ldm_got.refcount -= 1;
- break;
- case R_METAG_TLS_IE:
- case R_METAG_TLS_GD:
- case R_METAG_GETSET_GOT:
- if (eh != NULL)
- {
- if (eh->got.refcount > 0)
- eh->got.refcount -= 1;
- }
- else if (local_got_refcounts != NULL)
- {
- if (local_got_refcounts[r_symndx] > 0)
- local_got_refcounts[r_symndx] -= 1;
- }
- break;
-
- case R_METAG_RELBRANCH_PLT:
- if (eh != NULL)
- {
- if (eh->plt.refcount > 0)
- eh->plt.refcount -= 1;
- }
- break;
-
- case R_METAG_ADDR32:
- case R_METAG_HIADDR16:
- case R_METAG_LOADDR16:
- case R_METAG_GETSETOFF:
- case R_METAG_RELBRANCH:
- if (eh != NULL)
- {
- struct elf_metag_link_hash_entry *hh;
- struct elf_metag_dyn_reloc_entry **hdh_pp;
- struct elf_metag_dyn_reloc_entry *hdh_p;
-
- if (!info->shared && eh->plt.refcount > 0)
- eh->plt.refcount -= 1;
-
- hh = (struct elf_metag_link_hash_entry *) eh;
-
- for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL;
- hdh_pp = &hdh_p->hdh_next)
- if (hdh_p->sec == sec)
- {
- if (ELF32_R_TYPE (rel->r_info) == R_METAG_RELBRANCH)
- hdh_p->relative_count -= 1;
- hdh_p->count -= 1;
- if (hdh_p->count == 0)
- *hdh_pp = hdh_p->hdh_next;
- break;
- }
- }
- break;
-
- default:
- break;
- }
- }
-
- return TRUE;
-}
-
/* Determine the type of stub needed, if any, for a call. */
static enum elf_metag_stub_type
if (branch_offset + max_branch_offset >= 2*max_branch_offset)
{
- if (info->shared)
+ if (bfd_link_pic (info))
return metag_stub_long_branch_shared;
else
return metag_stub_long_branch;
#define ADD_A0_3_A0_3 0x82180000
#define MOV_PC_A0_3 0xa3180ca0
-static bfd_boolean
-metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_UNUSED)
+static bool
+metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
{
struct elf_metag_stub_hash_entry *hsh;
asection *stub_sec;
bfd_byte *loc;
bfd_vma sym_value;
int size;
+ struct bfd_link_info *info;
/* Massage our args to the form they really have. */
hsh = (struct elf_metag_stub_hash_entry *) gen_entry;
+ info = (struct bfd_link_info *) in_arg;
+
+ /* Fail if the target section could not be assigned to an output
+ section. The user should fix his linker script. */
+ if (hsh->target_section->output_section == NULL
+ && info->non_contiguous_regions)
+ info->callbacks->einfo (_("%F%P: Could not assign '%pA' to an output section. "
+ "Retry without --enable-non-contiguous-regions.\n"),
+ hsh->target_section);
stub_sec = hsh->stub_sec;
break;
default:
BFD_FAIL ();
- return FALSE;
+ return false;
}
stub_sec->size += size;
- return TRUE;
+ return true;
}
/* As above, but don't actually build the stub. Just bump offset so
we know stub section sizes. */
-static bfd_boolean
+static bool
metag_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_UNUSED)
{
struct elf_metag_stub_hash_entry *hsh;
size = 12;
hsh->stub_sec->size += size;
- return TRUE;
+ return true;
}
/* Set up various things so that we can make a list of input sections
{
bfd *input_bfd;
unsigned int bfd_count;
- int top_id, top_index;
+ unsigned int top_id, top_index;
asection *section;
asection **input_list, **list;
- bfd_size_type amt;
+ size_t amt;
struct elf_metag_link_hash_table *htab = metag_link_hash_table (info);
/* Count the number of input BFDs and find the top input section id. */
static void
group_sections (struct elf_metag_link_hash_table *htab,
bfd_size_type stub_group_size,
- bfd_boolean stubs_always_before_branch)
+ bool stubs_always_before_branch)
{
asection **list = htab->input_list + htab->top_index;
do
asection *curr;
asection *prev;
bfd_size_type total;
- bfd_boolean big_sec;
+ bool big_sec;
curr = tail;
total = tail->size;
/* We want to read in symbol extension records only once. To do this
we need to read in the local symbols in parallel and save them for
later use; so hold pointers to the local symbols in an array. */
- bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
+ size_t amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
all_local_syms = bfd_zmalloc (amt);
htab->all_local_syms = all_local_syms;
if (all_local_syms == NULL)
/* See elf32-hppa.c and elf64-ppc.c. */
-bfd_boolean
+bool
elf_metag_size_stubs(bfd *output_bfd, bfd *stub_bfd,
struct bfd_link_info *info,
bfd_signed_vma group_size,
void (*layout_sections_again) (void))
{
bfd_size_type stub_group_size;
- bfd_boolean stubs_always_before_branch;
- bfd_boolean stub_changed;
+ bool stubs_always_before_branch;
+ bool stub_changed;
struct elf_metag_link_hash_table *htab = metag_link_hash_table (info);
/* Stash our params away. */
default:
if (htab->all_local_syms)
goto error_ret_free_local;
- return FALSE;
+ return false;
case 0:
- stub_changed = FALSE;
+ stub_changed = false;
break;
case 1:
- stub_changed = TRUE;
+ stub_changed = true;
break;
}
&& hh->eh.dynindx != -1
&& r_type == (unsigned int) R_METAG_RELBRANCH_PLT)
{
- sym_sec = htab->splt;
+ sym_sec = htab->etab.splt;
sym_value = hh->eh.plt.offset;
}
}
else if (hh->eh.root.type == bfd_link_hash_undefweak)
{
- if (! info->shared)
+ if (! bfd_link_pic (info))
continue;
}
else if (hh->eh.root.type == bfd_link_hash_undefined)
hsh = metag_stub_hash_lookup (&htab->bstab,
stub_name,
- FALSE, FALSE);
+ false, false);
if (hsh != NULL)
{
/* The proper stub has already been created. */
hsh->stub_type = stub_type;
hsh->hh = hh;
hsh->addend = irela->r_addend;
- stub_changed = TRUE;
+ stub_changed = true;
}
/* We're done with the internal relocs, free them. */
/* Ask the linker to do its stuff. */
(*htab->layout_sections_again) ();
- stub_changed = FALSE;
+ stub_changed = false;
}
free (htab->all_local_syms);
- return TRUE;
+ return true;
error_ret_free_local:
free (htab->all_local_syms);
- return FALSE;
+ return false;
}
/* Build all the stubs associated with the current output file. The
stubs are kept in a hash table attached to the main linker hash
table. This function is called via metagelf_finish in the linker. */
-bfd_boolean
+bool
elf_metag_build_stubs (struct bfd_link_info *info)
{
asection *stub_sec;
size = stub_sec->size;
stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
if (stub_sec->contents == NULL && size != 0)
- return FALSE;
+ return false;
stub_sec->size = 0;
}
table = &htab->bstab;
bfd_hash_traverse (table, metag_build_one_stub, info);
- return TRUE;
+ return true;
}
/* Return TRUE if SYM represents a local label symbol. */
-static bfd_boolean
+static bool
elf_metag_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
{
if (name[0] == '$' && name[1] == 'L')
elf_metag_link_hash_table_create
#define elf_backend_relocate_section elf_metag_relocate_section
#define elf_backend_gc_mark_hook elf_metag_gc_mark_hook
-#define elf_backend_gc_sweep_hook elf_metag_gc_sweep_hook
#define elf_backend_check_relocs elf_metag_check_relocs
#define elf_backend_create_dynamic_sections elf_metag_create_dynamic_sections
#define elf_backend_adjust_dynamic_symbol elf_metag_adjust_dynamic_symbol
#define elf_backend_finish_dynamic_sections elf_metag_finish_dynamic_sections
#define elf_backend_size_dynamic_sections elf_metag_size_dynamic_sections
#define elf_backend_omit_section_dynsym \
- ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
-#define elf_backend_post_process_headers elf_metag_post_process_headers
+ _bfd_elf_omit_section_dynsym_all
+#define elf_backend_init_file_header elf_metag_init_file_header
#define elf_backend_reloc_type_class elf_metag_reloc_type_class
#define elf_backend_copy_indirect_symbol elf_metag_copy_indirect_symbol
#define elf_backend_plt_sym_val elf_metag_plt_sym_val
#define elf_backend_can_gc_sections 1
#define elf_backend_can_refcount 1
-#define elf_backend_got_header_size 12
-#define elf_backend_rela_normal 1
+#define elf_backend_rela_normal 1
+#define elf_backend_want_got_plt 1
#define elf_backend_want_got_sym 0
#define elf_backend_want_plt_sym 0
#define elf_backend_plt_readonly 1
+#define elf_backend_dtrel_excludes_plt 1
+#define elf_backend_want_dynrelro 1
#define bfd_elf32_bfd_reloc_type_lookup metag_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup metag_reloc_name_lookup