X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=bfd%2Felf32-metag.c;h=43b76a9f9743b26762c02f85fab128e1b07fa4d1;hb=708cedb722130686607d086085bac963a406580a;hp=6ae3bc06e4d691ab4bc4370d1882fa32359d233d;hpb=a3c629886c2cdaa6ee89513b64c7f989ba30eba3;p=binutils-gdb.git diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c index 6ae3bc06e4d..43b76a9f974 100644 --- a/bfd/elf32-metag.c +++ b/bfd/elf32-metag.c @@ -1,5 +1,5 @@ /* Meta support for 32-bit ELF - Copyright (C) 2013 Free Software Foundation, Inc. + Copyright (C) 2013-2023 Free Software Foundation, Inc. Contributed by Imagination Technologies Ltd. This file is part of BFD, the Binary File Descriptor library. @@ -73,20 +73,18 @@ static const unsigned int plt_pic_entry[] = /* 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. */ @@ -97,92 +95,92 @@ static reloc_howto_type elf_metag_howto_table[] = /* High order 16 bit absolute. */ HOWTO (R_METAG_HIADDR16, /* type */ 16, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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 */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* size */ 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) */ + 4, /* size */ 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) */ + 2, /* size */ 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), @@ -211,194 +209,194 @@ static reloc_howto_type elf_metag_howto_table[] = HOWTO (R_METAG_GNU_VTINHERIT, /* type */ 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 2, /* size */ 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) */ + 2, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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 @@ -407,276 +405,276 @@ static reloc_howto_type elf_metag_howto_table[] = run has to have the data at some particular address. */ HOWTO (R_METAG_COPY, /* type */ 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ + 4, /* size */ 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) */ + 4, /* size */ 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 addend. */ HOWTO (R_METAG_RELATIVE, /* type */ 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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) */ + 4, /* size */ 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 */ }; @@ -701,44 +699,44 @@ struct metag_reloc_map 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 }, }; @@ -787,23 +785,6 @@ struct elf_metag_link_hash_entry 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 @@ -838,22 +819,10 @@ struct elf_metag_link_hash_table /* 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 { @@ -888,16 +857,24 @@ tpoff (struct bfd_link_info *info, bfd_vma address) 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) { unsigned int r_type; r_type = ELF32_R_TYPE (dst->r_info); - BFD_ASSERT (r_type < (unsigned int) R_METAG_MAX); + if (r_type >= (unsigned int) R_METAG_MAX) + { + /* 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 * @@ -929,8 +906,9 @@ metag_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, /* 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)) @@ -1010,13 +988,24 @@ metag_link_hash_newfunc (struct bfd_hash_entry *entry, /* 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; } return entry; } +/* Free the derived linker hash table. */ + +static void +elf_metag_link_hash_table_free (bfd *obfd) +{ + struct elf_metag_link_hash_table *htab + = (struct elf_metag_link_hash_table *) obfd->link.hash; + + bfd_hash_table_free (&htab->bstab); + _bfd_elf_link_hash_table_free (obfd); +} + /* Create the derived linker hash table. The Meta ELF port uses the derived hash table to keep information specific to the Meta ELF linker (without using static variables). */ @@ -1025,9 +1014,9 @@ static struct bfd_link_hash_table * 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_malloc (amt); + htab = bfd_zmalloc (amt); if (htab == NULL) return NULL; @@ -1043,37 +1032,16 @@ elf_metag_link_hash_table_create (bfd *abfd) /* Init the stub hash table too. */ if (!bfd_hash_table_init (&htab->bstab, stub_hash_newfunc, sizeof (struct elf_metag_stub_hash_entry))) - return NULL; - - htab->stub_bfd = NULL; - htab->add_stub_section = NULL; - htab->layout_sections_again = NULL; - htab->stub_group = NULL; - htab->sgot = NULL; - htab->sgotplt = NULL; - htab->srelgot = NULL; - htab->splt = NULL; - htab->srelplt = NULL; - htab->sdynbss = NULL; - htab->srelbss = NULL; - htab->sym_cache.abfd = NULL; - htab->tls_ldm_got.refcount = 0; + { + _bfd_elf_link_hash_table_free (abfd); + return NULL; + } + htab->etab.root.hash_table_free = elf_metag_link_hash_table_free; + htab->etab.dt_pltgot_required = true; return &htab->etab.root; } -/* Free the derived linker hash table. */ - -static void -elf_metag_link_hash_table_free (struct bfd_link_hash_table *btab) -{ - struct elf_metag_link_hash_table *htab - = (struct elf_metag_link_hash_table *) btab; - - bfd_hash_table_free (&htab->bstab); - _bfd_generic_link_hash_table_free (btab); -} - /* Section name for stubs is the associated section name plus this string. */ #define STUB_SUFFIX ".stub" @@ -1152,7 +1120,7 @@ metag_get_stub_entry (const asection *input_section, return NULL; hsh = metag_stub_hash_lookup (&htab->bstab, - stub_name, FALSE, FALSE); + stub_name, false, false); if (hh != NULL) hh->hsh_cache = hsh; @@ -1205,12 +1173,12 @@ metag_add_stub (const char *stub_name, /* 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; } @@ -1223,7 +1191,7 @@ metag_add_stub (const char *stub_name, /* 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)); @@ -1422,9 +1390,9 @@ metag_final_link_relocate (reloc_howto_type *howto, 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 \ @@ -1484,7 +1452,7 @@ going to be the section symbol corresponding to the output 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, @@ -1545,17 +1513,17 @@ elf_metag_relocate_section (bfd *output_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; + bool unresolved_reloc, warned, ignored; RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, r_symndx, symtab_hdr, eh_syms, eh, sec, relocation, - unresolved_reloc, warned); + unresolved_reloc, warned, ignored); name = eh->root.root.string; hh = (struct elf_metag_link_hash_entry *) eh; @@ -1565,7 +1533,7 @@ elf_metag_relocate_section (bfd *output_bfd, 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) @@ -1575,12 +1543,12 @@ elf_metag_relocate_section (bfd *output_bfd, 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 + && !(r_type == R_METAG_RELBRANCH + && (hh == NULL || SYMBOL_CALLS_LOCAL (info, &hh->eh)))) + || (!bfd_link_pic (info) && hh != NULL && hh->eh.dynindx != -1 && !hh->eh.non_got_ref @@ -1590,7 +1558,7 @@ elf_metag_relocate_section (bfd *output_bfd, || 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 @@ -1600,17 +1568,17 @@ elf_metag_relocate_section (bfd *output_bfd, 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); @@ -1633,7 +1601,7 @@ elf_metag_relocate_section (bfd *output_bfd, || ((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; } @@ -1669,8 +1637,7 @@ elf_metag_relocate_section (bfd *output_bfd, 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 @@ -1678,16 +1645,16 @@ elf_metag_relocate_section (bfd *output_bfd, 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 @@ -1696,26 +1663,27 @@ elf_metag_relocate_section (bfd *output_bfd, 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, @@ -1755,18 +1723,18 @@ elf_metag_relocate_section (bfd *output_bfd, 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; @@ -1775,7 +1743,7 @@ elf_metag_relocate_section (bfd *output_bfd, } else bfd_put_32 (output_bfd, relocation, - htab->sgot->contents + off); + htab->etab.sgot->contents + off); } if (off >= (bfd_vma) -2) @@ -1793,17 +1761,19 @@ elf_metag_relocate_section (bfd *output_bfd, 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; @@ -1822,13 +1792,13 @@ elf_metag_relocate_section (bfd *output_bfd, } 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; @@ -1837,15 +1807,15 @@ elf_metag_relocate_section (bfd *output_bfd, 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) @@ -1853,36 +1823,43 @@ elf_metag_relocate_section (bfd *output_bfd, 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; @@ -1893,8 +1870,8 @@ elf_metag_relocate_section (bfd *output_bfd, 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) @@ -1903,12 +1880,12 @@ elf_metag_relocate_section (bfd *output_bfd, 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; } @@ -1929,20 +1906,22 @@ elf_metag_relocate_section (bfd *output_bfd, 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); @@ -1951,7 +1930,7 @@ elf_metag_relocate_section (bfd *output_bfd, { bfd_vma off; - if (htab->sgot == NULL) + if (htab->etab.sgot == NULL) abort(); off = htab->tls_ldm_got.offset; if (off & 1) @@ -1962,13 +1941,13 @@ elf_metag_relocate_section (bfd *output_bfd, 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; } @@ -1991,15 +1970,14 @@ elf_metag_relocate_section (bfd *output_bfd, 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: @@ -2020,21 +1998,18 @@ elf_metag_relocate_section (bfd *output_bfd, } 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; @@ -2044,54 +2019,36 @@ elf_metag_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) /* 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_section_by_name (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; + return false; - htab->splt = bfd_get_section_by_name (abfd, ".plt"); - htab->srelplt = bfd_get_section_by_name (abfd, ".rela.plt"); + htab->etab.hgot = eh; - htab->srelgot = bfd_get_section_by_name (abfd, ".rela.got"); - - htab->sdynbss = bfd_get_section_by_name (abfd, ".dynbss"); - htab->srelbss = bfd_get_section_by_name (abfd, ".rela.bss"); - - return TRUE; + return true; } /* Look through the relocs for a section during the first phase, and @@ -2099,7 +2056,7 @@ elf_metag_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) 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, @@ -2114,8 +2071,8 @@ elf_metag_check_relocs (bfd *abfd, 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; @@ -2124,21 +2081,32 @@ elf_metag_check_relocs (bfd *abfd, sreloc = NULL; if (htab == NULL) - return FALSE; + return false; rel_end = relocs + sec->reloc_count; for (rel = relocs; rel < rel_end; rel++) { int r_type; struct elf_metag_link_hash_entry *hh; + Elf_Internal_Sym *isym; unsigned long r_symndx; r_symndx = ELF32_R_SYM (rel->r_info); r_type = ELF32_R_TYPE (rel->r_info); if (r_symndx < symtab_hdr->sh_info) - hh = NULL; + { + /* A local symbol. */ + isym = bfd_sym_from_r_symndx (&htab->etab.sym_cache, + abfd, r_symndx); + if (isym == NULL) + return false; + + hh = NULL; + } else { + isym = NULL; + hh = (struct elf_metag_link_hash_entry *) eh_syms[r_symndx - symtab_hdr->sh_info]; while (hh->eh.root.type == bfd_link_hash_indirect @@ -2147,14 +2115,14 @@ elf_metag_check_relocs (bfd *abfd, } /* 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. */ @@ -2167,7 +2135,7 @@ elf_metag_check_relocs (bfd *abfd, if (dynobj == NULL) htab->etab.dynobj = dynobj = abfd; if (!elf_metag_create_dynamic_sections (dynobj, info)) - return FALSE; + return false; break; default: @@ -2216,7 +2184,7 @@ elf_metag_check_relocs (bfd *abfd, 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); @@ -2262,12 +2230,35 @@ elf_metag_check_relocs (bfd *abfd, hh->eh.plt.refcount += 1; break; - case R_METAG_ADDR32: case R_METAG_HIADDR16: case R_METAG_LOADDR16: + /* Let's help debug shared library creation. These relocs + 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 (bfd_link_pic (info) + && (sec->flags & SEC_ALLOC) != 0 + && (sec->flags & SEC_READONLY) != 0) + { + const char *name; + + if (hh) + name = hh->eh.root.root.string; + else + name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); + _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; + } + + /* 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; @@ -2292,21 +2283,21 @@ elf_metag_check_relocs (bfd *abfd, 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; @@ -2317,12 +2308,12 @@ elf_metag_check_relocs (bfd *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; @@ -2331,44 +2322,38 @@ elf_metag_check_relocs (bfd *abfd, /* 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. */ asection *sr; void *vpp; - Elf_Internal_Sym *isym; - - isym = bfd_sym_from_r_symndx (&htab->sym_cache, - abfd, r_symndx); - if (isym == NULL) - return FALSE; sr = bfd_section_from_elf_index (abfd, isym->st_shndx); if (sr == NULL) 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; @@ -2377,21 +2362,19 @@ elf_metag_check_relocs (bfd *abfd, 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. */ @@ -2406,41 +2389,6 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info, 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) { @@ -2457,14 +2405,12 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info, 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, @@ -2486,7 +2432,7 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info, eh->needs_plt = 0; } - return TRUE; + return true; } else eh->plt.offset = (bfd_vma) -1; @@ -2494,15 +2440,14 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info, /* 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 @@ -2512,42 +2457,27 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info, 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; + 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; - } - - /* 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; - } - - if (eh->size == 0) - { - (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"), - hh->eh.root.root.string); - return TRUE; + return true; } /* We must allocate the symbol in our .dynbss section, which will @@ -2565,30 +2495,37 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info, /* 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_ALLOC) != 0) + 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 (eh, s); + 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; @@ -2605,12 +2542,12 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) && !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. */ @@ -2624,7 +2561,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) 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; @@ -2636,10 +2573,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) /* 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 { @@ -2656,7 +2593,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) 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. @@ -2665,10 +2602,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) && !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; @@ -2680,48 +2617,49 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) 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. */ @@ -2729,7 +2667,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) && !eh->forced_local) { if (! bfd_elf_link_record_dynamic_symbol (info, eh)) - return FALSE; + return false; } } } @@ -2751,7 +2689,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) && !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 @@ -2760,54 +2698,25 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) 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) { @@ -2815,7 +2724,7 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, bfd *dynobj; bfd *ibfd; asection *s; - bfd_boolean relocs; + bool relocs; htab = metag_link_hash_table (info); dynobj = htab->etab.dynobj; @@ -2825,9 +2734,9 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, 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_section_by_name (dynobj, ".interp"); + s = bfd_get_linker_section (dynobj, ".interp"); if (s == NULL) abort (); s->size = sizeof ELF_DYNAMIC_INTERPRETER; @@ -2837,7 +2746,7 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* Set up .got offsets for local syms, and space for local dynamic relocs. */ - for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) + for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) { bfd_signed_vma *local_got; bfd_signed_vma *end_local_got; @@ -2851,12 +2760,12 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, 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)) @@ -2884,8 +2793,8 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, 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) @@ -2895,7 +2804,7 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* 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 @@ -2908,9 +2817,9 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, { /* 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; @@ -2921,31 +2830,32 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* 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 { @@ -2974,7 +2884,7 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* 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; @@ -2991,61 +2901,13 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, } } - 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, @@ -3072,9 +2934,9 @@ elf_metag_finish_dynamic_symbol (bfd *output_bfd, 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 @@ -3096,7 +2958,7 @@ elf_metag_finish_dynamic_symbol (bfd *output_bfd, 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] @@ -3152,7 +3014,7 @@ elf_metag_finish_dynamic_symbol (bfd *output_bfd, + 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); @@ -3172,15 +3034,15 @@ elf_metag_finish_dynamic_symbol (bfd *output_bfd, 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) { @@ -3193,13 +3055,13 @@ elf_metag_finish_dynamic_symbol (bfd *output_bfd, { 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); } @@ -3214,13 +3076,15 @@ elf_metag_finish_dynamic_symbol (bfd *output_bfd, || 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); } @@ -3233,25 +3097,31 @@ elf_metag_finish_dynamic_symbol (bfd *output_bfd, 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 ATTRIBUTE_UNUSED) +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. */ + 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 dynamic linker, before writing them out. */ static enum elf_reloc_type_class -elf_metag_reloc_type_class (const Elf_Internal_Rela *rela) +elf_metag_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, + const asection *rel_sec ATTRIBUTE_UNUSED, + const Elf_Internal_Rela *rela) { switch ((int) ELF32_R_TYPE (rela->r_info)) { @@ -3268,7 +3138,7 @@ elf_metag_reloc_type_class (const Elf_Internal_Rela *rela) /* Finish up the dynamic sections. */ -static bfd_boolean +static bool elf_metag_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) { @@ -3279,7 +3149,7 @@ elf_metag_finish_dynamic_sections (bfd *output_bfd, htab = metag_link_hash_table (info); dynobj = htab->etab.dynobj; - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); + sdyn = bfd_get_linker_section (dynobj, ".dynamic"); if (htab->etab.dynamic_sections_created) { @@ -3304,59 +3174,35 @@ elf_metag_finish_dynamic_sections (bfd *output_bfd, 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, @@ -3387,23 +3233,23 @@ elf_metag_finish_dynamic_sections (bfd *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 @@ -3427,131 +3273,6 @@ elf_metag_gc_mark_hook (asection *sec, 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 @@ -3583,7 +3304,7 @@ metag_type_of_stub (asection *input_sec, 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; @@ -3602,8 +3323,8 @@ metag_type_of_stub (asection *input_sec, #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; @@ -3611,9 +3332,19 @@ metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_U 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; @@ -3666,17 +3397,17 @@ metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_U 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; @@ -3691,7 +3422,7 @@ metag_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_UN 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 @@ -3703,16 +3434,16 @@ elf_metag_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info) { 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. */ for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0; input_bfd != NULL; - input_bfd = input_bfd->link_next) + input_bfd = input_bfd->link.next) { bfd_count += 1; for (section = input_bfd->sections; @@ -3806,7 +3537,7 @@ elf_metag_next_input_section (struct bfd_link_info *info, asection *isec) 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 @@ -3819,7 +3550,7 @@ group_sections (struct elf_metag_link_hash_table *htab, asection *curr; asection *prev; bfd_size_type total; - bfd_boolean big_sec; + bool big_sec; curr = tail; total = tail->size; @@ -3885,7 +3616,7 @@ get_local_syms (bfd *output_bfd ATTRIBUTE_UNUSED, bfd *input_bfd, /* 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) @@ -3894,7 +3625,7 @@ get_local_syms (bfd *output_bfd ATTRIBUTE_UNUSED, bfd *input_bfd, /* Walk over all the input BFDs, swapping in local symbols. */ for (bfd_indx = 0; input_bfd != NULL; - input_bfd = input_bfd->link_next, bfd_indx++) + input_bfd = input_bfd->link.next, bfd_indx++) { Elf_Internal_Shdr *symtab_hdr; @@ -3930,7 +3661,7 @@ instruction. */ /* 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, @@ -3938,8 +3669,8 @@ elf_metag_size_stubs(bfd *output_bfd, bfd *stub_bfd, 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. */ @@ -3972,14 +3703,14 @@ elf_metag_size_stubs(bfd *output_bfd, bfd *stub_bfd, 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; } @@ -3991,7 +3722,7 @@ elf_metag_size_stubs(bfd *output_bfd, bfd *stub_bfd, for (input_bfd = info->input_bfds, bfd_indx = 0; input_bfd != NULL; - input_bfd = input_bfd->link_next, bfd_indx++) + input_bfd = input_bfd->link.next, bfd_indx++) { Elf_Internal_Shdr *symtab_hdr; asection *section; @@ -4111,7 +3842,7 @@ elf_metag_size_stubs(bfd *output_bfd, bfd *stub_bfd, && 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; } @@ -4124,7 +3855,7 @@ elf_metag_size_stubs(bfd *output_bfd, bfd *stub_bfd, } 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) @@ -4157,7 +3888,7 @@ elf_metag_size_stubs(bfd *output_bfd, bfd *stub_bfd, hsh = metag_stub_hash_lookup (&htab->bstab, stub_name, - FALSE, FALSE); + false, false); if (hsh != NULL) { /* The proper stub has already been created. */ @@ -4176,7 +3907,7 @@ elf_metag_size_stubs(bfd *output_bfd, bfd *stub_bfd, 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. */ @@ -4199,22 +3930,22 @@ elf_metag_size_stubs(bfd *output_bfd, bfd *stub_bfd, /* 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; @@ -4233,7 +3964,7 @@ elf_metag_build_stubs (struct bfd_link_info *info) 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; } @@ -4241,12 +3972,12 @@ elf_metag_build_stubs (struct bfd_link_info *info) 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') @@ -4267,11 +3998,10 @@ elf_metag_plt_sym_val (bfd_vma i, const asection *plt, #define ELF_ARCH bfd_arch_metag #define ELF_TARGET_ID METAG_ELF_DATA #define ELF_MACHINE_CODE EM_METAG -#define ELF_MINPAGESIZE 0x1000 -#define ELF_MAXPAGESIZE 0x4000 +#define ELF_MAXPAGESIZE 0x4000 #define ELF_COMMONPAGESIZE 0x1000 -#define TARGET_LITTLE_SYM bfd_elf32_metag_vec +#define TARGET_LITTLE_SYM metag_elf32_vec #define TARGET_LITTLE_NAME "elf32-metag" #define elf_symbol_leading_char '_' @@ -4282,10 +4012,8 @@ elf_metag_plt_sym_val (bfd_vma i, const asection *plt, #define bfd_elf32_bfd_is_local_label_name elf_metag_is_local_label_name #define bfd_elf32_bfd_link_hash_table_create \ elf_metag_link_hash_table_create -#define bfd_elf32_bfd_link_hash_table_free elf_metag_link_hash_table_free #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 @@ -4293,19 +4021,21 @@ elf_metag_plt_sym_val (bfd_vma i, const asection *plt, #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