xref: /dragonfly/contrib/gdb-7/bfd/elf64-x86-64.c (revision ef5ccd6c)
1c50c785cSJohn Marino /* X86-64 specific support for ELF
2cf7f2e2dSJohn Marino    Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
3a45ae5f8SJohn Marino    2010, 2011, 2012
4a45ae5f8SJohn Marino    Free Software Foundation, Inc.
55796c8dcSSimon Schubert    Contributed by Jan Hubicka <jh@suse.cz>.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This file is part of BFD, the Binary File Descriptor library.
85796c8dcSSimon Schubert 
95796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
105796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
115796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
125796c8dcSSimon Schubert    (at your option) any later version.
135796c8dcSSimon Schubert 
145796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
155796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
165796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
175796c8dcSSimon Schubert    GNU General Public License for more details.
185796c8dcSSimon Schubert 
195796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
205796c8dcSSimon Schubert    along with this program; if not, write to the Free Software
215796c8dcSSimon Schubert    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
225796c8dcSSimon Schubert    MA 02110-1301, USA.  */
235796c8dcSSimon Schubert 
245796c8dcSSimon Schubert #include "sysdep.h"
255796c8dcSSimon Schubert #include "bfd.h"
265796c8dcSSimon Schubert #include "bfdlink.h"
275796c8dcSSimon Schubert #include "libbfd.h"
285796c8dcSSimon Schubert #include "elf-bfd.h"
29*ef5ccd6cSJohn Marino #include "elf-nacl.h"
305796c8dcSSimon Schubert #include "bfd_stdint.h"
315796c8dcSSimon Schubert #include "objalloc.h"
325796c8dcSSimon Schubert #include "hashtab.h"
33a45ae5f8SJohn Marino #include "dwarf2.h"
34a45ae5f8SJohn Marino #include "libiberty.h"
355796c8dcSSimon Schubert 
365796c8dcSSimon Schubert #include "elf/x86-64.h"
375796c8dcSSimon Schubert 
38a45ae5f8SJohn Marino #ifdef CORE_HEADER
39a45ae5f8SJohn Marino #include <stdarg.h>
40a45ae5f8SJohn Marino #include CORE_HEADER
41a45ae5f8SJohn Marino #endif
42a45ae5f8SJohn Marino 
435796c8dcSSimon Schubert /* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
445796c8dcSSimon Schubert #define MINUS_ONE (~ (bfd_vma) 0)
455796c8dcSSimon Schubert 
46c50c785cSJohn Marino /* Since both 32-bit and 64-bit x86-64 encode relocation type in the
47c50c785cSJohn Marino    identical manner, we use ELF32_R_TYPE instead of ELF64_R_TYPE to get
48c50c785cSJohn Marino    relocation type.  We also use ELF_ST_TYPE instead of ELF64_ST_TYPE
49c50c785cSJohn Marino    since they are the same.  */
50c50c785cSJohn Marino 
51c50c785cSJohn Marino #define ABI_64_P(abfd) \
52c50c785cSJohn Marino   (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
53c50c785cSJohn Marino 
545796c8dcSSimon Schubert /* The relocation "howto" table.  Order of fields:
555796c8dcSSimon Schubert    type, rightshift, size, bitsize, pc_relative, bitpos, complain_on_overflow,
565796c8dcSSimon Schubert    special_function, name, partial_inplace, src_mask, dst_mask, pcrel_offset.  */
575796c8dcSSimon Schubert static reloc_howto_type x86_64_elf_howto_table[] =
585796c8dcSSimon Schubert {
595796c8dcSSimon Schubert   HOWTO(R_X86_64_NONE, 0, 0, 0, FALSE, 0, complain_overflow_dont,
605796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_NONE",	FALSE, 0x00000000, 0x00000000,
615796c8dcSSimon Schubert 	FALSE),
625796c8dcSSimon Schubert   HOWTO(R_X86_64_64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
635796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_64", FALSE, MINUS_ONE, MINUS_ONE,
645796c8dcSSimon Schubert 	FALSE),
655796c8dcSSimon Schubert   HOWTO(R_X86_64_PC32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
665796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_PC32", FALSE, 0xffffffff, 0xffffffff,
675796c8dcSSimon Schubert 	TRUE),
685796c8dcSSimon Schubert   HOWTO(R_X86_64_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
695796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_GOT32", FALSE, 0xffffffff, 0xffffffff,
705796c8dcSSimon Schubert 	FALSE),
715796c8dcSSimon Schubert   HOWTO(R_X86_64_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
725796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_PLT32", FALSE, 0xffffffff, 0xffffffff,
735796c8dcSSimon Schubert 	TRUE),
745796c8dcSSimon Schubert   HOWTO(R_X86_64_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
755796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_COPY", FALSE, 0xffffffff, 0xffffffff,
765796c8dcSSimon Schubert 	FALSE),
775796c8dcSSimon Schubert   HOWTO(R_X86_64_GLOB_DAT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
785796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", FALSE, MINUS_ONE,
795796c8dcSSimon Schubert 	MINUS_ONE, FALSE),
805796c8dcSSimon Schubert   HOWTO(R_X86_64_JUMP_SLOT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
815796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", FALSE, MINUS_ONE,
825796c8dcSSimon Schubert 	MINUS_ONE, FALSE),
835796c8dcSSimon Schubert   HOWTO(R_X86_64_RELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
845796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_RELATIVE", FALSE, MINUS_ONE,
855796c8dcSSimon Schubert 	MINUS_ONE, FALSE),
865796c8dcSSimon Schubert   HOWTO(R_X86_64_GOTPCREL, 0, 2, 32, TRUE, 0, complain_overflow_signed,
875796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", FALSE, 0xffffffff,
885796c8dcSSimon Schubert 	0xffffffff, TRUE),
895796c8dcSSimon Schubert   HOWTO(R_X86_64_32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned,
905796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_32", FALSE, 0xffffffff, 0xffffffff,
915796c8dcSSimon Schubert 	FALSE),
925796c8dcSSimon Schubert   HOWTO(R_X86_64_32S, 0, 2, 32, FALSE, 0, complain_overflow_signed,
935796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_32S", FALSE, 0xffffffff, 0xffffffff,
945796c8dcSSimon Schubert 	FALSE),
955796c8dcSSimon Schubert   HOWTO(R_X86_64_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
965796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_16", FALSE, 0xffff, 0xffff, FALSE),
975796c8dcSSimon Schubert   HOWTO(R_X86_64_PC16,0, 1, 16, TRUE, 0, complain_overflow_bitfield,
985796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_PC16", FALSE, 0xffff, 0xffff, TRUE),
995796c8dcSSimon Schubert   HOWTO(R_X86_64_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
1005796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_8", FALSE, 0xff, 0xff, FALSE),
1015796c8dcSSimon Schubert   HOWTO(R_X86_64_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed,
1025796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_PC8", FALSE, 0xff, 0xff, TRUE),
1035796c8dcSSimon Schubert   HOWTO(R_X86_64_DTPMOD64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
1045796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_DTPMOD64", FALSE, MINUS_ONE,
1055796c8dcSSimon Schubert 	MINUS_ONE, FALSE),
1065796c8dcSSimon Schubert   HOWTO(R_X86_64_DTPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
1075796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_DTPOFF64", FALSE, MINUS_ONE,
1085796c8dcSSimon Schubert 	MINUS_ONE, FALSE),
1095796c8dcSSimon Schubert   HOWTO(R_X86_64_TPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
1105796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_TPOFF64", FALSE, MINUS_ONE,
1115796c8dcSSimon Schubert 	MINUS_ONE, FALSE),
1125796c8dcSSimon Schubert   HOWTO(R_X86_64_TLSGD, 0, 2, 32, TRUE, 0, complain_overflow_signed,
1135796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_TLSGD", FALSE, 0xffffffff,
1145796c8dcSSimon Schubert 	0xffffffff, TRUE),
1155796c8dcSSimon Schubert   HOWTO(R_X86_64_TLSLD, 0, 2, 32, TRUE, 0, complain_overflow_signed,
1165796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_TLSLD", FALSE, 0xffffffff,
1175796c8dcSSimon Schubert 	0xffffffff, TRUE),
1185796c8dcSSimon Schubert   HOWTO(R_X86_64_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
1195796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_DTPOFF32", FALSE, 0xffffffff,
1205796c8dcSSimon Schubert 	0xffffffff, FALSE),
1215796c8dcSSimon Schubert   HOWTO(R_X86_64_GOTTPOFF, 0, 2, 32, TRUE, 0, complain_overflow_signed,
1225796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_GOTTPOFF", FALSE, 0xffffffff,
1235796c8dcSSimon Schubert 	0xffffffff, TRUE),
1245796c8dcSSimon Schubert   HOWTO(R_X86_64_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
1255796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_TPOFF32", FALSE, 0xffffffff,
1265796c8dcSSimon Schubert 	0xffffffff, FALSE),
1275796c8dcSSimon Schubert   HOWTO(R_X86_64_PC64, 0, 4, 64, TRUE, 0, complain_overflow_bitfield,
1285796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_PC64", FALSE, MINUS_ONE, MINUS_ONE,
1295796c8dcSSimon Schubert 	TRUE),
1305796c8dcSSimon Schubert   HOWTO(R_X86_64_GOTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
1315796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_GOTOFF64",
1325796c8dcSSimon Schubert 	FALSE, MINUS_ONE, MINUS_ONE, FALSE),
1335796c8dcSSimon Schubert   HOWTO(R_X86_64_GOTPC32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
1345796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_GOTPC32",
1355796c8dcSSimon Schubert 	FALSE, 0xffffffff, 0xffffffff, TRUE),
1365796c8dcSSimon Schubert   HOWTO(R_X86_64_GOT64, 0, 4, 64, FALSE, 0, complain_overflow_signed,
1375796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_GOT64", FALSE, MINUS_ONE, MINUS_ONE,
1385796c8dcSSimon Schubert 	FALSE),
1395796c8dcSSimon Schubert   HOWTO(R_X86_64_GOTPCREL64, 0, 4, 64, TRUE, 0, complain_overflow_signed,
1405796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_GOTPCREL64", FALSE, MINUS_ONE,
1415796c8dcSSimon Schubert 	MINUS_ONE, TRUE),
1425796c8dcSSimon Schubert   HOWTO(R_X86_64_GOTPC64, 0, 4, 64, TRUE, 0, complain_overflow_signed,
1435796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_GOTPC64",
1445796c8dcSSimon Schubert 	FALSE, MINUS_ONE, MINUS_ONE, TRUE),
1455796c8dcSSimon Schubert   HOWTO(R_X86_64_GOTPLT64, 0, 4, 64, FALSE, 0, complain_overflow_signed,
1465796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_GOTPLT64", FALSE, MINUS_ONE,
1475796c8dcSSimon Schubert 	MINUS_ONE, FALSE),
1485796c8dcSSimon Schubert   HOWTO(R_X86_64_PLTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_signed,
1495796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_PLTOFF64", FALSE, MINUS_ONE,
1505796c8dcSSimon Schubert 	MINUS_ONE, FALSE),
151*ef5ccd6cSJohn Marino   HOWTO(R_X86_64_SIZE32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned,
152*ef5ccd6cSJohn Marino 	bfd_elf_generic_reloc, "R_X86_64_SIZE32", FALSE, 0xffffffff, 0xffffffff,
153*ef5ccd6cSJohn Marino 	FALSE),
154*ef5ccd6cSJohn Marino   HOWTO(R_X86_64_SIZE64, 0, 4, 64, FALSE, 0, complain_overflow_unsigned,
155*ef5ccd6cSJohn Marino 	bfd_elf_generic_reloc, "R_X86_64_SIZE64", FALSE, MINUS_ONE, MINUS_ONE,
156*ef5ccd6cSJohn Marino 	FALSE),
1575796c8dcSSimon Schubert   HOWTO(R_X86_64_GOTPC32_TLSDESC, 0, 2, 32, TRUE, 0,
1585796c8dcSSimon Schubert 	complain_overflow_bitfield, bfd_elf_generic_reloc,
1595796c8dcSSimon Schubert 	"R_X86_64_GOTPC32_TLSDESC",
1605796c8dcSSimon Schubert 	FALSE, 0xffffffff, 0xffffffff, TRUE),
1615796c8dcSSimon Schubert   HOWTO(R_X86_64_TLSDESC_CALL, 0, 0, 0, FALSE, 0,
1625796c8dcSSimon Schubert 	complain_overflow_dont, bfd_elf_generic_reloc,
1635796c8dcSSimon Schubert 	"R_X86_64_TLSDESC_CALL",
1645796c8dcSSimon Schubert 	FALSE, 0, 0, FALSE),
1655796c8dcSSimon Schubert   HOWTO(R_X86_64_TLSDESC, 0, 4, 64, FALSE, 0,
1665796c8dcSSimon Schubert 	complain_overflow_bitfield, bfd_elf_generic_reloc,
1675796c8dcSSimon Schubert 	"R_X86_64_TLSDESC",
1685796c8dcSSimon Schubert 	FALSE, MINUS_ONE, MINUS_ONE, FALSE),
1695796c8dcSSimon Schubert   HOWTO(R_X86_64_IRELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
1705796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_X86_64_IRELATIVE", FALSE, MINUS_ONE,
1715796c8dcSSimon Schubert 	MINUS_ONE, FALSE),
172a45ae5f8SJohn Marino   HOWTO(R_X86_64_RELATIVE64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
173a45ae5f8SJohn Marino 	bfd_elf_generic_reloc, "R_X86_64_RELATIVE64", FALSE, MINUS_ONE,
174a45ae5f8SJohn Marino 	MINUS_ONE, FALSE),
1755796c8dcSSimon Schubert 
1765796c8dcSSimon Schubert   /* We have a gap in the reloc numbers here.
1775796c8dcSSimon Schubert      R_X86_64_standard counts the number up to this point, and
1785796c8dcSSimon Schubert      R_X86_64_vt_offset is the value to subtract from a reloc type of
1795796c8dcSSimon Schubert      R_X86_64_GNU_VT* to form an index into this table.  */
180*ef5ccd6cSJohn Marino #define R_X86_64_standard (R_X86_64_RELATIVE64 + 1)
1815796c8dcSSimon Schubert #define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard)
1825796c8dcSSimon Schubert 
1835796c8dcSSimon Schubert /* GNU extension to record C++ vtable hierarchy.  */
1845796c8dcSSimon Schubert   HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, FALSE, 0, complain_overflow_dont,
1855796c8dcSSimon Schubert 	 NULL, "R_X86_64_GNU_VTINHERIT", FALSE, 0, 0, FALSE),
1865796c8dcSSimon Schubert 
1875796c8dcSSimon Schubert /* GNU extension to record C++ vtable member usage.  */
1885796c8dcSSimon Schubert   HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, FALSE, 0, complain_overflow_dont,
1895796c8dcSSimon Schubert 	 _bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", FALSE, 0, 0,
190a45ae5f8SJohn Marino 	 FALSE),
191a45ae5f8SJohn Marino 
192a45ae5f8SJohn Marino /* Use complain_overflow_bitfield on R_X86_64_32 for x32.  */
193a45ae5f8SJohn Marino   HOWTO(R_X86_64_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
194a45ae5f8SJohn Marino 	bfd_elf_generic_reloc, "R_X86_64_32", FALSE, 0xffffffff, 0xffffffff,
1955796c8dcSSimon Schubert 	FALSE)
1965796c8dcSSimon Schubert };
1975796c8dcSSimon Schubert 
1985796c8dcSSimon Schubert #define IS_X86_64_PCREL_TYPE(TYPE)	\
1995796c8dcSSimon Schubert   (   ((TYPE) == R_X86_64_PC8)		\
2005796c8dcSSimon Schubert    || ((TYPE) == R_X86_64_PC16)		\
2015796c8dcSSimon Schubert    || ((TYPE) == R_X86_64_PC32)		\
2025796c8dcSSimon Schubert    || ((TYPE) == R_X86_64_PC64))
2035796c8dcSSimon Schubert 
2045796c8dcSSimon Schubert /* Map BFD relocs to the x86_64 elf relocs.  */
2055796c8dcSSimon Schubert struct elf_reloc_map
2065796c8dcSSimon Schubert {
2075796c8dcSSimon Schubert   bfd_reloc_code_real_type bfd_reloc_val;
2085796c8dcSSimon Schubert   unsigned char elf_reloc_val;
2095796c8dcSSimon Schubert };
2105796c8dcSSimon Schubert 
2115796c8dcSSimon Schubert static const struct elf_reloc_map x86_64_reloc_map[] =
2125796c8dcSSimon Schubert {
2135796c8dcSSimon Schubert   { BFD_RELOC_NONE,		R_X86_64_NONE, },
2145796c8dcSSimon Schubert   { BFD_RELOC_64,		R_X86_64_64,   },
2155796c8dcSSimon Schubert   { BFD_RELOC_32_PCREL,		R_X86_64_PC32, },
2165796c8dcSSimon Schubert   { BFD_RELOC_X86_64_GOT32,	R_X86_64_GOT32,},
2175796c8dcSSimon Schubert   { BFD_RELOC_X86_64_PLT32,	R_X86_64_PLT32,},
2185796c8dcSSimon Schubert   { BFD_RELOC_X86_64_COPY,	R_X86_64_COPY, },
2195796c8dcSSimon Schubert   { BFD_RELOC_X86_64_GLOB_DAT,	R_X86_64_GLOB_DAT, },
2205796c8dcSSimon Schubert   { BFD_RELOC_X86_64_JUMP_SLOT, R_X86_64_JUMP_SLOT, },
2215796c8dcSSimon Schubert   { BFD_RELOC_X86_64_RELATIVE,	R_X86_64_RELATIVE, },
2225796c8dcSSimon Schubert   { BFD_RELOC_X86_64_GOTPCREL,	R_X86_64_GOTPCREL, },
2235796c8dcSSimon Schubert   { BFD_RELOC_32,		R_X86_64_32, },
2245796c8dcSSimon Schubert   { BFD_RELOC_X86_64_32S,	R_X86_64_32S, },
2255796c8dcSSimon Schubert   { BFD_RELOC_16,		R_X86_64_16, },
2265796c8dcSSimon Schubert   { BFD_RELOC_16_PCREL,		R_X86_64_PC16, },
2275796c8dcSSimon Schubert   { BFD_RELOC_8,		R_X86_64_8, },
2285796c8dcSSimon Schubert   { BFD_RELOC_8_PCREL,		R_X86_64_PC8, },
2295796c8dcSSimon Schubert   { BFD_RELOC_X86_64_DTPMOD64,	R_X86_64_DTPMOD64, },
2305796c8dcSSimon Schubert   { BFD_RELOC_X86_64_DTPOFF64,	R_X86_64_DTPOFF64, },
2315796c8dcSSimon Schubert   { BFD_RELOC_X86_64_TPOFF64,	R_X86_64_TPOFF64, },
2325796c8dcSSimon Schubert   { BFD_RELOC_X86_64_TLSGD,	R_X86_64_TLSGD, },
2335796c8dcSSimon Schubert   { BFD_RELOC_X86_64_TLSLD,	R_X86_64_TLSLD, },
2345796c8dcSSimon Schubert   { BFD_RELOC_X86_64_DTPOFF32,	R_X86_64_DTPOFF32, },
2355796c8dcSSimon Schubert   { BFD_RELOC_X86_64_GOTTPOFF,	R_X86_64_GOTTPOFF, },
2365796c8dcSSimon Schubert   { BFD_RELOC_X86_64_TPOFF32,	R_X86_64_TPOFF32, },
2375796c8dcSSimon Schubert   { BFD_RELOC_64_PCREL,		R_X86_64_PC64, },
2385796c8dcSSimon Schubert   { BFD_RELOC_X86_64_GOTOFF64,	R_X86_64_GOTOFF64, },
2395796c8dcSSimon Schubert   { BFD_RELOC_X86_64_GOTPC32,	R_X86_64_GOTPC32, },
2405796c8dcSSimon Schubert   { BFD_RELOC_X86_64_GOT64,	R_X86_64_GOT64, },
2415796c8dcSSimon Schubert   { BFD_RELOC_X86_64_GOTPCREL64,R_X86_64_GOTPCREL64, },
2425796c8dcSSimon Schubert   { BFD_RELOC_X86_64_GOTPC64,	R_X86_64_GOTPC64, },
2435796c8dcSSimon Schubert   { BFD_RELOC_X86_64_GOTPLT64,	R_X86_64_GOTPLT64, },
2445796c8dcSSimon Schubert   { BFD_RELOC_X86_64_PLTOFF64,	R_X86_64_PLTOFF64, },
245*ef5ccd6cSJohn Marino   { BFD_RELOC_SIZE32,		R_X86_64_SIZE32, },
246*ef5ccd6cSJohn Marino   { BFD_RELOC_SIZE64,		R_X86_64_SIZE64, },
2475796c8dcSSimon Schubert   { BFD_RELOC_X86_64_GOTPC32_TLSDESC, R_X86_64_GOTPC32_TLSDESC, },
2485796c8dcSSimon Schubert   { BFD_RELOC_X86_64_TLSDESC_CALL, R_X86_64_TLSDESC_CALL, },
2495796c8dcSSimon Schubert   { BFD_RELOC_X86_64_TLSDESC,	R_X86_64_TLSDESC, },
2505796c8dcSSimon Schubert   { BFD_RELOC_X86_64_IRELATIVE,	R_X86_64_IRELATIVE, },
2515796c8dcSSimon Schubert   { BFD_RELOC_VTABLE_INHERIT,	R_X86_64_GNU_VTINHERIT, },
2525796c8dcSSimon Schubert   { BFD_RELOC_VTABLE_ENTRY,	R_X86_64_GNU_VTENTRY, },
2535796c8dcSSimon Schubert };
2545796c8dcSSimon Schubert 
2555796c8dcSSimon Schubert static reloc_howto_type *
elf_x86_64_rtype_to_howto(bfd * abfd,unsigned r_type)256c50c785cSJohn Marino elf_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type)
2575796c8dcSSimon Schubert {
2585796c8dcSSimon Schubert   unsigned i;
2595796c8dcSSimon Schubert 
260a45ae5f8SJohn Marino   if (r_type == (unsigned int) R_X86_64_32)
261a45ae5f8SJohn Marino     {
262a45ae5f8SJohn Marino       if (ABI_64_P (abfd))
263a45ae5f8SJohn Marino 	i = r_type;
264a45ae5f8SJohn Marino       else
265a45ae5f8SJohn Marino 	i = ARRAY_SIZE (x86_64_elf_howto_table) - 1;
266a45ae5f8SJohn Marino     }
267a45ae5f8SJohn Marino   else if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT
2685796c8dcSSimon Schubert 	   || r_type >= (unsigned int) R_X86_64_max)
2695796c8dcSSimon Schubert     {
2705796c8dcSSimon Schubert       if (r_type >= (unsigned int) R_X86_64_standard)
2715796c8dcSSimon Schubert 	{
2725796c8dcSSimon Schubert 	  (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
2735796c8dcSSimon Schubert 				 abfd, (int) r_type);
2745796c8dcSSimon Schubert 	  r_type = R_X86_64_NONE;
2755796c8dcSSimon Schubert 	}
2765796c8dcSSimon Schubert       i = r_type;
2775796c8dcSSimon Schubert     }
2785796c8dcSSimon Schubert   else
2795796c8dcSSimon Schubert     i = r_type - (unsigned int) R_X86_64_vt_offset;
2805796c8dcSSimon Schubert   BFD_ASSERT (x86_64_elf_howto_table[i].type == r_type);
2815796c8dcSSimon Schubert   return &x86_64_elf_howto_table[i];
2825796c8dcSSimon Schubert }
2835796c8dcSSimon Schubert 
2845796c8dcSSimon Schubert /* Given a BFD reloc type, return a HOWTO structure.  */
2855796c8dcSSimon Schubert static reloc_howto_type *
elf_x86_64_reloc_type_lookup(bfd * abfd,bfd_reloc_code_real_type code)286c50c785cSJohn Marino elf_x86_64_reloc_type_lookup (bfd *abfd,
2875796c8dcSSimon Schubert 			      bfd_reloc_code_real_type code)
2885796c8dcSSimon Schubert {
2895796c8dcSSimon Schubert   unsigned int i;
2905796c8dcSSimon Schubert 
2915796c8dcSSimon Schubert   for (i = 0; i < sizeof (x86_64_reloc_map) / sizeof (struct elf_reloc_map);
2925796c8dcSSimon Schubert        i++)
2935796c8dcSSimon Schubert     {
2945796c8dcSSimon Schubert       if (x86_64_reloc_map[i].bfd_reloc_val == code)
295c50c785cSJohn Marino 	return elf_x86_64_rtype_to_howto (abfd,
2965796c8dcSSimon Schubert 					  x86_64_reloc_map[i].elf_reloc_val);
2975796c8dcSSimon Schubert     }
2985796c8dcSSimon Schubert   return 0;
2995796c8dcSSimon Schubert }
3005796c8dcSSimon Schubert 
3015796c8dcSSimon Schubert static reloc_howto_type *
elf_x86_64_reloc_name_lookup(bfd * abfd,const char * r_name)302a45ae5f8SJohn Marino elf_x86_64_reloc_name_lookup (bfd *abfd,
3035796c8dcSSimon Schubert 			      const char *r_name)
3045796c8dcSSimon Schubert {
3055796c8dcSSimon Schubert   unsigned int i;
3065796c8dcSSimon Schubert 
307a45ae5f8SJohn Marino   if (!ABI_64_P (abfd) && strcasecmp (r_name, "R_X86_64_32") == 0)
308a45ae5f8SJohn Marino     {
309a45ae5f8SJohn Marino       /* Get x32 R_X86_64_32.  */
310a45ae5f8SJohn Marino       reloc_howto_type *reloc
311a45ae5f8SJohn Marino 	= &x86_64_elf_howto_table[ARRAY_SIZE (x86_64_elf_howto_table) - 1];
312a45ae5f8SJohn Marino       BFD_ASSERT (reloc->type == (unsigned int) R_X86_64_32);
313a45ae5f8SJohn Marino       return reloc;
314a45ae5f8SJohn Marino     }
315a45ae5f8SJohn Marino 
316a45ae5f8SJohn Marino   for (i = 0; i < ARRAY_SIZE (x86_64_elf_howto_table); i++)
3175796c8dcSSimon Schubert     if (x86_64_elf_howto_table[i].name != NULL
3185796c8dcSSimon Schubert 	&& strcasecmp (x86_64_elf_howto_table[i].name, r_name) == 0)
3195796c8dcSSimon Schubert       return &x86_64_elf_howto_table[i];
3205796c8dcSSimon Schubert 
3215796c8dcSSimon Schubert   return NULL;
3225796c8dcSSimon Schubert }
3235796c8dcSSimon Schubert 
3245796c8dcSSimon Schubert /* Given an x86_64 ELF reloc type, fill in an arelent structure.  */
3255796c8dcSSimon Schubert 
3265796c8dcSSimon Schubert static void
elf_x86_64_info_to_howto(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr,Elf_Internal_Rela * dst)327c50c785cSJohn Marino elf_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
3285796c8dcSSimon Schubert 			  Elf_Internal_Rela *dst)
3295796c8dcSSimon Schubert {
3305796c8dcSSimon Schubert   unsigned r_type;
3315796c8dcSSimon Schubert 
332c50c785cSJohn Marino   r_type = ELF32_R_TYPE (dst->r_info);
333c50c785cSJohn Marino   cache_ptr->howto = elf_x86_64_rtype_to_howto (abfd, r_type);
3345796c8dcSSimon Schubert   BFD_ASSERT (r_type == cache_ptr->howto->type);
3355796c8dcSSimon Schubert }
3365796c8dcSSimon Schubert 
3375796c8dcSSimon Schubert /* Support for core dump NOTE sections.  */
3385796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_grok_prstatus(bfd * abfd,Elf_Internal_Note * note)339c50c785cSJohn Marino elf_x86_64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3405796c8dcSSimon Schubert {
3415796c8dcSSimon Schubert   int offset;
3425796c8dcSSimon Schubert   size_t size;
3435796c8dcSSimon Schubert 
3445796c8dcSSimon Schubert   switch (note->descsz)
3455796c8dcSSimon Schubert     {
3465796c8dcSSimon Schubert       default:
3475796c8dcSSimon Schubert 	return FALSE;
3485796c8dcSSimon Schubert 
349a45ae5f8SJohn Marino       case 296:		/* sizeof(istruct elf_prstatus) on Linux/x32 */
350a45ae5f8SJohn Marino 	/* pr_cursig */
351*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
352a45ae5f8SJohn Marino 
353a45ae5f8SJohn Marino 	/* pr_pid */
354*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
355a45ae5f8SJohn Marino 
356a45ae5f8SJohn Marino 	/* pr_reg */
357a45ae5f8SJohn Marino 	offset = 72;
358a45ae5f8SJohn Marino 	size = 216;
359a45ae5f8SJohn Marino 
360a45ae5f8SJohn Marino 	break;
361a45ae5f8SJohn Marino 
3625796c8dcSSimon Schubert       case 336:		/* sizeof(istruct elf_prstatus) on Linux/x86_64 */
3635796c8dcSSimon Schubert 	/* pr_cursig */
364*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->signal
3655796c8dcSSimon Schubert 	  = bfd_get_16 (abfd, note->descdata + 12);
3665796c8dcSSimon Schubert 
3675796c8dcSSimon Schubert 	/* pr_pid */
368*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->lwpid
3695796c8dcSSimon Schubert 	  = bfd_get_32 (abfd, note->descdata + 32);
3705796c8dcSSimon Schubert 
3715796c8dcSSimon Schubert 	/* pr_reg */
3725796c8dcSSimon Schubert 	offset = 112;
3735796c8dcSSimon Schubert 	size = 216;
3745796c8dcSSimon Schubert 
3755796c8dcSSimon Schubert 	break;
3765796c8dcSSimon Schubert     }
3775796c8dcSSimon Schubert 
3785796c8dcSSimon Schubert   /* Make a ".reg/999" section.  */
3795796c8dcSSimon Schubert   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
3805796c8dcSSimon Schubert 					  size, note->descpos + offset);
3815796c8dcSSimon Schubert }
3825796c8dcSSimon Schubert 
3835796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_grok_psinfo(bfd * abfd,Elf_Internal_Note * note)384c50c785cSJohn Marino elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3855796c8dcSSimon Schubert {
3865796c8dcSSimon Schubert   switch (note->descsz)
3875796c8dcSSimon Schubert     {
3885796c8dcSSimon Schubert       default:
3895796c8dcSSimon Schubert 	return FALSE;
3905796c8dcSSimon Schubert 
391a45ae5f8SJohn Marino       case 124:		/* sizeof(struct elf_prpsinfo) on Linux/x32 */
392*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->pid
393a45ae5f8SJohn Marino 	  = bfd_get_32 (abfd, note->descdata + 12);
394*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->program
395a45ae5f8SJohn Marino 	  = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
396*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->command
397a45ae5f8SJohn Marino 	  = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
398a45ae5f8SJohn Marino 	break;
399a45ae5f8SJohn Marino 
4005796c8dcSSimon Schubert       case 136:		/* sizeof(struct elf_prpsinfo) on Linux/x86_64 */
401*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->pid
402c50c785cSJohn Marino 	  = bfd_get_32 (abfd, note->descdata + 24);
403*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->program
4045796c8dcSSimon Schubert 	 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
405*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->command
4065796c8dcSSimon Schubert 	 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
4075796c8dcSSimon Schubert     }
4085796c8dcSSimon Schubert 
4095796c8dcSSimon Schubert   /* Note that for some reason, a spurious space is tacked
4105796c8dcSSimon Schubert      onto the end of the args in some (at least one anyway)
4115796c8dcSSimon Schubert      implementations, so strip it off if it exists.  */
4125796c8dcSSimon Schubert 
4135796c8dcSSimon Schubert   {
414*ef5ccd6cSJohn Marino     char *command = elf_tdata (abfd)->core->command;
4155796c8dcSSimon Schubert     int n = strlen (command);
4165796c8dcSSimon Schubert 
4175796c8dcSSimon Schubert     if (0 < n && command[n - 1] == ' ')
4185796c8dcSSimon Schubert       command[n - 1] = '\0';
4195796c8dcSSimon Schubert   }
4205796c8dcSSimon Schubert 
4215796c8dcSSimon Schubert   return TRUE;
4225796c8dcSSimon Schubert }
423a45ae5f8SJohn Marino 
424a45ae5f8SJohn Marino #ifdef CORE_HEADER
425a45ae5f8SJohn Marino static char *
elf_x86_64_write_core_note(bfd * abfd,char * buf,int * bufsiz,int note_type,...)426a45ae5f8SJohn Marino elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
427a45ae5f8SJohn Marino 			    int note_type, ...)
428a45ae5f8SJohn Marino {
429a45ae5f8SJohn Marino   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
430a45ae5f8SJohn Marino   va_list ap;
431a45ae5f8SJohn Marino   const char *fname, *psargs;
432a45ae5f8SJohn Marino   long pid;
433a45ae5f8SJohn Marino   int cursig;
434a45ae5f8SJohn Marino   const void *gregs;
435a45ae5f8SJohn Marino 
436a45ae5f8SJohn Marino   switch (note_type)
437a45ae5f8SJohn Marino     {
438a45ae5f8SJohn Marino     default:
439a45ae5f8SJohn Marino       return NULL;
440a45ae5f8SJohn Marino 
441a45ae5f8SJohn Marino     case NT_PRPSINFO:
442a45ae5f8SJohn Marino       va_start (ap, note_type);
443a45ae5f8SJohn Marino       fname = va_arg (ap, const char *);
444a45ae5f8SJohn Marino       psargs = va_arg (ap, const char *);
445a45ae5f8SJohn Marino       va_end (ap);
446a45ae5f8SJohn Marino 
447a45ae5f8SJohn Marino       if (bed->s->elfclass == ELFCLASS32)
448a45ae5f8SJohn Marino 	{
449a45ae5f8SJohn Marino 	  prpsinfo32_t data;
450a45ae5f8SJohn Marino 	  memset (&data, 0, sizeof (data));
451a45ae5f8SJohn Marino 	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
452a45ae5f8SJohn Marino 	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
453a45ae5f8SJohn Marino 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
454a45ae5f8SJohn Marino 				     &data, sizeof (data));
455a45ae5f8SJohn Marino 	}
456a45ae5f8SJohn Marino       else
457a45ae5f8SJohn Marino 	{
458*ef5ccd6cSJohn Marino 	  prpsinfo64_t data;
459a45ae5f8SJohn Marino 	  memset (&data, 0, sizeof (data));
460a45ae5f8SJohn Marino 	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
461a45ae5f8SJohn Marino 	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
462a45ae5f8SJohn Marino 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
463a45ae5f8SJohn Marino 				     &data, sizeof (data));
464a45ae5f8SJohn Marino 	}
465a45ae5f8SJohn Marino       /* NOTREACHED */
466a45ae5f8SJohn Marino 
467a45ae5f8SJohn Marino     case NT_PRSTATUS:
468a45ae5f8SJohn Marino       va_start (ap, note_type);
469a45ae5f8SJohn Marino       pid = va_arg (ap, long);
470a45ae5f8SJohn Marino       cursig = va_arg (ap, int);
471a45ae5f8SJohn Marino       gregs = va_arg (ap, const void *);
472a45ae5f8SJohn Marino       va_end (ap);
473a45ae5f8SJohn Marino 
474a45ae5f8SJohn Marino       if (bed->s->elfclass == ELFCLASS32)
475a45ae5f8SJohn Marino 	{
476a45ae5f8SJohn Marino 	  if (bed->elf_machine_code == EM_X86_64)
477a45ae5f8SJohn Marino 	    {
478a45ae5f8SJohn Marino 	      prstatusx32_t prstat;
479a45ae5f8SJohn Marino 	      memset (&prstat, 0, sizeof (prstat));
480a45ae5f8SJohn Marino 	      prstat.pr_pid = pid;
481a45ae5f8SJohn Marino 	      prstat.pr_cursig = cursig;
482a45ae5f8SJohn Marino 	      memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
483a45ae5f8SJohn Marino 	      return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
484a45ae5f8SJohn Marino 					 &prstat, sizeof (prstat));
485a45ae5f8SJohn Marino 	    }
486a45ae5f8SJohn Marino 	  else
487a45ae5f8SJohn Marino 	    {
488a45ae5f8SJohn Marino 	      prstatus32_t prstat;
489a45ae5f8SJohn Marino 	      memset (&prstat, 0, sizeof (prstat));
490a45ae5f8SJohn Marino 	      prstat.pr_pid = pid;
491a45ae5f8SJohn Marino 	      prstat.pr_cursig = cursig;
492a45ae5f8SJohn Marino 	      memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
493a45ae5f8SJohn Marino 	      return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
494a45ae5f8SJohn Marino 					 &prstat, sizeof (prstat));
495a45ae5f8SJohn Marino 	    }
496a45ae5f8SJohn Marino 	}
497a45ae5f8SJohn Marino       else
498a45ae5f8SJohn Marino 	{
499*ef5ccd6cSJohn Marino 	  prstatus64_t prstat;
500a45ae5f8SJohn Marino 	  memset (&prstat, 0, sizeof (prstat));
501a45ae5f8SJohn Marino 	  prstat.pr_pid = pid;
502a45ae5f8SJohn Marino 	  prstat.pr_cursig = cursig;
503a45ae5f8SJohn Marino 	  memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
504a45ae5f8SJohn Marino 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
505a45ae5f8SJohn Marino 				     &prstat, sizeof (prstat));
506a45ae5f8SJohn Marino 	}
507a45ae5f8SJohn Marino     }
508a45ae5f8SJohn Marino   /* NOTREACHED */
509a45ae5f8SJohn Marino }
510a45ae5f8SJohn Marino #endif
5115796c8dcSSimon Schubert 
5125796c8dcSSimon Schubert /* Functions for the x86-64 ELF linker.	 */
5135796c8dcSSimon Schubert 
5145796c8dcSSimon Schubert /* The name of the dynamic interpreter.	 This is put in the .interp
5155796c8dcSSimon Schubert    section.  */
5165796c8dcSSimon Schubert 
517c50c785cSJohn Marino #define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
518*ef5ccd6cSJohn Marino #define ELF32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1"
5195796c8dcSSimon Schubert 
5205796c8dcSSimon Schubert /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
5215796c8dcSSimon Schubert    copying dynamic variables from a shared lib into an app's dynbss
5225796c8dcSSimon Schubert    section, and instead use a dynamic relocation to point into the
5235796c8dcSSimon Schubert    shared lib.  */
5245796c8dcSSimon Schubert #define ELIMINATE_COPY_RELOCS 1
5255796c8dcSSimon Schubert 
5265796c8dcSSimon Schubert /* The size in bytes of an entry in the global offset table.  */
5275796c8dcSSimon Schubert 
5285796c8dcSSimon Schubert #define GOT_ENTRY_SIZE 8
5295796c8dcSSimon Schubert 
5305796c8dcSSimon Schubert /* The size in bytes of an entry in the procedure linkage table.  */
5315796c8dcSSimon Schubert 
5325796c8dcSSimon Schubert #define PLT_ENTRY_SIZE 16
5335796c8dcSSimon Schubert 
5345796c8dcSSimon Schubert /* The first entry in a procedure linkage table looks like this.  See the
5355796c8dcSSimon Schubert    SVR4 ABI i386 supplement and the x86-64 ABI to see how this works.  */
5365796c8dcSSimon Schubert 
537c50c785cSJohn Marino static const bfd_byte elf_x86_64_plt0_entry[PLT_ENTRY_SIZE] =
5385796c8dcSSimon Schubert {
5395796c8dcSSimon Schubert   0xff, 0x35, 8, 0, 0, 0,	/* pushq GOT+8(%rip)  */
5405796c8dcSSimon Schubert   0xff, 0x25, 16, 0, 0, 0,	/* jmpq *GOT+16(%rip) */
5415796c8dcSSimon Schubert   0x0f, 0x1f, 0x40, 0x00	/* nopl 0(%rax)       */
5425796c8dcSSimon Schubert };
5435796c8dcSSimon Schubert 
5445796c8dcSSimon Schubert /* Subsequent entries in a procedure linkage table look like this.  */
5455796c8dcSSimon Schubert 
546c50c785cSJohn Marino static const bfd_byte elf_x86_64_plt_entry[PLT_ENTRY_SIZE] =
5475796c8dcSSimon Schubert {
5485796c8dcSSimon Schubert   0xff, 0x25,	/* jmpq *name@GOTPC(%rip) */
5495796c8dcSSimon Schubert   0, 0, 0, 0,	/* replaced with offset to this symbol in .got.	 */
5505796c8dcSSimon Schubert   0x68,		/* pushq immediate */
5515796c8dcSSimon Schubert   0, 0, 0, 0,	/* replaced with index into relocation table.  */
5525796c8dcSSimon Schubert   0xe9,		/* jmp relative */
5535796c8dcSSimon Schubert   0, 0, 0, 0	/* replaced with offset to start of .plt0.  */
5545796c8dcSSimon Schubert };
5555796c8dcSSimon Schubert 
556a45ae5f8SJohn Marino /* .eh_frame covering the .plt section.  */
557a45ae5f8SJohn Marino 
558a45ae5f8SJohn Marino static const bfd_byte elf_x86_64_eh_frame_plt[] =
559a45ae5f8SJohn Marino {
560a45ae5f8SJohn Marino #define PLT_CIE_LENGTH		20
561a45ae5f8SJohn Marino #define PLT_FDE_LENGTH		36
562a45ae5f8SJohn Marino #define PLT_FDE_START_OFFSET	4 + PLT_CIE_LENGTH + 8
563a45ae5f8SJohn Marino #define PLT_FDE_LEN_OFFSET	4 + PLT_CIE_LENGTH + 12
564a45ae5f8SJohn Marino   PLT_CIE_LENGTH, 0, 0, 0,	/* CIE length */
565a45ae5f8SJohn Marino   0, 0, 0, 0,			/* CIE ID */
566a45ae5f8SJohn Marino   1,				/* CIE version */
567a45ae5f8SJohn Marino   'z', 'R', 0,			/* Augmentation string */
568a45ae5f8SJohn Marino   1,				/* Code alignment factor */
569a45ae5f8SJohn Marino   0x78,				/* Data alignment factor */
570a45ae5f8SJohn Marino   16,				/* Return address column */
571a45ae5f8SJohn Marino   1,				/* Augmentation size */
572a45ae5f8SJohn Marino   DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
573a45ae5f8SJohn Marino   DW_CFA_def_cfa, 7, 8,		/* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
574a45ae5f8SJohn Marino   DW_CFA_offset + 16, 1,	/* DW_CFA_offset: r16 (rip) at cfa-8 */
575a45ae5f8SJohn Marino   DW_CFA_nop, DW_CFA_nop,
576a45ae5f8SJohn Marino 
577a45ae5f8SJohn Marino   PLT_FDE_LENGTH, 0, 0, 0,	/* FDE length */
578a45ae5f8SJohn Marino   PLT_CIE_LENGTH + 8, 0, 0, 0,	/* CIE pointer */
579a45ae5f8SJohn Marino   0, 0, 0, 0,			/* R_X86_64_PC32 .plt goes here */
580a45ae5f8SJohn Marino   0, 0, 0, 0,			/* .plt size goes here */
581a45ae5f8SJohn Marino   0,				/* Augmentation size */
582a45ae5f8SJohn Marino   DW_CFA_def_cfa_offset, 16,	/* DW_CFA_def_cfa_offset: 16 */
583a45ae5f8SJohn Marino   DW_CFA_advance_loc + 6,	/* DW_CFA_advance_loc: 6 to __PLT__+6 */
584a45ae5f8SJohn Marino   DW_CFA_def_cfa_offset, 24,	/* DW_CFA_def_cfa_offset: 24 */
585a45ae5f8SJohn Marino   DW_CFA_advance_loc + 10,	/* DW_CFA_advance_loc: 10 to __PLT__+16 */
586a45ae5f8SJohn Marino   DW_CFA_def_cfa_expression,	/* DW_CFA_def_cfa_expression */
587a45ae5f8SJohn Marino   11,				/* Block length */
588a45ae5f8SJohn Marino   DW_OP_breg7, 8,		/* DW_OP_breg7 (rsp): 8 */
589a45ae5f8SJohn Marino   DW_OP_breg16, 0,		/* DW_OP_breg16 (rip): 0 */
590a45ae5f8SJohn Marino   DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge,
591a45ae5f8SJohn Marino   DW_OP_lit3, DW_OP_shl, DW_OP_plus,
592a45ae5f8SJohn Marino   DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
593a45ae5f8SJohn Marino };
594a45ae5f8SJohn Marino 
595*ef5ccd6cSJohn Marino /* Architecture-specific backend data for x86-64.  */
596*ef5ccd6cSJohn Marino 
597*ef5ccd6cSJohn Marino struct elf_x86_64_backend_data
598*ef5ccd6cSJohn Marino {
599*ef5ccd6cSJohn Marino   /* Templates for the initial PLT entry and for subsequent entries.  */
600*ef5ccd6cSJohn Marino   const bfd_byte *plt0_entry;
601*ef5ccd6cSJohn Marino   const bfd_byte *plt_entry;
602*ef5ccd6cSJohn Marino   unsigned int plt_entry_size;          /* Size of each PLT entry.  */
603*ef5ccd6cSJohn Marino 
604*ef5ccd6cSJohn Marino   /* Offsets into plt0_entry that are to be replaced with GOT[1] and GOT[2].  */
605*ef5ccd6cSJohn Marino   unsigned int plt0_got1_offset;
606*ef5ccd6cSJohn Marino   unsigned int plt0_got2_offset;
607*ef5ccd6cSJohn Marino 
608*ef5ccd6cSJohn Marino   /* Offset of the end of the PC-relative instruction containing
609*ef5ccd6cSJohn Marino      plt0_got2_offset.  */
610*ef5ccd6cSJohn Marino   unsigned int plt0_got2_insn_end;
611*ef5ccd6cSJohn Marino 
612*ef5ccd6cSJohn Marino   /* Offsets into plt_entry that are to be replaced with...  */
613*ef5ccd6cSJohn Marino   unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
614*ef5ccd6cSJohn Marino   unsigned int plt_reloc_offset;  /* ... offset into relocation table. */
615*ef5ccd6cSJohn Marino   unsigned int plt_plt_offset;    /* ... offset to start of .plt. */
616*ef5ccd6cSJohn Marino 
617*ef5ccd6cSJohn Marino   /* Length of the PC-relative instruction containing plt_got_offset.  */
618*ef5ccd6cSJohn Marino   unsigned int plt_got_insn_size;
619*ef5ccd6cSJohn Marino 
620*ef5ccd6cSJohn Marino   /* Offset of the end of the PC-relative jump to plt0_entry.  */
621*ef5ccd6cSJohn Marino   unsigned int plt_plt_insn_end;
622*ef5ccd6cSJohn Marino 
623*ef5ccd6cSJohn Marino   /* Offset into plt_entry where the initial value of the GOT entry points.  */
624*ef5ccd6cSJohn Marino   unsigned int plt_lazy_offset;
625*ef5ccd6cSJohn Marino 
626*ef5ccd6cSJohn Marino   /* .eh_frame covering the .plt section.  */
627*ef5ccd6cSJohn Marino   const bfd_byte *eh_frame_plt;
628*ef5ccd6cSJohn Marino   unsigned int eh_frame_plt_size;
629*ef5ccd6cSJohn Marino };
630*ef5ccd6cSJohn Marino 
631*ef5ccd6cSJohn Marino #define get_elf_x86_64_backend_data(abfd) \
632*ef5ccd6cSJohn Marino   ((const struct elf_x86_64_backend_data *) \
633*ef5ccd6cSJohn Marino    get_elf_backend_data (abfd)->arch_data)
634*ef5ccd6cSJohn Marino 
635*ef5ccd6cSJohn Marino #define GET_PLT_ENTRY_SIZE(abfd) \
636*ef5ccd6cSJohn Marino   get_elf_x86_64_backend_data (abfd)->plt_entry_size
637*ef5ccd6cSJohn Marino 
638*ef5ccd6cSJohn Marino /* These are the standard parameters.  */
639*ef5ccd6cSJohn Marino static const struct elf_x86_64_backend_data elf_x86_64_arch_bed =
640*ef5ccd6cSJohn Marino   {
641*ef5ccd6cSJohn Marino     elf_x86_64_plt0_entry,              /* plt0_entry */
642*ef5ccd6cSJohn Marino     elf_x86_64_plt_entry,               /* plt_entry */
643*ef5ccd6cSJohn Marino     sizeof (elf_x86_64_plt_entry),      /* plt_entry_size */
644*ef5ccd6cSJohn Marino     2,                                  /* plt0_got1_offset */
645*ef5ccd6cSJohn Marino     8,                                  /* plt0_got2_offset */
646*ef5ccd6cSJohn Marino     12,                                 /* plt0_got2_insn_end */
647*ef5ccd6cSJohn Marino     2,                                  /* plt_got_offset */
648*ef5ccd6cSJohn Marino     7,                                  /* plt_reloc_offset */
649*ef5ccd6cSJohn Marino     12,                                 /* plt_plt_offset */
650*ef5ccd6cSJohn Marino     6,                                  /* plt_got_insn_size */
651*ef5ccd6cSJohn Marino     PLT_ENTRY_SIZE,                     /* plt_plt_insn_end */
652*ef5ccd6cSJohn Marino     6,                                  /* plt_lazy_offset */
653*ef5ccd6cSJohn Marino     elf_x86_64_eh_frame_plt,            /* eh_frame_plt */
654*ef5ccd6cSJohn Marino     sizeof (elf_x86_64_eh_frame_plt),   /* eh_frame_plt_size */
655*ef5ccd6cSJohn Marino   };
656*ef5ccd6cSJohn Marino 
657*ef5ccd6cSJohn Marino #define	elf_backend_arch_data	&elf_x86_64_arch_bed
658*ef5ccd6cSJohn Marino 
6595796c8dcSSimon Schubert /* x86-64 ELF linker hash entry.  */
6605796c8dcSSimon Schubert 
661c50c785cSJohn Marino struct elf_x86_64_link_hash_entry
6625796c8dcSSimon Schubert {
6635796c8dcSSimon Schubert   struct elf_link_hash_entry elf;
6645796c8dcSSimon Schubert 
6655796c8dcSSimon Schubert   /* Track dynamic relocs copied for this symbol.  */
6665796c8dcSSimon Schubert   struct elf_dyn_relocs *dyn_relocs;
6675796c8dcSSimon Schubert 
6685796c8dcSSimon Schubert #define GOT_UNKNOWN	0
6695796c8dcSSimon Schubert #define GOT_NORMAL	1
6705796c8dcSSimon Schubert #define GOT_TLS_GD	2
6715796c8dcSSimon Schubert #define GOT_TLS_IE	3
6725796c8dcSSimon Schubert #define GOT_TLS_GDESC	4
6735796c8dcSSimon Schubert #define GOT_TLS_GD_BOTH_P(type) \
6745796c8dcSSimon Schubert   ((type) == (GOT_TLS_GD | GOT_TLS_GDESC))
6755796c8dcSSimon Schubert #define GOT_TLS_GD_P(type) \
6765796c8dcSSimon Schubert   ((type) == GOT_TLS_GD || GOT_TLS_GD_BOTH_P (type))
6775796c8dcSSimon Schubert #define GOT_TLS_GDESC_P(type) \
6785796c8dcSSimon Schubert   ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type))
6795796c8dcSSimon Schubert #define GOT_TLS_GD_ANY_P(type) \
6805796c8dcSSimon Schubert   (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type))
6815796c8dcSSimon Schubert   unsigned char tls_type;
6825796c8dcSSimon Schubert 
6835796c8dcSSimon Schubert   /* Offset of the GOTPLT entry reserved for the TLS descriptor,
6845796c8dcSSimon Schubert      starting at the end of the jump table.  */
6855796c8dcSSimon Schubert   bfd_vma tlsdesc_got;
6865796c8dcSSimon Schubert };
6875796c8dcSSimon Schubert 
688c50c785cSJohn Marino #define elf_x86_64_hash_entry(ent) \
689c50c785cSJohn Marino   ((struct elf_x86_64_link_hash_entry *)(ent))
6905796c8dcSSimon Schubert 
691c50c785cSJohn Marino struct elf_x86_64_obj_tdata
6925796c8dcSSimon Schubert {
6935796c8dcSSimon Schubert   struct elf_obj_tdata root;
6945796c8dcSSimon Schubert 
6955796c8dcSSimon Schubert   /* tls_type for each local got entry.  */
6965796c8dcSSimon Schubert   char *local_got_tls_type;
6975796c8dcSSimon Schubert 
6985796c8dcSSimon Schubert   /* GOTPLT entries for TLS descriptors.  */
6995796c8dcSSimon Schubert   bfd_vma *local_tlsdesc_gotent;
7005796c8dcSSimon Schubert };
7015796c8dcSSimon Schubert 
702c50c785cSJohn Marino #define elf_x86_64_tdata(abfd) \
703c50c785cSJohn Marino   ((struct elf_x86_64_obj_tdata *) (abfd)->tdata.any)
7045796c8dcSSimon Schubert 
705c50c785cSJohn Marino #define elf_x86_64_local_got_tls_type(abfd) \
706c50c785cSJohn Marino   (elf_x86_64_tdata (abfd)->local_got_tls_type)
7075796c8dcSSimon Schubert 
708c50c785cSJohn Marino #define elf_x86_64_local_tlsdesc_gotent(abfd) \
709c50c785cSJohn Marino   (elf_x86_64_tdata (abfd)->local_tlsdesc_gotent)
7105796c8dcSSimon Schubert 
7115796c8dcSSimon Schubert #define is_x86_64_elf(bfd)				\
7125796c8dcSSimon Schubert   (bfd_get_flavour (bfd) == bfd_target_elf_flavour	\
7135796c8dcSSimon Schubert    && elf_tdata (bfd) != NULL				\
714cf7f2e2dSJohn Marino    && elf_object_id (bfd) == X86_64_ELF_DATA)
7155796c8dcSSimon Schubert 
7165796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_mkobject(bfd * abfd)717c50c785cSJohn Marino elf_x86_64_mkobject (bfd *abfd)
7185796c8dcSSimon Schubert {
719c50c785cSJohn Marino   return bfd_elf_allocate_object (abfd, sizeof (struct elf_x86_64_obj_tdata),
720cf7f2e2dSJohn Marino 				  X86_64_ELF_DATA);
7215796c8dcSSimon Schubert }
7225796c8dcSSimon Schubert 
7235796c8dcSSimon Schubert /* x86-64 ELF linker hash table.  */
7245796c8dcSSimon Schubert 
725c50c785cSJohn Marino struct elf_x86_64_link_hash_table
7265796c8dcSSimon Schubert {
7275796c8dcSSimon Schubert   struct elf_link_hash_table elf;
7285796c8dcSSimon Schubert 
7295796c8dcSSimon Schubert   /* Short-cuts to get to dynamic linker sections.  */
7305796c8dcSSimon Schubert   asection *sdynbss;
7315796c8dcSSimon Schubert   asection *srelbss;
732a45ae5f8SJohn Marino   asection *plt_eh_frame;
7335796c8dcSSimon Schubert 
734cf7f2e2dSJohn Marino   union
735cf7f2e2dSJohn Marino   {
7365796c8dcSSimon Schubert     bfd_signed_vma refcount;
7375796c8dcSSimon Schubert     bfd_vma offset;
7385796c8dcSSimon Schubert   } tls_ld_got;
7395796c8dcSSimon Schubert 
7405796c8dcSSimon Schubert   /* The amount of space used by the jump slots in the GOT.  */
7415796c8dcSSimon Schubert   bfd_vma sgotplt_jump_table_size;
7425796c8dcSSimon Schubert 
7435796c8dcSSimon Schubert   /* Small local sym cache.  */
7445796c8dcSSimon Schubert   struct sym_cache sym_cache;
7455796c8dcSSimon Schubert 
746c50c785cSJohn Marino   bfd_vma (*r_info) (bfd_vma, bfd_vma);
747c50c785cSJohn Marino   bfd_vma (*r_sym) (bfd_vma);
748c50c785cSJohn Marino   unsigned int pointer_r_type;
749c50c785cSJohn Marino   const char *dynamic_interpreter;
750c50c785cSJohn Marino   int dynamic_interpreter_size;
751c50c785cSJohn Marino 
7525796c8dcSSimon Schubert   /* _TLS_MODULE_BASE_ symbol.  */
7535796c8dcSSimon Schubert   struct bfd_link_hash_entry *tls_module_base;
7545796c8dcSSimon Schubert 
7555796c8dcSSimon Schubert   /* Used by local STT_GNU_IFUNC symbols.  */
7565796c8dcSSimon Schubert   htab_t loc_hash_table;
7575796c8dcSSimon Schubert   void * loc_hash_memory;
758cf7f2e2dSJohn Marino 
759cf7f2e2dSJohn Marino   /* The offset into splt of the PLT entry for the TLS descriptor
760cf7f2e2dSJohn Marino      resolver.  Special values are 0, if not necessary (or not found
761cf7f2e2dSJohn Marino      to be necessary yet), and -1 if needed but not determined
762cf7f2e2dSJohn Marino      yet.  */
763cf7f2e2dSJohn Marino   bfd_vma tlsdesc_plt;
764cf7f2e2dSJohn Marino   /* The offset into sgot of the GOT entry used by the PLT entry
765cf7f2e2dSJohn Marino      above.  */
766cf7f2e2dSJohn Marino   bfd_vma tlsdesc_got;
767a45ae5f8SJohn Marino 
768a45ae5f8SJohn Marino   /* The index of the next R_X86_64_JUMP_SLOT entry in .rela.plt.  */
769a45ae5f8SJohn Marino   bfd_vma next_jump_slot_index;
770a45ae5f8SJohn Marino   /* The index of the next R_X86_64_IRELATIVE entry in .rela.plt.  */
771a45ae5f8SJohn Marino   bfd_vma next_irelative_index;
7725796c8dcSSimon Schubert };
7735796c8dcSSimon Schubert 
7745796c8dcSSimon Schubert /* Get the x86-64 ELF linker hash table from a link_info structure.  */
7755796c8dcSSimon Schubert 
776c50c785cSJohn Marino #define elf_x86_64_hash_table(p) \
777cf7f2e2dSJohn Marino   (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
778c50c785cSJohn Marino   == X86_64_ELF_DATA ? ((struct elf_x86_64_link_hash_table *) ((p)->hash)) : NULL)
7795796c8dcSSimon Schubert 
780c50c785cSJohn Marino #define elf_x86_64_compute_jump_table_size(htab) \
7815796c8dcSSimon Schubert   ((htab)->elf.srelplt->reloc_count * GOT_ENTRY_SIZE)
7825796c8dcSSimon Schubert 
7835796c8dcSSimon Schubert /* Create an entry in an x86-64 ELF linker hash table.	*/
7845796c8dcSSimon Schubert 
7855796c8dcSSimon Schubert static struct bfd_hash_entry *
elf_x86_64_link_hash_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)786c50c785cSJohn Marino elf_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry,
7875796c8dcSSimon Schubert 			      struct bfd_hash_table *table,
7885796c8dcSSimon Schubert 			      const char *string)
7895796c8dcSSimon Schubert {
7905796c8dcSSimon Schubert   /* Allocate the structure if it has not already been allocated by a
7915796c8dcSSimon Schubert      subclass.  */
7925796c8dcSSimon Schubert   if (entry == NULL)
7935796c8dcSSimon Schubert     {
7945796c8dcSSimon Schubert       entry = (struct bfd_hash_entry *)
7955796c8dcSSimon Schubert 	  bfd_hash_allocate (table,
796c50c785cSJohn Marino 			     sizeof (struct elf_x86_64_link_hash_entry));
7975796c8dcSSimon Schubert       if (entry == NULL)
7985796c8dcSSimon Schubert 	return entry;
7995796c8dcSSimon Schubert     }
8005796c8dcSSimon Schubert 
8015796c8dcSSimon Schubert   /* Call the allocation method of the superclass.  */
8025796c8dcSSimon Schubert   entry = _bfd_elf_link_hash_newfunc (entry, table, string);
8035796c8dcSSimon Schubert   if (entry != NULL)
8045796c8dcSSimon Schubert     {
805c50c785cSJohn Marino       struct elf_x86_64_link_hash_entry *eh;
8065796c8dcSSimon Schubert 
807c50c785cSJohn Marino       eh = (struct elf_x86_64_link_hash_entry *) entry;
8085796c8dcSSimon Schubert       eh->dyn_relocs = NULL;
8095796c8dcSSimon Schubert       eh->tls_type = GOT_UNKNOWN;
8105796c8dcSSimon Schubert       eh->tlsdesc_got = (bfd_vma) -1;
8115796c8dcSSimon Schubert     }
8125796c8dcSSimon Schubert 
8135796c8dcSSimon Schubert   return entry;
8145796c8dcSSimon Schubert }
8155796c8dcSSimon Schubert 
8165796c8dcSSimon Schubert /* Compute a hash of a local hash entry.  We use elf_link_hash_entry
8175796c8dcSSimon Schubert   for local symbol so that we can handle local STT_GNU_IFUNC symbols
8185796c8dcSSimon Schubert   as global symbol.  We reuse indx and dynstr_index for local symbol
8195796c8dcSSimon Schubert   hash since they aren't used by global symbols in this backend.  */
8205796c8dcSSimon Schubert 
8215796c8dcSSimon Schubert static hashval_t
elf_x86_64_local_htab_hash(const void * ptr)822c50c785cSJohn Marino elf_x86_64_local_htab_hash (const void *ptr)
8235796c8dcSSimon Schubert {
8245796c8dcSSimon Schubert   struct elf_link_hash_entry *h
8255796c8dcSSimon Schubert     = (struct elf_link_hash_entry *) ptr;
8265796c8dcSSimon Schubert   return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
8275796c8dcSSimon Schubert }
8285796c8dcSSimon Schubert 
8295796c8dcSSimon Schubert /* Compare local hash entries.  */
8305796c8dcSSimon Schubert 
8315796c8dcSSimon Schubert static int
elf_x86_64_local_htab_eq(const void * ptr1,const void * ptr2)832c50c785cSJohn Marino elf_x86_64_local_htab_eq (const void *ptr1, const void *ptr2)
8335796c8dcSSimon Schubert {
8345796c8dcSSimon Schubert   struct elf_link_hash_entry *h1
8355796c8dcSSimon Schubert      = (struct elf_link_hash_entry *) ptr1;
8365796c8dcSSimon Schubert   struct elf_link_hash_entry *h2
8375796c8dcSSimon Schubert     = (struct elf_link_hash_entry *) ptr2;
8385796c8dcSSimon Schubert 
8395796c8dcSSimon Schubert   return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
8405796c8dcSSimon Schubert }
8415796c8dcSSimon Schubert 
8425796c8dcSSimon Schubert /* Find and/or create a hash entry for local symbol.  */
8435796c8dcSSimon Schubert 
8445796c8dcSSimon Schubert static struct elf_link_hash_entry *
elf_x86_64_get_local_sym_hash(struct elf_x86_64_link_hash_table * htab,bfd * abfd,const Elf_Internal_Rela * rel,bfd_boolean create)845c50c785cSJohn Marino elf_x86_64_get_local_sym_hash (struct elf_x86_64_link_hash_table *htab,
8465796c8dcSSimon Schubert 			       bfd *abfd, const Elf_Internal_Rela *rel,
8475796c8dcSSimon Schubert 			       bfd_boolean create)
8485796c8dcSSimon Schubert {
849c50c785cSJohn Marino   struct elf_x86_64_link_hash_entry e, *ret;
8505796c8dcSSimon Schubert   asection *sec = abfd->sections;
8515796c8dcSSimon Schubert   hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
852c50c785cSJohn Marino 				       htab->r_sym (rel->r_info));
8535796c8dcSSimon Schubert   void **slot;
8545796c8dcSSimon Schubert 
8555796c8dcSSimon Schubert   e.elf.indx = sec->id;
856c50c785cSJohn Marino   e.elf.dynstr_index = htab->r_sym (rel->r_info);
8575796c8dcSSimon Schubert   slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
8585796c8dcSSimon Schubert 				   create ? INSERT : NO_INSERT);
8595796c8dcSSimon Schubert 
8605796c8dcSSimon Schubert   if (!slot)
8615796c8dcSSimon Schubert     return NULL;
8625796c8dcSSimon Schubert 
8635796c8dcSSimon Schubert   if (*slot)
8645796c8dcSSimon Schubert     {
865c50c785cSJohn Marino       ret = (struct elf_x86_64_link_hash_entry *) *slot;
8665796c8dcSSimon Schubert       return &ret->elf;
8675796c8dcSSimon Schubert     }
8685796c8dcSSimon Schubert 
869c50c785cSJohn Marino   ret = (struct elf_x86_64_link_hash_entry *)
8705796c8dcSSimon Schubert 	objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
871c50c785cSJohn Marino 			sizeof (struct elf_x86_64_link_hash_entry));
8725796c8dcSSimon Schubert   if (ret)
8735796c8dcSSimon Schubert     {
8745796c8dcSSimon Schubert       memset (ret, 0, sizeof (*ret));
8755796c8dcSSimon Schubert       ret->elf.indx = sec->id;
876c50c785cSJohn Marino       ret->elf.dynstr_index = htab->r_sym (rel->r_info);
8775796c8dcSSimon Schubert       ret->elf.dynindx = -1;
8785796c8dcSSimon Schubert       *slot = ret;
8795796c8dcSSimon Schubert     }
8805796c8dcSSimon Schubert   return &ret->elf;
8815796c8dcSSimon Schubert }
8825796c8dcSSimon Schubert 
8835796c8dcSSimon Schubert /* Create an X86-64 ELF linker hash table.  */
8845796c8dcSSimon Schubert 
8855796c8dcSSimon Schubert static struct bfd_link_hash_table *
elf_x86_64_link_hash_table_create(bfd * abfd)886c50c785cSJohn Marino elf_x86_64_link_hash_table_create (bfd *abfd)
8875796c8dcSSimon Schubert {
888c50c785cSJohn Marino   struct elf_x86_64_link_hash_table *ret;
889c50c785cSJohn Marino   bfd_size_type amt = sizeof (struct elf_x86_64_link_hash_table);
8905796c8dcSSimon Schubert 
891*ef5ccd6cSJohn Marino   ret = (struct elf_x86_64_link_hash_table *) bfd_zmalloc (amt);
8925796c8dcSSimon Schubert   if (ret == NULL)
8935796c8dcSSimon Schubert     return NULL;
8945796c8dcSSimon Schubert 
8955796c8dcSSimon Schubert   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
896c50c785cSJohn Marino 				      elf_x86_64_link_hash_newfunc,
897c50c785cSJohn Marino 				      sizeof (struct elf_x86_64_link_hash_entry),
898cf7f2e2dSJohn Marino 				      X86_64_ELF_DATA))
8995796c8dcSSimon Schubert     {
9005796c8dcSSimon Schubert       free (ret);
9015796c8dcSSimon Schubert       return NULL;
9025796c8dcSSimon Schubert     }
9035796c8dcSSimon Schubert 
904c50c785cSJohn Marino   if (ABI_64_P (abfd))
905c50c785cSJohn Marino     {
906c50c785cSJohn Marino       ret->r_info = elf64_r_info;
907c50c785cSJohn Marino       ret->r_sym = elf64_r_sym;
908c50c785cSJohn Marino       ret->pointer_r_type = R_X86_64_64;
909c50c785cSJohn Marino       ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER;
910c50c785cSJohn Marino       ret->dynamic_interpreter_size = sizeof ELF64_DYNAMIC_INTERPRETER;
911c50c785cSJohn Marino     }
912c50c785cSJohn Marino   else
913c50c785cSJohn Marino     {
914c50c785cSJohn Marino       ret->r_info = elf32_r_info;
915c50c785cSJohn Marino       ret->r_sym = elf32_r_sym;
916c50c785cSJohn Marino       ret->pointer_r_type = R_X86_64_32;
917c50c785cSJohn Marino       ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER;
918c50c785cSJohn Marino       ret->dynamic_interpreter_size = sizeof ELF32_DYNAMIC_INTERPRETER;
919c50c785cSJohn Marino     }
920c50c785cSJohn Marino 
9215796c8dcSSimon Schubert   ret->loc_hash_table = htab_try_create (1024,
922c50c785cSJohn Marino 					 elf_x86_64_local_htab_hash,
923c50c785cSJohn Marino 					 elf_x86_64_local_htab_eq,
9245796c8dcSSimon Schubert 					 NULL);
9255796c8dcSSimon Schubert   ret->loc_hash_memory = objalloc_create ();
9265796c8dcSSimon Schubert   if (!ret->loc_hash_table || !ret->loc_hash_memory)
9275796c8dcSSimon Schubert     {
9285796c8dcSSimon Schubert       free (ret);
9295796c8dcSSimon Schubert       return NULL;
9305796c8dcSSimon Schubert     }
9315796c8dcSSimon Schubert 
9325796c8dcSSimon Schubert   return &ret->elf.root;
9335796c8dcSSimon Schubert }
9345796c8dcSSimon Schubert 
9355796c8dcSSimon Schubert /* Destroy an X86-64 ELF linker hash table.  */
9365796c8dcSSimon Schubert 
9375796c8dcSSimon Schubert static void
elf_x86_64_link_hash_table_free(struct bfd_link_hash_table * hash)938c50c785cSJohn Marino elf_x86_64_link_hash_table_free (struct bfd_link_hash_table *hash)
9395796c8dcSSimon Schubert {
940c50c785cSJohn Marino   struct elf_x86_64_link_hash_table *htab
941c50c785cSJohn Marino     = (struct elf_x86_64_link_hash_table *) hash;
9425796c8dcSSimon Schubert 
9435796c8dcSSimon Schubert   if (htab->loc_hash_table)
9445796c8dcSSimon Schubert     htab_delete (htab->loc_hash_table);
9455796c8dcSSimon Schubert   if (htab->loc_hash_memory)
9465796c8dcSSimon Schubert     objalloc_free ((struct objalloc *) htab->loc_hash_memory);
947*ef5ccd6cSJohn Marino   _bfd_elf_link_hash_table_free (hash);
9485796c8dcSSimon Schubert }
9495796c8dcSSimon Schubert 
9505796c8dcSSimon Schubert /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
9515796c8dcSSimon Schubert    .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
9525796c8dcSSimon Schubert    hash table.  */
9535796c8dcSSimon Schubert 
9545796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_create_dynamic_sections(bfd * dynobj,struct bfd_link_info * info)955c50c785cSJohn Marino elf_x86_64_create_dynamic_sections (bfd *dynobj,
956c50c785cSJohn Marino 				    struct bfd_link_info *info)
9575796c8dcSSimon Schubert {
958c50c785cSJohn Marino   struct elf_x86_64_link_hash_table *htab;
9595796c8dcSSimon Schubert 
9605796c8dcSSimon Schubert   if (!_bfd_elf_create_dynamic_sections (dynobj, info))
9615796c8dcSSimon Schubert     return FALSE;
9625796c8dcSSimon Schubert 
963c50c785cSJohn Marino   htab = elf_x86_64_hash_table (info);
964cf7f2e2dSJohn Marino   if (htab == NULL)
965cf7f2e2dSJohn Marino     return FALSE;
966cf7f2e2dSJohn Marino 
967*ef5ccd6cSJohn Marino   htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
9685796c8dcSSimon Schubert   if (!info->shared)
969*ef5ccd6cSJohn Marino     htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
9705796c8dcSSimon Schubert 
9715796c8dcSSimon Schubert   if (!htab->sdynbss
9725796c8dcSSimon Schubert       || (!info->shared && !htab->srelbss))
9735796c8dcSSimon Schubert     abort ();
9745796c8dcSSimon Schubert 
975a45ae5f8SJohn Marino   if (!info->no_ld_generated_unwind_info
976*ef5ccd6cSJohn Marino       && htab->plt_eh_frame == NULL
977a45ae5f8SJohn Marino       && htab->elf.splt != NULL)
978a45ae5f8SJohn Marino     {
979*ef5ccd6cSJohn Marino       flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
980*ef5ccd6cSJohn Marino 			| SEC_HAS_CONTENTS | SEC_IN_MEMORY
981*ef5ccd6cSJohn Marino 			| SEC_LINKER_CREATED);
982a45ae5f8SJohn Marino       htab->plt_eh_frame
983*ef5ccd6cSJohn Marino 	= bfd_make_section_anyway_with_flags (dynobj, ".eh_frame", flags);
984a45ae5f8SJohn Marino       if (htab->plt_eh_frame == NULL
985a45ae5f8SJohn Marino 	  || !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 3))
986a45ae5f8SJohn Marino 	return FALSE;
987a45ae5f8SJohn Marino     }
9885796c8dcSSimon Schubert   return TRUE;
9895796c8dcSSimon Schubert }
9905796c8dcSSimon Schubert 
9915796c8dcSSimon Schubert /* Copy the extra info we tack onto an elf_link_hash_entry.  */
9925796c8dcSSimon Schubert 
9935796c8dcSSimon Schubert static void
elf_x86_64_copy_indirect_symbol(struct bfd_link_info * info,struct elf_link_hash_entry * dir,struct elf_link_hash_entry * ind)994c50c785cSJohn Marino elf_x86_64_copy_indirect_symbol (struct bfd_link_info *info,
9955796c8dcSSimon Schubert 				 struct elf_link_hash_entry *dir,
9965796c8dcSSimon Schubert 				 struct elf_link_hash_entry *ind)
9975796c8dcSSimon Schubert {
998c50c785cSJohn Marino   struct elf_x86_64_link_hash_entry *edir, *eind;
9995796c8dcSSimon Schubert 
1000c50c785cSJohn Marino   edir = (struct elf_x86_64_link_hash_entry *) dir;
1001c50c785cSJohn Marino   eind = (struct elf_x86_64_link_hash_entry *) ind;
10025796c8dcSSimon Schubert 
10035796c8dcSSimon Schubert   if (eind->dyn_relocs != NULL)
10045796c8dcSSimon Schubert     {
10055796c8dcSSimon Schubert       if (edir->dyn_relocs != NULL)
10065796c8dcSSimon Schubert 	{
10075796c8dcSSimon Schubert 	  struct elf_dyn_relocs **pp;
10085796c8dcSSimon Schubert 	  struct elf_dyn_relocs *p;
10095796c8dcSSimon Schubert 
10105796c8dcSSimon Schubert 	  /* Add reloc counts against the indirect sym to the direct sym
10115796c8dcSSimon Schubert 	     list.  Merge any entries against the same section.  */
10125796c8dcSSimon Schubert 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
10135796c8dcSSimon Schubert 	    {
10145796c8dcSSimon Schubert 	      struct elf_dyn_relocs *q;
10155796c8dcSSimon Schubert 
10165796c8dcSSimon Schubert 	      for (q = edir->dyn_relocs; q != NULL; q = q->next)
10175796c8dcSSimon Schubert 		if (q->sec == p->sec)
10185796c8dcSSimon Schubert 		  {
10195796c8dcSSimon Schubert 		    q->pc_count += p->pc_count;
10205796c8dcSSimon Schubert 		    q->count += p->count;
10215796c8dcSSimon Schubert 		    *pp = p->next;
10225796c8dcSSimon Schubert 		    break;
10235796c8dcSSimon Schubert 		  }
10245796c8dcSSimon Schubert 	      if (q == NULL)
10255796c8dcSSimon Schubert 		pp = &p->next;
10265796c8dcSSimon Schubert 	    }
10275796c8dcSSimon Schubert 	  *pp = edir->dyn_relocs;
10285796c8dcSSimon Schubert 	}
10295796c8dcSSimon Schubert 
10305796c8dcSSimon Schubert       edir->dyn_relocs = eind->dyn_relocs;
10315796c8dcSSimon Schubert       eind->dyn_relocs = NULL;
10325796c8dcSSimon Schubert     }
10335796c8dcSSimon Schubert 
10345796c8dcSSimon Schubert   if (ind->root.type == bfd_link_hash_indirect
10355796c8dcSSimon Schubert       && dir->got.refcount <= 0)
10365796c8dcSSimon Schubert     {
10375796c8dcSSimon Schubert       edir->tls_type = eind->tls_type;
10385796c8dcSSimon Schubert       eind->tls_type = GOT_UNKNOWN;
10395796c8dcSSimon Schubert     }
10405796c8dcSSimon Schubert 
10415796c8dcSSimon Schubert   if (ELIMINATE_COPY_RELOCS
10425796c8dcSSimon Schubert       && ind->root.type != bfd_link_hash_indirect
10435796c8dcSSimon Schubert       && dir->dynamic_adjusted)
10445796c8dcSSimon Schubert     {
10455796c8dcSSimon Schubert       /* If called to transfer flags for a weakdef during processing
10465796c8dcSSimon Schubert 	 of elf_adjust_dynamic_symbol, don't copy non_got_ref.
10475796c8dcSSimon Schubert 	 We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
10485796c8dcSSimon Schubert       dir->ref_dynamic |= ind->ref_dynamic;
10495796c8dcSSimon Schubert       dir->ref_regular |= ind->ref_regular;
10505796c8dcSSimon Schubert       dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
10515796c8dcSSimon Schubert       dir->needs_plt |= ind->needs_plt;
10525796c8dcSSimon Schubert       dir->pointer_equality_needed |= ind->pointer_equality_needed;
10535796c8dcSSimon Schubert     }
10545796c8dcSSimon Schubert   else
10555796c8dcSSimon Schubert     _bfd_elf_link_hash_copy_indirect (info, dir, ind);
10565796c8dcSSimon Schubert }
10575796c8dcSSimon Schubert 
10585796c8dcSSimon Schubert static bfd_boolean
elf64_x86_64_elf_object_p(bfd * abfd)10595796c8dcSSimon Schubert elf64_x86_64_elf_object_p (bfd *abfd)
10605796c8dcSSimon Schubert {
10615796c8dcSSimon Schubert   /* Set the right machine number for an x86-64 elf64 file.  */
10625796c8dcSSimon Schubert   bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
10635796c8dcSSimon Schubert   return TRUE;
10645796c8dcSSimon Schubert }
10655796c8dcSSimon Schubert 
1066*ef5ccd6cSJohn Marino static bfd_boolean
elf32_x86_64_elf_object_p(bfd * abfd)1067*ef5ccd6cSJohn Marino elf32_x86_64_elf_object_p (bfd *abfd)
1068*ef5ccd6cSJohn Marino {
1069*ef5ccd6cSJohn Marino   /* Set the right machine number for an x86-64 elf32 file.  */
1070*ef5ccd6cSJohn Marino   bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x64_32);
1071*ef5ccd6cSJohn Marino   return TRUE;
1072*ef5ccd6cSJohn Marino }
1073*ef5ccd6cSJohn Marino 
10745796c8dcSSimon Schubert /* Return TRUE if the TLS access code sequence support transition
10755796c8dcSSimon Schubert    from R_TYPE.  */
10765796c8dcSSimon Schubert 
10775796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_check_tls_transition(bfd * abfd,struct bfd_link_info * info,asection * sec,bfd_byte * contents,Elf_Internal_Shdr * symtab_hdr,struct elf_link_hash_entry ** sym_hashes,unsigned int r_type,const Elf_Internal_Rela * rel,const Elf_Internal_Rela * relend)1078c50c785cSJohn Marino elf_x86_64_check_tls_transition (bfd *abfd,
1079c50c785cSJohn Marino 				 struct bfd_link_info *info,
1080c50c785cSJohn Marino 				 asection *sec,
10815796c8dcSSimon Schubert 				 bfd_byte *contents,
10825796c8dcSSimon Schubert 				 Elf_Internal_Shdr *symtab_hdr,
10835796c8dcSSimon Schubert 				 struct elf_link_hash_entry **sym_hashes,
10845796c8dcSSimon Schubert 				 unsigned int r_type,
10855796c8dcSSimon Schubert 				 const Elf_Internal_Rela *rel,
10865796c8dcSSimon Schubert 				 const Elf_Internal_Rela *relend)
10875796c8dcSSimon Schubert {
10885796c8dcSSimon Schubert   unsigned int val;
10895796c8dcSSimon Schubert   unsigned long r_symndx;
10905796c8dcSSimon Schubert   struct elf_link_hash_entry *h;
10915796c8dcSSimon Schubert   bfd_vma offset;
1092c50c785cSJohn Marino   struct elf_x86_64_link_hash_table *htab;
10935796c8dcSSimon Schubert 
10945796c8dcSSimon Schubert   /* Get the section contents.  */
10955796c8dcSSimon Schubert   if (contents == NULL)
10965796c8dcSSimon Schubert     {
10975796c8dcSSimon Schubert       if (elf_section_data (sec)->this_hdr.contents != NULL)
10985796c8dcSSimon Schubert 	contents = elf_section_data (sec)->this_hdr.contents;
10995796c8dcSSimon Schubert       else
11005796c8dcSSimon Schubert 	{
11015796c8dcSSimon Schubert 	  /* FIXME: How to better handle error condition?  */
11025796c8dcSSimon Schubert 	  if (!bfd_malloc_and_get_section (abfd, sec, &contents))
11035796c8dcSSimon Schubert 	    return FALSE;
11045796c8dcSSimon Schubert 
11055796c8dcSSimon Schubert 	  /* Cache the section contents for elf_link_input_bfd.  */
11065796c8dcSSimon Schubert 	  elf_section_data (sec)->this_hdr.contents = contents;
11075796c8dcSSimon Schubert 	}
11085796c8dcSSimon Schubert     }
11095796c8dcSSimon Schubert 
1110c50c785cSJohn Marino   htab = elf_x86_64_hash_table (info);
11115796c8dcSSimon Schubert   offset = rel->r_offset;
11125796c8dcSSimon Schubert   switch (r_type)
11135796c8dcSSimon Schubert     {
11145796c8dcSSimon Schubert     case R_X86_64_TLSGD:
11155796c8dcSSimon Schubert     case R_X86_64_TLSLD:
11165796c8dcSSimon Schubert       if ((rel + 1) >= relend)
11175796c8dcSSimon Schubert 	return FALSE;
11185796c8dcSSimon Schubert 
11195796c8dcSSimon Schubert       if (r_type == R_X86_64_TLSGD)
11205796c8dcSSimon Schubert 	{
1121c50c785cSJohn Marino 	  /* Check transition from GD access model.  For 64bit, only
11225796c8dcSSimon Schubert 		.byte 0x66; leaq foo@tlsgd(%rip), %rdi
11235796c8dcSSimon Schubert 		.word 0x6666; rex64; call __tls_get_addr
1124c50c785cSJohn Marino 	     can transit to different access model.  For 32bit, only
1125c50c785cSJohn Marino 		leaq foo@tlsgd(%rip), %rdi
1126c50c785cSJohn Marino 		.word 0x6666; rex64; call __tls_get_addr
11275796c8dcSSimon Schubert 	     can transit to different access model.  */
11285796c8dcSSimon Schubert 
1129a45ae5f8SJohn Marino 	  static const unsigned char call[] = { 0x66, 0x66, 0x48, 0xe8 };
1130a45ae5f8SJohn Marino 	  static const unsigned char leaq[] = { 0x66, 0x48, 0x8d, 0x3d };
1131a45ae5f8SJohn Marino 
1132c50c785cSJohn Marino 	  if ((offset + 12) > sec->size
1133a45ae5f8SJohn Marino 	      || memcmp (contents + offset + 4, call, 4) != 0)
11345796c8dcSSimon Schubert 	    return FALSE;
1135c50c785cSJohn Marino 
1136c50c785cSJohn Marino 	  if (ABI_64_P (abfd))
1137c50c785cSJohn Marino 	    {
1138c50c785cSJohn Marino 	      if (offset < 4
1139a45ae5f8SJohn Marino 		  || memcmp (contents + offset - 4, leaq, 4) != 0)
1140c50c785cSJohn Marino 		return FALSE;
1141c50c785cSJohn Marino 	    }
1142c50c785cSJohn Marino 	  else
1143c50c785cSJohn Marino 	    {
1144c50c785cSJohn Marino 	      if (offset < 3
1145a45ae5f8SJohn Marino 		  || memcmp (contents + offset - 3, leaq + 1, 3) != 0)
1146c50c785cSJohn Marino 		return FALSE;
1147c50c785cSJohn Marino 	    }
11485796c8dcSSimon Schubert 	}
11495796c8dcSSimon Schubert       else
11505796c8dcSSimon Schubert 	{
11515796c8dcSSimon Schubert 	  /* Check transition from LD access model.  Only
11525796c8dcSSimon Schubert 		leaq foo@tlsld(%rip), %rdi;
11535796c8dcSSimon Schubert 		call __tls_get_addr
11545796c8dcSSimon Schubert 	     can transit to different access model.  */
11555796c8dcSSimon Schubert 
1156a45ae5f8SJohn Marino 	  static const unsigned char lea[] = { 0x48, 0x8d, 0x3d };
11575796c8dcSSimon Schubert 
11585796c8dcSSimon Schubert 	  if (offset < 3 || (offset + 9) > sec->size)
11595796c8dcSSimon Schubert 	    return FALSE;
11605796c8dcSSimon Schubert 
1161a45ae5f8SJohn Marino 	  if (memcmp (contents + offset - 3, lea, 3) != 0
1162a45ae5f8SJohn Marino 	      || 0xe8 != *(contents + offset + 4))
11635796c8dcSSimon Schubert 	    return FALSE;
11645796c8dcSSimon Schubert 	}
11655796c8dcSSimon Schubert 
1166c50c785cSJohn Marino       r_symndx = htab->r_sym (rel[1].r_info);
11675796c8dcSSimon Schubert       if (r_symndx < symtab_hdr->sh_info)
11685796c8dcSSimon Schubert 	return FALSE;
11695796c8dcSSimon Schubert 
11705796c8dcSSimon Schubert       h = sym_hashes[r_symndx - symtab_hdr->sh_info];
11715796c8dcSSimon Schubert       /* Use strncmp to check __tls_get_addr since __tls_get_addr
11725796c8dcSSimon Schubert 	 may be versioned.  */
11735796c8dcSSimon Schubert       return (h != NULL
11745796c8dcSSimon Schubert 	      && h->root.root.string != NULL
1175c50c785cSJohn Marino 	      && (ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PC32
1176c50c785cSJohn Marino 		  || ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PLT32)
11775796c8dcSSimon Schubert 	      && (strncmp (h->root.root.string,
11785796c8dcSSimon Schubert 			   "__tls_get_addr", 14) == 0));
11795796c8dcSSimon Schubert 
11805796c8dcSSimon Schubert     case R_X86_64_GOTTPOFF:
11815796c8dcSSimon Schubert       /* Check transition from IE access model:
1182c50c785cSJohn Marino 		mov foo@gottpoff(%rip), %reg
1183c50c785cSJohn Marino 		add foo@gottpoff(%rip), %reg
11845796c8dcSSimon Schubert        */
11855796c8dcSSimon Schubert 
1186c50c785cSJohn Marino       /* Check REX prefix first.  */
1187c50c785cSJohn Marino       if (offset >= 3 && (offset + 4) <= sec->size)
1188c50c785cSJohn Marino 	{
11895796c8dcSSimon Schubert 	  val = bfd_get_8 (abfd, contents + offset - 3);
11905796c8dcSSimon Schubert 	  if (val != 0x48 && val != 0x4c)
1191c50c785cSJohn Marino 	    {
1192c50c785cSJohn Marino 	      /* X32 may have 0x44 REX prefix or no REX prefix.  */
1193c50c785cSJohn Marino 	      if (ABI_64_P (abfd))
11945796c8dcSSimon Schubert 		return FALSE;
1195c50c785cSJohn Marino 	    }
1196c50c785cSJohn Marino 	}
1197c50c785cSJohn Marino       else
1198c50c785cSJohn Marino 	{
1199c50c785cSJohn Marino 	  /* X32 may not have any REX prefix.  */
1200c50c785cSJohn Marino 	  if (ABI_64_P (abfd))
1201c50c785cSJohn Marino 	    return FALSE;
1202c50c785cSJohn Marino 	  if (offset < 2 || (offset + 3) > sec->size)
1203c50c785cSJohn Marino 	    return FALSE;
1204c50c785cSJohn Marino 	}
12055796c8dcSSimon Schubert 
12065796c8dcSSimon Schubert       val = bfd_get_8 (abfd, contents + offset - 2);
12075796c8dcSSimon Schubert       if (val != 0x8b && val != 0x03)
12085796c8dcSSimon Schubert 	return FALSE;
12095796c8dcSSimon Schubert 
12105796c8dcSSimon Schubert       val = bfd_get_8 (abfd, contents + offset - 1);
12115796c8dcSSimon Schubert       return (val & 0xc7) == 5;
12125796c8dcSSimon Schubert 
12135796c8dcSSimon Schubert     case R_X86_64_GOTPC32_TLSDESC:
12145796c8dcSSimon Schubert       /* Check transition from GDesc access model:
12155796c8dcSSimon Schubert 		leaq x@tlsdesc(%rip), %rax
12165796c8dcSSimon Schubert 
12175796c8dcSSimon Schubert 	 Make sure it's a leaq adding rip to a 32-bit offset
12185796c8dcSSimon Schubert 	 into any register, although it's probably almost always
12195796c8dcSSimon Schubert 	 going to be rax.  */
12205796c8dcSSimon Schubert 
12215796c8dcSSimon Schubert       if (offset < 3 || (offset + 4) > sec->size)
12225796c8dcSSimon Schubert 	return FALSE;
12235796c8dcSSimon Schubert 
12245796c8dcSSimon Schubert       val = bfd_get_8 (abfd, contents + offset - 3);
12255796c8dcSSimon Schubert       if ((val & 0xfb) != 0x48)
12265796c8dcSSimon Schubert 	return FALSE;
12275796c8dcSSimon Schubert 
12285796c8dcSSimon Schubert       if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d)
12295796c8dcSSimon Schubert 	return FALSE;
12305796c8dcSSimon Schubert 
12315796c8dcSSimon Schubert       val = bfd_get_8 (abfd, contents + offset - 1);
12325796c8dcSSimon Schubert       return (val & 0xc7) == 0x05;
12335796c8dcSSimon Schubert 
12345796c8dcSSimon Schubert     case R_X86_64_TLSDESC_CALL:
12355796c8dcSSimon Schubert       /* Check transition from GDesc access model:
12365796c8dcSSimon Schubert 		call *x@tlsdesc(%rax)
12375796c8dcSSimon Schubert        */
12385796c8dcSSimon Schubert       if (offset + 2 <= sec->size)
12395796c8dcSSimon Schubert 	{
12405796c8dcSSimon Schubert 	  /* Make sure that it's a call *x@tlsdesc(%rax).  */
1241a45ae5f8SJohn Marino 	  static const unsigned char call[] = { 0xff, 0x10 };
1242a45ae5f8SJohn Marino 	  return memcmp (contents + offset, call, 2) == 0;
12435796c8dcSSimon Schubert 	}
12445796c8dcSSimon Schubert 
12455796c8dcSSimon Schubert       return FALSE;
12465796c8dcSSimon Schubert 
12475796c8dcSSimon Schubert     default:
12485796c8dcSSimon Schubert       abort ();
12495796c8dcSSimon Schubert     }
12505796c8dcSSimon Schubert }
12515796c8dcSSimon Schubert 
12525796c8dcSSimon Schubert /* Return TRUE if the TLS access transition is OK or no transition
12535796c8dcSSimon Schubert    will be performed.  Update R_TYPE if there is a transition.  */
12545796c8dcSSimon Schubert 
12555796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_tls_transition(struct bfd_link_info * info,bfd * abfd,asection * sec,bfd_byte * contents,Elf_Internal_Shdr * symtab_hdr,struct elf_link_hash_entry ** sym_hashes,unsigned int * r_type,int tls_type,const Elf_Internal_Rela * rel,const Elf_Internal_Rela * relend,struct elf_link_hash_entry * h,unsigned long r_symndx)1256c50c785cSJohn Marino elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
12575796c8dcSSimon Schubert 			   asection *sec, bfd_byte *contents,
12585796c8dcSSimon Schubert 			   Elf_Internal_Shdr *symtab_hdr,
12595796c8dcSSimon Schubert 			   struct elf_link_hash_entry **sym_hashes,
12605796c8dcSSimon Schubert 			   unsigned int *r_type, int tls_type,
12615796c8dcSSimon Schubert 			   const Elf_Internal_Rela *rel,
12625796c8dcSSimon Schubert 			   const Elf_Internal_Rela *relend,
12635796c8dcSSimon Schubert 			   struct elf_link_hash_entry *h,
12645796c8dcSSimon Schubert 			   unsigned long r_symndx)
12655796c8dcSSimon Schubert {
12665796c8dcSSimon Schubert   unsigned int from_type = *r_type;
12675796c8dcSSimon Schubert   unsigned int to_type = from_type;
12685796c8dcSSimon Schubert   bfd_boolean check = TRUE;
12695796c8dcSSimon Schubert 
1270c50c785cSJohn Marino   /* Skip TLS transition for functions.  */
1271c50c785cSJohn Marino   if (h != NULL
1272c50c785cSJohn Marino       && (h->type == STT_FUNC
1273c50c785cSJohn Marino 	  || h->type == STT_GNU_IFUNC))
1274c50c785cSJohn Marino     return TRUE;
1275c50c785cSJohn Marino 
12765796c8dcSSimon Schubert   switch (from_type)
12775796c8dcSSimon Schubert     {
12785796c8dcSSimon Schubert     case R_X86_64_TLSGD:
12795796c8dcSSimon Schubert     case R_X86_64_GOTPC32_TLSDESC:
12805796c8dcSSimon Schubert     case R_X86_64_TLSDESC_CALL:
12815796c8dcSSimon Schubert     case R_X86_64_GOTTPOFF:
12825796c8dcSSimon Schubert       if (info->executable)
12835796c8dcSSimon Schubert 	{
12845796c8dcSSimon Schubert 	  if (h == NULL)
12855796c8dcSSimon Schubert 	    to_type = R_X86_64_TPOFF32;
12865796c8dcSSimon Schubert 	  else
12875796c8dcSSimon Schubert 	    to_type = R_X86_64_GOTTPOFF;
12885796c8dcSSimon Schubert 	}
12895796c8dcSSimon Schubert 
1290c50c785cSJohn Marino       /* When we are called from elf_x86_64_relocate_section,
12915796c8dcSSimon Schubert 	 CONTENTS isn't NULL and there may be additional transitions
12925796c8dcSSimon Schubert 	 based on TLS_TYPE.  */
12935796c8dcSSimon Schubert       if (contents != NULL)
12945796c8dcSSimon Schubert 	{
12955796c8dcSSimon Schubert 	  unsigned int new_to_type = to_type;
12965796c8dcSSimon Schubert 
12975796c8dcSSimon Schubert 	  if (info->executable
12985796c8dcSSimon Schubert 	      && h != NULL
12995796c8dcSSimon Schubert 	      && h->dynindx == -1
13005796c8dcSSimon Schubert 	      && tls_type == GOT_TLS_IE)
13015796c8dcSSimon Schubert 	    new_to_type = R_X86_64_TPOFF32;
13025796c8dcSSimon Schubert 
13035796c8dcSSimon Schubert 	  if (to_type == R_X86_64_TLSGD
13045796c8dcSSimon Schubert 	      || to_type == R_X86_64_GOTPC32_TLSDESC
13055796c8dcSSimon Schubert 	      || to_type == R_X86_64_TLSDESC_CALL)
13065796c8dcSSimon Schubert 	    {
13075796c8dcSSimon Schubert 	      if (tls_type == GOT_TLS_IE)
13085796c8dcSSimon Schubert 		new_to_type = R_X86_64_GOTTPOFF;
13095796c8dcSSimon Schubert 	    }
13105796c8dcSSimon Schubert 
13115796c8dcSSimon Schubert 	  /* We checked the transition before when we were called from
1312c50c785cSJohn Marino 	     elf_x86_64_check_relocs.  We only want to check the new
13135796c8dcSSimon Schubert 	     transition which hasn't been checked before.  */
13145796c8dcSSimon Schubert 	  check = new_to_type != to_type && from_type == to_type;
13155796c8dcSSimon Schubert 	  to_type = new_to_type;
13165796c8dcSSimon Schubert 	}
13175796c8dcSSimon Schubert 
13185796c8dcSSimon Schubert       break;
13195796c8dcSSimon Schubert 
13205796c8dcSSimon Schubert     case R_X86_64_TLSLD:
13215796c8dcSSimon Schubert       if (info->executable)
13225796c8dcSSimon Schubert 	to_type = R_X86_64_TPOFF32;
13235796c8dcSSimon Schubert       break;
13245796c8dcSSimon Schubert 
13255796c8dcSSimon Schubert     default:
13265796c8dcSSimon Schubert       return TRUE;
13275796c8dcSSimon Schubert     }
13285796c8dcSSimon Schubert 
13295796c8dcSSimon Schubert   /* Return TRUE if there is no transition.  */
13305796c8dcSSimon Schubert   if (from_type == to_type)
13315796c8dcSSimon Schubert     return TRUE;
13325796c8dcSSimon Schubert 
13335796c8dcSSimon Schubert   /* Check if the transition can be performed.  */
13345796c8dcSSimon Schubert   if (check
1335c50c785cSJohn Marino       && ! elf_x86_64_check_tls_transition (abfd, info, sec, contents,
13365796c8dcSSimon Schubert 					    symtab_hdr, sym_hashes,
13375796c8dcSSimon Schubert 					    from_type, rel, relend))
13385796c8dcSSimon Schubert     {
13395796c8dcSSimon Schubert       reloc_howto_type *from, *to;
13405796c8dcSSimon Schubert       const char *name;
13415796c8dcSSimon Schubert 
1342c50c785cSJohn Marino       from = elf_x86_64_rtype_to_howto (abfd, from_type);
1343c50c785cSJohn Marino       to = elf_x86_64_rtype_to_howto (abfd, to_type);
13445796c8dcSSimon Schubert 
13455796c8dcSSimon Schubert       if (h)
13465796c8dcSSimon Schubert 	name = h->root.root.string;
13475796c8dcSSimon Schubert       else
13485796c8dcSSimon Schubert 	{
1349c50c785cSJohn Marino 	  struct elf_x86_64_link_hash_table *htab;
1350cf7f2e2dSJohn Marino 
1351c50c785cSJohn Marino 	  htab = elf_x86_64_hash_table (info);
1352cf7f2e2dSJohn Marino 	  if (htab == NULL)
1353cf7f2e2dSJohn Marino 	    name = "*unknown*";
1354cf7f2e2dSJohn Marino 	  else
1355cf7f2e2dSJohn Marino 	    {
1356cf7f2e2dSJohn Marino 	      Elf_Internal_Sym *isym;
1357cf7f2e2dSJohn Marino 
13585796c8dcSSimon Schubert 	      isym = bfd_sym_from_r_symndx (&htab->sym_cache,
13595796c8dcSSimon Schubert 					    abfd, r_symndx);
13605796c8dcSSimon Schubert 	      name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
13615796c8dcSSimon Schubert 	    }
1362cf7f2e2dSJohn Marino 	}
13635796c8dcSSimon Schubert 
13645796c8dcSSimon Schubert       (*_bfd_error_handler)
13655796c8dcSSimon Schubert 	(_("%B: TLS transition from %s to %s against `%s' at 0x%lx "
13665796c8dcSSimon Schubert 	   "in section `%A' failed"),
13675796c8dcSSimon Schubert 	 abfd, sec, from->name, to->name, name,
13685796c8dcSSimon Schubert 	 (unsigned long) rel->r_offset);
13695796c8dcSSimon Schubert       bfd_set_error (bfd_error_bad_value);
13705796c8dcSSimon Schubert       return FALSE;
13715796c8dcSSimon Schubert     }
13725796c8dcSSimon Schubert 
13735796c8dcSSimon Schubert   *r_type = to_type;
13745796c8dcSSimon Schubert   return TRUE;
13755796c8dcSSimon Schubert }
13765796c8dcSSimon Schubert 
13775796c8dcSSimon Schubert /* Look through the relocs for a section during the first phase, and
13785796c8dcSSimon Schubert    calculate needed space in the global offset table, procedure
13795796c8dcSSimon Schubert    linkage table, and dynamic reloc sections.  */
13805796c8dcSSimon Schubert 
13815796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_check_relocs(bfd * abfd,struct bfd_link_info * info,asection * sec,const Elf_Internal_Rela * relocs)1382c50c785cSJohn Marino elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
13835796c8dcSSimon Schubert 			 asection *sec,
13845796c8dcSSimon Schubert 			 const Elf_Internal_Rela *relocs)
13855796c8dcSSimon Schubert {
1386c50c785cSJohn Marino   struct elf_x86_64_link_hash_table *htab;
13875796c8dcSSimon Schubert   Elf_Internal_Shdr *symtab_hdr;
13885796c8dcSSimon Schubert   struct elf_link_hash_entry **sym_hashes;
13895796c8dcSSimon Schubert   const Elf_Internal_Rela *rel;
13905796c8dcSSimon Schubert   const Elf_Internal_Rela *rel_end;
13915796c8dcSSimon Schubert   asection *sreloc;
13925796c8dcSSimon Schubert 
13935796c8dcSSimon Schubert   if (info->relocatable)
13945796c8dcSSimon Schubert     return TRUE;
13955796c8dcSSimon Schubert 
13965796c8dcSSimon Schubert   BFD_ASSERT (is_x86_64_elf (abfd));
13975796c8dcSSimon Schubert 
1398c50c785cSJohn Marino   htab = elf_x86_64_hash_table (info);
1399cf7f2e2dSJohn Marino   if (htab == NULL)
1400cf7f2e2dSJohn Marino     return FALSE;
1401cf7f2e2dSJohn Marino 
14025796c8dcSSimon Schubert   symtab_hdr = &elf_symtab_hdr (abfd);
14035796c8dcSSimon Schubert   sym_hashes = elf_sym_hashes (abfd);
14045796c8dcSSimon Schubert 
14055796c8dcSSimon Schubert   sreloc = NULL;
14065796c8dcSSimon Schubert 
14075796c8dcSSimon Schubert   rel_end = relocs + sec->reloc_count;
14085796c8dcSSimon Schubert   for (rel = relocs; rel < rel_end; rel++)
14095796c8dcSSimon Schubert     {
14105796c8dcSSimon Schubert       unsigned int r_type;
14115796c8dcSSimon Schubert       unsigned long r_symndx;
14125796c8dcSSimon Schubert       struct elf_link_hash_entry *h;
14135796c8dcSSimon Schubert       Elf_Internal_Sym *isym;
14145796c8dcSSimon Schubert       const char *name;
1415*ef5ccd6cSJohn Marino       bfd_boolean size_reloc;
14165796c8dcSSimon Schubert 
1417c50c785cSJohn Marino       r_symndx = htab->r_sym (rel->r_info);
1418c50c785cSJohn Marino       r_type = ELF32_R_TYPE (rel->r_info);
14195796c8dcSSimon Schubert 
14205796c8dcSSimon Schubert       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
14215796c8dcSSimon Schubert 	{
14225796c8dcSSimon Schubert 	  (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
14235796c8dcSSimon Schubert 				 abfd, r_symndx);
14245796c8dcSSimon Schubert 	  return FALSE;
14255796c8dcSSimon Schubert 	}
14265796c8dcSSimon Schubert 
14275796c8dcSSimon Schubert       if (r_symndx < symtab_hdr->sh_info)
14285796c8dcSSimon Schubert 	{
14295796c8dcSSimon Schubert 	  /* A local symbol.  */
14305796c8dcSSimon Schubert 	  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
14315796c8dcSSimon Schubert 					abfd, r_symndx);
14325796c8dcSSimon Schubert 	  if (isym == NULL)
14335796c8dcSSimon Schubert 	    return FALSE;
14345796c8dcSSimon Schubert 
14355796c8dcSSimon Schubert 	  /* Check relocation against local STT_GNU_IFUNC symbol.  */
1436c50c785cSJohn Marino 	  if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
14375796c8dcSSimon Schubert 	    {
1438c50c785cSJohn Marino 	      h = elf_x86_64_get_local_sym_hash (htab, abfd, rel,
14395796c8dcSSimon Schubert 						 TRUE);
14405796c8dcSSimon Schubert 	      if (h == NULL)
14415796c8dcSSimon Schubert 		return FALSE;
14425796c8dcSSimon Schubert 
14435796c8dcSSimon Schubert 	      /* Fake a STT_GNU_IFUNC symbol.  */
14445796c8dcSSimon Schubert 	      h->type = STT_GNU_IFUNC;
14455796c8dcSSimon Schubert 	      h->def_regular = 1;
14465796c8dcSSimon Schubert 	      h->ref_regular = 1;
14475796c8dcSSimon Schubert 	      h->forced_local = 1;
14485796c8dcSSimon Schubert 	      h->root.type = bfd_link_hash_defined;
14495796c8dcSSimon Schubert 	    }
14505796c8dcSSimon Schubert 	  else
14515796c8dcSSimon Schubert 	    h = NULL;
14525796c8dcSSimon Schubert 	}
14535796c8dcSSimon Schubert       else
14545796c8dcSSimon Schubert 	{
14555796c8dcSSimon Schubert 	  isym = NULL;
14565796c8dcSSimon Schubert 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
14575796c8dcSSimon Schubert 	  while (h->root.type == bfd_link_hash_indirect
14585796c8dcSSimon Schubert 		 || h->root.type == bfd_link_hash_warning)
14595796c8dcSSimon Schubert 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
14605796c8dcSSimon Schubert 	}
14615796c8dcSSimon Schubert 
1462c50c785cSJohn Marino       /* Check invalid x32 relocations.  */
1463c50c785cSJohn Marino       if (!ABI_64_P (abfd))
1464c50c785cSJohn Marino 	switch (r_type)
1465c50c785cSJohn Marino 	  {
1466c50c785cSJohn Marino 	  default:
1467c50c785cSJohn Marino 	    break;
1468c50c785cSJohn Marino 
1469c50c785cSJohn Marino 	  case R_X86_64_DTPOFF64:
1470c50c785cSJohn Marino 	  case R_X86_64_TPOFF64:
1471c50c785cSJohn Marino 	  case R_X86_64_PC64:
1472c50c785cSJohn Marino 	  case R_X86_64_GOTOFF64:
1473c50c785cSJohn Marino 	  case R_X86_64_GOT64:
1474c50c785cSJohn Marino 	  case R_X86_64_GOTPCREL64:
1475c50c785cSJohn Marino 	  case R_X86_64_GOTPC64:
1476c50c785cSJohn Marino 	  case R_X86_64_GOTPLT64:
1477c50c785cSJohn Marino 	  case R_X86_64_PLTOFF64:
1478c50c785cSJohn Marino 	      {
1479c50c785cSJohn Marino 		if (h)
1480c50c785cSJohn Marino 		  name = h->root.root.string;
1481c50c785cSJohn Marino 		else
1482c50c785cSJohn Marino 		  name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
1483c50c785cSJohn Marino 					   NULL);
1484c50c785cSJohn Marino 		(*_bfd_error_handler)
1485c50c785cSJohn Marino 		  (_("%B: relocation %s against symbol `%s' isn't "
1486c50c785cSJohn Marino 		     "supported in x32 mode"), abfd,
1487c50c785cSJohn Marino 		   x86_64_elf_howto_table[r_type].name, name);
1488c50c785cSJohn Marino 		bfd_set_error (bfd_error_bad_value);
1489c50c785cSJohn Marino 		return FALSE;
1490c50c785cSJohn Marino 	      }
1491c50c785cSJohn Marino 	    break;
1492c50c785cSJohn Marino 	  }
1493c50c785cSJohn Marino 
14945796c8dcSSimon Schubert       if (h != NULL)
14955796c8dcSSimon Schubert 	{
14965796c8dcSSimon Schubert 	  /* Create the ifunc sections for static executables.  If we
14975796c8dcSSimon Schubert 	     never see an indirect function symbol nor we are building
14985796c8dcSSimon Schubert 	     a static executable, those sections will be empty and
14995796c8dcSSimon Schubert 	     won't appear in output.  */
15005796c8dcSSimon Schubert 	  switch (r_type)
15015796c8dcSSimon Schubert 	    {
15025796c8dcSSimon Schubert 	    default:
15035796c8dcSSimon Schubert 	      break;
15045796c8dcSSimon Schubert 
15055796c8dcSSimon Schubert 	    case R_X86_64_32S:
15065796c8dcSSimon Schubert 	    case R_X86_64_32:
15075796c8dcSSimon Schubert 	    case R_X86_64_64:
15085796c8dcSSimon Schubert 	    case R_X86_64_PC32:
15095796c8dcSSimon Schubert 	    case R_X86_64_PC64:
15105796c8dcSSimon Schubert 	    case R_X86_64_PLT32:
15115796c8dcSSimon Schubert 	    case R_X86_64_GOTPCREL:
15125796c8dcSSimon Schubert 	    case R_X86_64_GOTPCREL64:
1513a45ae5f8SJohn Marino 	      if (htab->elf.dynobj == NULL)
1514a45ae5f8SJohn Marino 		htab->elf.dynobj = abfd;
1515a45ae5f8SJohn Marino 	      if (!_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
15165796c8dcSSimon Schubert 		return FALSE;
15175796c8dcSSimon Schubert 	      break;
15185796c8dcSSimon Schubert 	    }
15195796c8dcSSimon Schubert 
15205796c8dcSSimon Schubert 	  /* It is referenced by a non-shared object. */
15215796c8dcSSimon Schubert 	  h->ref_regular = 1;
15225796c8dcSSimon Schubert 	}
15235796c8dcSSimon Schubert 
1524c50c785cSJohn Marino       if (! elf_x86_64_tls_transition (info, abfd, sec, NULL,
15255796c8dcSSimon Schubert 				       symtab_hdr, sym_hashes,
15265796c8dcSSimon Schubert 				       &r_type, GOT_UNKNOWN,
15275796c8dcSSimon Schubert 				       rel, rel_end, h, r_symndx))
15285796c8dcSSimon Schubert 	return FALSE;
15295796c8dcSSimon Schubert 
15305796c8dcSSimon Schubert       switch (r_type)
15315796c8dcSSimon Schubert 	{
15325796c8dcSSimon Schubert 	case R_X86_64_TLSLD:
15335796c8dcSSimon Schubert 	  htab->tls_ld_got.refcount += 1;
15345796c8dcSSimon Schubert 	  goto create_got;
15355796c8dcSSimon Schubert 
15365796c8dcSSimon Schubert 	case R_X86_64_TPOFF32:
1537c50c785cSJohn Marino 	  if (!info->executable && ABI_64_P (abfd))
15385796c8dcSSimon Schubert 	    {
15395796c8dcSSimon Schubert 	      if (h)
15405796c8dcSSimon Schubert 		name = h->root.root.string;
15415796c8dcSSimon Schubert 	      else
15425796c8dcSSimon Schubert 		name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
15435796c8dcSSimon Schubert 					 NULL);
15445796c8dcSSimon Schubert 	      (*_bfd_error_handler)
15455796c8dcSSimon Schubert 		(_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
15465796c8dcSSimon Schubert 		 abfd,
15475796c8dcSSimon Schubert 		 x86_64_elf_howto_table[r_type].name, name);
15485796c8dcSSimon Schubert 	      bfd_set_error (bfd_error_bad_value);
15495796c8dcSSimon Schubert 	      return FALSE;
15505796c8dcSSimon Schubert 	    }
15515796c8dcSSimon Schubert 	  break;
15525796c8dcSSimon Schubert 
15535796c8dcSSimon Schubert 	case R_X86_64_GOTTPOFF:
15545796c8dcSSimon Schubert 	  if (!info->executable)
15555796c8dcSSimon Schubert 	    info->flags |= DF_STATIC_TLS;
15565796c8dcSSimon Schubert 	  /* Fall through */
15575796c8dcSSimon Schubert 
15585796c8dcSSimon Schubert 	case R_X86_64_GOT32:
15595796c8dcSSimon Schubert 	case R_X86_64_GOTPCREL:
15605796c8dcSSimon Schubert 	case R_X86_64_TLSGD:
15615796c8dcSSimon Schubert 	case R_X86_64_GOT64:
15625796c8dcSSimon Schubert 	case R_X86_64_GOTPCREL64:
15635796c8dcSSimon Schubert 	case R_X86_64_GOTPLT64:
15645796c8dcSSimon Schubert 	case R_X86_64_GOTPC32_TLSDESC:
15655796c8dcSSimon Schubert 	case R_X86_64_TLSDESC_CALL:
15665796c8dcSSimon Schubert 	  /* This symbol requires a global offset table entry.	*/
15675796c8dcSSimon Schubert 	  {
15685796c8dcSSimon Schubert 	    int tls_type, old_tls_type;
15695796c8dcSSimon Schubert 
15705796c8dcSSimon Schubert 	    switch (r_type)
15715796c8dcSSimon Schubert 	      {
15725796c8dcSSimon Schubert 	      default: tls_type = GOT_NORMAL; break;
15735796c8dcSSimon Schubert 	      case R_X86_64_TLSGD: tls_type = GOT_TLS_GD; break;
15745796c8dcSSimon Schubert 	      case R_X86_64_GOTTPOFF: tls_type = GOT_TLS_IE; break;
15755796c8dcSSimon Schubert 	      case R_X86_64_GOTPC32_TLSDESC:
15765796c8dcSSimon Schubert 	      case R_X86_64_TLSDESC_CALL:
15775796c8dcSSimon Schubert 		tls_type = GOT_TLS_GDESC; break;
15785796c8dcSSimon Schubert 	      }
15795796c8dcSSimon Schubert 
15805796c8dcSSimon Schubert 	    if (h != NULL)
15815796c8dcSSimon Schubert 	      {
15825796c8dcSSimon Schubert 		if (r_type == R_X86_64_GOTPLT64)
15835796c8dcSSimon Schubert 		  {
15845796c8dcSSimon Schubert 		    /* This relocation indicates that we also need
15855796c8dcSSimon Schubert 		       a PLT entry, as this is a function.  We don't need
15865796c8dcSSimon Schubert 		       a PLT entry for local symbols.  */
15875796c8dcSSimon Schubert 		    h->needs_plt = 1;
15885796c8dcSSimon Schubert 		    h->plt.refcount += 1;
15895796c8dcSSimon Schubert 		  }
15905796c8dcSSimon Schubert 		h->got.refcount += 1;
1591c50c785cSJohn Marino 		old_tls_type = elf_x86_64_hash_entry (h)->tls_type;
15925796c8dcSSimon Schubert 	      }
15935796c8dcSSimon Schubert 	    else
15945796c8dcSSimon Schubert 	      {
15955796c8dcSSimon Schubert 		bfd_signed_vma *local_got_refcounts;
15965796c8dcSSimon Schubert 
15975796c8dcSSimon Schubert 		/* This is a global offset table entry for a local symbol.  */
15985796c8dcSSimon Schubert 		local_got_refcounts = elf_local_got_refcounts (abfd);
15995796c8dcSSimon Schubert 		if (local_got_refcounts == NULL)
16005796c8dcSSimon Schubert 		  {
16015796c8dcSSimon Schubert 		    bfd_size_type size;
16025796c8dcSSimon Schubert 
16035796c8dcSSimon Schubert 		    size = symtab_hdr->sh_info;
16045796c8dcSSimon Schubert 		    size *= sizeof (bfd_signed_vma)
16055796c8dcSSimon Schubert 		      + sizeof (bfd_vma) + sizeof (char);
16065796c8dcSSimon Schubert 		    local_got_refcounts = ((bfd_signed_vma *)
16075796c8dcSSimon Schubert 					   bfd_zalloc (abfd, size));
16085796c8dcSSimon Schubert 		    if (local_got_refcounts == NULL)
16095796c8dcSSimon Schubert 		      return FALSE;
16105796c8dcSSimon Schubert 		    elf_local_got_refcounts (abfd) = local_got_refcounts;
1611c50c785cSJohn Marino 		    elf_x86_64_local_tlsdesc_gotent (abfd)
16125796c8dcSSimon Schubert 		      = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
1613c50c785cSJohn Marino 		    elf_x86_64_local_got_tls_type (abfd)
16145796c8dcSSimon Schubert 		      = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
16155796c8dcSSimon Schubert 		  }
16165796c8dcSSimon Schubert 		local_got_refcounts[r_symndx] += 1;
16175796c8dcSSimon Schubert 		old_tls_type
1618c50c785cSJohn Marino 		  = elf_x86_64_local_got_tls_type (abfd) [r_symndx];
16195796c8dcSSimon Schubert 	      }
16205796c8dcSSimon Schubert 
16215796c8dcSSimon Schubert 	    /* If a TLS symbol is accessed using IE at least once,
16225796c8dcSSimon Schubert 	       there is no point to use dynamic model for it.  */
16235796c8dcSSimon Schubert 	    if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
16245796c8dcSSimon Schubert 		&& (! GOT_TLS_GD_ANY_P (old_tls_type)
16255796c8dcSSimon Schubert 		    || tls_type != GOT_TLS_IE))
16265796c8dcSSimon Schubert 	      {
16275796c8dcSSimon Schubert 		if (old_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (tls_type))
16285796c8dcSSimon Schubert 		  tls_type = old_tls_type;
16295796c8dcSSimon Schubert 		else if (GOT_TLS_GD_ANY_P (old_tls_type)
16305796c8dcSSimon Schubert 			 && GOT_TLS_GD_ANY_P (tls_type))
16315796c8dcSSimon Schubert 		  tls_type |= old_tls_type;
16325796c8dcSSimon Schubert 		else
16335796c8dcSSimon Schubert 		  {
16345796c8dcSSimon Schubert 		    if (h)
16355796c8dcSSimon Schubert 		      name = h->root.root.string;
16365796c8dcSSimon Schubert 		    else
16375796c8dcSSimon Schubert 		      name = bfd_elf_sym_name (abfd, symtab_hdr,
16385796c8dcSSimon Schubert 					       isym, NULL);
16395796c8dcSSimon Schubert 		    (*_bfd_error_handler)
16405796c8dcSSimon Schubert 		      (_("%B: '%s' accessed both as normal and thread local symbol"),
16415796c8dcSSimon Schubert 		       abfd, name);
1642*ef5ccd6cSJohn Marino 		    bfd_set_error (bfd_error_bad_value);
16435796c8dcSSimon Schubert 		    return FALSE;
16445796c8dcSSimon Schubert 		  }
16455796c8dcSSimon Schubert 	      }
16465796c8dcSSimon Schubert 
16475796c8dcSSimon Schubert 	    if (old_tls_type != tls_type)
16485796c8dcSSimon Schubert 	      {
16495796c8dcSSimon Schubert 		if (h != NULL)
1650c50c785cSJohn Marino 		  elf_x86_64_hash_entry (h)->tls_type = tls_type;
16515796c8dcSSimon Schubert 		else
1652c50c785cSJohn Marino 		  elf_x86_64_local_got_tls_type (abfd) [r_symndx] = tls_type;
16535796c8dcSSimon Schubert 	      }
16545796c8dcSSimon Schubert 	  }
16555796c8dcSSimon Schubert 	  /* Fall through */
16565796c8dcSSimon Schubert 
16575796c8dcSSimon Schubert 	case R_X86_64_GOTOFF64:
16585796c8dcSSimon Schubert 	case R_X86_64_GOTPC32:
16595796c8dcSSimon Schubert 	case R_X86_64_GOTPC64:
16605796c8dcSSimon Schubert 	create_got:
16615796c8dcSSimon Schubert 	  if (htab->elf.sgot == NULL)
16625796c8dcSSimon Schubert 	    {
16635796c8dcSSimon Schubert 	      if (htab->elf.dynobj == NULL)
16645796c8dcSSimon Schubert 		htab->elf.dynobj = abfd;
16655796c8dcSSimon Schubert 	      if (!_bfd_elf_create_got_section (htab->elf.dynobj,
16665796c8dcSSimon Schubert 						info))
16675796c8dcSSimon Schubert 		return FALSE;
16685796c8dcSSimon Schubert 	    }
16695796c8dcSSimon Schubert 	  break;
16705796c8dcSSimon Schubert 
16715796c8dcSSimon Schubert 	case R_X86_64_PLT32:
16725796c8dcSSimon Schubert 	  /* This symbol requires a procedure linkage table entry.  We
16735796c8dcSSimon Schubert 	     actually build the entry in adjust_dynamic_symbol,
16745796c8dcSSimon Schubert 	     because this might be a case of linking PIC code which is
16755796c8dcSSimon Schubert 	     never referenced by a dynamic object, in which case we
16765796c8dcSSimon Schubert 	     don't need to generate a procedure linkage table entry
16775796c8dcSSimon Schubert 	     after all.	 */
16785796c8dcSSimon Schubert 
16795796c8dcSSimon Schubert 	  /* If this is a local symbol, we resolve it directly without
16805796c8dcSSimon Schubert 	     creating a procedure linkage table entry.	*/
16815796c8dcSSimon Schubert 	  if (h == NULL)
16825796c8dcSSimon Schubert 	    continue;
16835796c8dcSSimon Schubert 
16845796c8dcSSimon Schubert 	  h->needs_plt = 1;
16855796c8dcSSimon Schubert 	  h->plt.refcount += 1;
16865796c8dcSSimon Schubert 	  break;
16875796c8dcSSimon Schubert 
16885796c8dcSSimon Schubert 	case R_X86_64_PLTOFF64:
16895796c8dcSSimon Schubert 	  /* This tries to form the 'address' of a function relative
16905796c8dcSSimon Schubert 	     to GOT.  For global symbols we need a PLT entry.  */
16915796c8dcSSimon Schubert 	  if (h != NULL)
16925796c8dcSSimon Schubert 	    {
16935796c8dcSSimon Schubert 	      h->needs_plt = 1;
16945796c8dcSSimon Schubert 	      h->plt.refcount += 1;
16955796c8dcSSimon Schubert 	    }
16965796c8dcSSimon Schubert 	  goto create_got;
16975796c8dcSSimon Schubert 
1698*ef5ccd6cSJohn Marino 	case R_X86_64_SIZE32:
1699*ef5ccd6cSJohn Marino 	case R_X86_64_SIZE64:
1700*ef5ccd6cSJohn Marino 	  size_reloc = TRUE;
1701*ef5ccd6cSJohn Marino 	  goto do_size;
1702*ef5ccd6cSJohn Marino 
1703c50c785cSJohn Marino 	case R_X86_64_32:
1704c50c785cSJohn Marino 	  if (!ABI_64_P (abfd))
1705c50c785cSJohn Marino 	    goto pointer;
17065796c8dcSSimon Schubert 	case R_X86_64_8:
17075796c8dcSSimon Schubert 	case R_X86_64_16:
17085796c8dcSSimon Schubert 	case R_X86_64_32S:
17095796c8dcSSimon Schubert 	  /* Let's help debug shared library creation.  These relocs
17105796c8dcSSimon Schubert 	     cannot be used in shared libs.  Don't error out for
17115796c8dcSSimon Schubert 	     sections we don't care about, such as debug sections or
17125796c8dcSSimon Schubert 	     non-constant sections.  */
17135796c8dcSSimon Schubert 	  if (info->shared
17145796c8dcSSimon Schubert 	      && (sec->flags & SEC_ALLOC) != 0
17155796c8dcSSimon Schubert 	      && (sec->flags & SEC_READONLY) != 0)
17165796c8dcSSimon Schubert 	    {
17175796c8dcSSimon Schubert 	      if (h)
17185796c8dcSSimon Schubert 		name = h->root.root.string;
17195796c8dcSSimon Schubert 	      else
17205796c8dcSSimon Schubert 		name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
17215796c8dcSSimon Schubert 	      (*_bfd_error_handler)
17225796c8dcSSimon Schubert 		(_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
17235796c8dcSSimon Schubert 		 abfd, x86_64_elf_howto_table[r_type].name, name);
17245796c8dcSSimon Schubert 	      bfd_set_error (bfd_error_bad_value);
17255796c8dcSSimon Schubert 	      return FALSE;
17265796c8dcSSimon Schubert 	    }
17275796c8dcSSimon Schubert 	  /* Fall through.  */
17285796c8dcSSimon Schubert 
17295796c8dcSSimon Schubert 	case R_X86_64_PC8:
17305796c8dcSSimon Schubert 	case R_X86_64_PC16:
17315796c8dcSSimon Schubert 	case R_X86_64_PC32:
17325796c8dcSSimon Schubert 	case R_X86_64_PC64:
17335796c8dcSSimon Schubert 	case R_X86_64_64:
1734c50c785cSJohn Marino pointer:
17355796c8dcSSimon Schubert 	  if (h != NULL && info->executable)
17365796c8dcSSimon Schubert 	    {
17375796c8dcSSimon Schubert 	      /* If this reloc is in a read-only section, we might
17385796c8dcSSimon Schubert 		 need a copy reloc.  We can't check reliably at this
17395796c8dcSSimon Schubert 		 stage whether the section is read-only, as input
17405796c8dcSSimon Schubert 		 sections have not yet been mapped to output sections.
17415796c8dcSSimon Schubert 		 Tentatively set the flag for now, and correct in
17425796c8dcSSimon Schubert 		 adjust_dynamic_symbol.  */
17435796c8dcSSimon Schubert 	      h->non_got_ref = 1;
17445796c8dcSSimon Schubert 
17455796c8dcSSimon Schubert 	      /* We may need a .plt entry if the function this reloc
17465796c8dcSSimon Schubert 		 refers to is in a shared lib.  */
17475796c8dcSSimon Schubert 	      h->plt.refcount += 1;
17485796c8dcSSimon Schubert 	      if (r_type != R_X86_64_PC32 && r_type != R_X86_64_PC64)
17495796c8dcSSimon Schubert 		h->pointer_equality_needed = 1;
17505796c8dcSSimon Schubert 	    }
17515796c8dcSSimon Schubert 
1752*ef5ccd6cSJohn Marino 	  size_reloc = FALSE;
1753*ef5ccd6cSJohn Marino do_size:
17545796c8dcSSimon Schubert 	  /* If we are creating a shared library, and this is a reloc
17555796c8dcSSimon Schubert 	     against a global symbol, or a non PC relative reloc
17565796c8dcSSimon Schubert 	     against a local symbol, then we need to copy the reloc
17575796c8dcSSimon Schubert 	     into the shared library.  However, if we are linking with
17585796c8dcSSimon Schubert 	     -Bsymbolic, we do not need to copy a reloc against a
17595796c8dcSSimon Schubert 	     global symbol which is defined in an object we are
17605796c8dcSSimon Schubert 	     including in the link (i.e., DEF_REGULAR is set).	At
17615796c8dcSSimon Schubert 	     this point we have not seen all the input files, so it is
17625796c8dcSSimon Schubert 	     possible that DEF_REGULAR is not set now but will be set
17635796c8dcSSimon Schubert 	     later (it is never cleared).  In case of a weak definition,
17645796c8dcSSimon Schubert 	     DEF_REGULAR may be cleared later by a strong definition in
17655796c8dcSSimon Schubert 	     a shared library.  We account for that possibility below by
17665796c8dcSSimon Schubert 	     storing information in the relocs_copied field of the hash
17675796c8dcSSimon Schubert 	     table entry.  A similar situation occurs when creating
17685796c8dcSSimon Schubert 	     shared libraries and symbol visibility changes render the
17695796c8dcSSimon Schubert 	     symbol local.
17705796c8dcSSimon Schubert 
17715796c8dcSSimon Schubert 	     If on the other hand, we are creating an executable, we
17725796c8dcSSimon Schubert 	     may need to keep relocations for symbols satisfied by a
17735796c8dcSSimon Schubert 	     dynamic library if we manage to avoid copy relocs for the
17745796c8dcSSimon Schubert 	     symbol.  */
17755796c8dcSSimon Schubert 	  if ((info->shared
17765796c8dcSSimon Schubert 	       && (sec->flags & SEC_ALLOC) != 0
17775796c8dcSSimon Schubert 	       && (! IS_X86_64_PCREL_TYPE (r_type)
17785796c8dcSSimon Schubert 		   || (h != NULL
17795796c8dcSSimon Schubert 		       && (! SYMBOLIC_BIND (info, h)
17805796c8dcSSimon Schubert 			   || h->root.type == bfd_link_hash_defweak
17815796c8dcSSimon Schubert 			   || !h->def_regular))))
17825796c8dcSSimon Schubert 	      || (ELIMINATE_COPY_RELOCS
17835796c8dcSSimon Schubert 		  && !info->shared
17845796c8dcSSimon Schubert 		  && (sec->flags & SEC_ALLOC) != 0
17855796c8dcSSimon Schubert 		  && h != NULL
17865796c8dcSSimon Schubert 		  && (h->root.type == bfd_link_hash_defweak
17875796c8dcSSimon Schubert 		      || !h->def_regular)))
17885796c8dcSSimon Schubert 	    {
17895796c8dcSSimon Schubert 	      struct elf_dyn_relocs *p;
17905796c8dcSSimon Schubert 	      struct elf_dyn_relocs **head;
17915796c8dcSSimon Schubert 
17925796c8dcSSimon Schubert 	      /* We must copy these reloc types into the output file.
17935796c8dcSSimon Schubert 		 Create a reloc section in dynobj and make room for
17945796c8dcSSimon Schubert 		 this reloc.  */
17955796c8dcSSimon Schubert 	      if (sreloc == NULL)
17965796c8dcSSimon Schubert 		{
17975796c8dcSSimon Schubert 		  if (htab->elf.dynobj == NULL)
17985796c8dcSSimon Schubert 		    htab->elf.dynobj = abfd;
17995796c8dcSSimon Schubert 
18005796c8dcSSimon Schubert 		  sreloc = _bfd_elf_make_dynamic_reloc_section
1801c50c785cSJohn Marino 		    (sec, htab->elf.dynobj, ABI_64_P (abfd) ? 3 : 2,
1802c50c785cSJohn Marino 		     abfd, /*rela?*/ TRUE);
18035796c8dcSSimon Schubert 
18045796c8dcSSimon Schubert 		  if (sreloc == NULL)
18055796c8dcSSimon Schubert 		    return FALSE;
18065796c8dcSSimon Schubert 		}
18075796c8dcSSimon Schubert 
18085796c8dcSSimon Schubert 	      /* If this is a global symbol, we count the number of
18095796c8dcSSimon Schubert 		 relocations we need for this symbol.  */
18105796c8dcSSimon Schubert 	      if (h != NULL)
18115796c8dcSSimon Schubert 		{
1812c50c785cSJohn Marino 		  head = &((struct elf_x86_64_link_hash_entry *) h)->dyn_relocs;
18135796c8dcSSimon Schubert 		}
18145796c8dcSSimon Schubert 	      else
18155796c8dcSSimon Schubert 		{
18165796c8dcSSimon Schubert 		  /* Track dynamic relocs needed for local syms too.
18175796c8dcSSimon Schubert 		     We really need local syms available to do this
18185796c8dcSSimon Schubert 		     easily.  Oh well.  */
18195796c8dcSSimon Schubert 		  asection *s;
18205796c8dcSSimon Schubert 		  void **vpp;
18215796c8dcSSimon Schubert 
18225796c8dcSSimon Schubert 		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
18235796c8dcSSimon Schubert 						abfd, r_symndx);
18245796c8dcSSimon Schubert 		  if (isym == NULL)
18255796c8dcSSimon Schubert 		    return FALSE;
18265796c8dcSSimon Schubert 
18275796c8dcSSimon Schubert 		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
18285796c8dcSSimon Schubert 		  if (s == NULL)
18295796c8dcSSimon Schubert 		    s = sec;
18305796c8dcSSimon Schubert 
18315796c8dcSSimon Schubert 		  /* Beware of type punned pointers vs strict aliasing
18325796c8dcSSimon Schubert 		     rules.  */
18335796c8dcSSimon Schubert 		  vpp = &(elf_section_data (s)->local_dynrel);
18345796c8dcSSimon Schubert 		  head = (struct elf_dyn_relocs **)vpp;
18355796c8dcSSimon Schubert 		}
18365796c8dcSSimon Schubert 
18375796c8dcSSimon Schubert 	      p = *head;
18385796c8dcSSimon Schubert 	      if (p == NULL || p->sec != sec)
18395796c8dcSSimon Schubert 		{
18405796c8dcSSimon Schubert 		  bfd_size_type amt = sizeof *p;
18415796c8dcSSimon Schubert 
18425796c8dcSSimon Schubert 		  p = ((struct elf_dyn_relocs *)
18435796c8dcSSimon Schubert 		       bfd_alloc (htab->elf.dynobj, amt));
18445796c8dcSSimon Schubert 		  if (p == NULL)
18455796c8dcSSimon Schubert 		    return FALSE;
18465796c8dcSSimon Schubert 		  p->next = *head;
18475796c8dcSSimon Schubert 		  *head = p;
18485796c8dcSSimon Schubert 		  p->sec = sec;
18495796c8dcSSimon Schubert 		  p->count = 0;
18505796c8dcSSimon Schubert 		  p->pc_count = 0;
18515796c8dcSSimon Schubert 		}
18525796c8dcSSimon Schubert 
18535796c8dcSSimon Schubert 	      p->count += 1;
1854*ef5ccd6cSJohn Marino 	      /* Count size relocation as PC-relative relocation.  */
1855*ef5ccd6cSJohn Marino 	      if (IS_X86_64_PCREL_TYPE (r_type) || size_reloc)
18565796c8dcSSimon Schubert 		p->pc_count += 1;
18575796c8dcSSimon Schubert 	    }
18585796c8dcSSimon Schubert 	  break;
18595796c8dcSSimon Schubert 
18605796c8dcSSimon Schubert 	  /* This relocation describes the C++ object vtable hierarchy.
18615796c8dcSSimon Schubert 	     Reconstruct it for later use during GC.  */
18625796c8dcSSimon Schubert 	case R_X86_64_GNU_VTINHERIT:
18635796c8dcSSimon Schubert 	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
18645796c8dcSSimon Schubert 	    return FALSE;
18655796c8dcSSimon Schubert 	  break;
18665796c8dcSSimon Schubert 
18675796c8dcSSimon Schubert 	  /* This relocation describes which C++ vtable entries are actually
18685796c8dcSSimon Schubert 	     used.  Record for later use during GC.  */
18695796c8dcSSimon Schubert 	case R_X86_64_GNU_VTENTRY:
18705796c8dcSSimon Schubert 	  BFD_ASSERT (h != NULL);
18715796c8dcSSimon Schubert 	  if (h != NULL
18725796c8dcSSimon Schubert 	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
18735796c8dcSSimon Schubert 	    return FALSE;
18745796c8dcSSimon Schubert 	  break;
18755796c8dcSSimon Schubert 
18765796c8dcSSimon Schubert 	default:
18775796c8dcSSimon Schubert 	  break;
18785796c8dcSSimon Schubert 	}
18795796c8dcSSimon Schubert     }
18805796c8dcSSimon Schubert 
18815796c8dcSSimon Schubert   return TRUE;
18825796c8dcSSimon Schubert }
18835796c8dcSSimon Schubert 
18845796c8dcSSimon Schubert /* Return the section that should be marked against GC for a given
18855796c8dcSSimon Schubert    relocation.	*/
18865796c8dcSSimon Schubert 
18875796c8dcSSimon Schubert static asection *
elf_x86_64_gc_mark_hook(asection * sec,struct bfd_link_info * info,Elf_Internal_Rela * rel,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)1888c50c785cSJohn Marino elf_x86_64_gc_mark_hook (asection *sec,
18895796c8dcSSimon Schubert 			 struct bfd_link_info *info,
18905796c8dcSSimon Schubert 			 Elf_Internal_Rela *rel,
18915796c8dcSSimon Schubert 			 struct elf_link_hash_entry *h,
18925796c8dcSSimon Schubert 			 Elf_Internal_Sym *sym)
18935796c8dcSSimon Schubert {
18945796c8dcSSimon Schubert   if (h != NULL)
1895c50c785cSJohn Marino     switch (ELF32_R_TYPE (rel->r_info))
18965796c8dcSSimon Schubert       {
18975796c8dcSSimon Schubert       case R_X86_64_GNU_VTINHERIT:
18985796c8dcSSimon Schubert       case R_X86_64_GNU_VTENTRY:
18995796c8dcSSimon Schubert 	return NULL;
19005796c8dcSSimon Schubert       }
19015796c8dcSSimon Schubert 
19025796c8dcSSimon Schubert   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
19035796c8dcSSimon Schubert }
19045796c8dcSSimon Schubert 
19055796c8dcSSimon Schubert /* Update the got entry reference counts for the section being removed.	 */
19065796c8dcSSimon Schubert 
19075796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_gc_sweep_hook(bfd * abfd,struct bfd_link_info * info,asection * sec,const Elf_Internal_Rela * relocs)1908c50c785cSJohn Marino elf_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
19095796c8dcSSimon Schubert 			  asection *sec,
19105796c8dcSSimon Schubert 			  const Elf_Internal_Rela *relocs)
19115796c8dcSSimon Schubert {
1912c50c785cSJohn Marino   struct elf_x86_64_link_hash_table *htab;
19135796c8dcSSimon Schubert   Elf_Internal_Shdr *symtab_hdr;
19145796c8dcSSimon Schubert   struct elf_link_hash_entry **sym_hashes;
19155796c8dcSSimon Schubert   bfd_signed_vma *local_got_refcounts;
19165796c8dcSSimon Schubert   const Elf_Internal_Rela *rel, *relend;
19175796c8dcSSimon Schubert 
19185796c8dcSSimon Schubert   if (info->relocatable)
19195796c8dcSSimon Schubert     return TRUE;
19205796c8dcSSimon Schubert 
1921c50c785cSJohn Marino   htab = elf_x86_64_hash_table (info);
1922cf7f2e2dSJohn Marino   if (htab == NULL)
1923cf7f2e2dSJohn Marino     return FALSE;
1924cf7f2e2dSJohn Marino 
19255796c8dcSSimon Schubert   elf_section_data (sec)->local_dynrel = NULL;
19265796c8dcSSimon Schubert 
19275796c8dcSSimon Schubert   symtab_hdr = &elf_symtab_hdr (abfd);
19285796c8dcSSimon Schubert   sym_hashes = elf_sym_hashes (abfd);
19295796c8dcSSimon Schubert   local_got_refcounts = elf_local_got_refcounts (abfd);
19305796c8dcSSimon Schubert 
1931c50c785cSJohn Marino   htab = elf_x86_64_hash_table (info);
19325796c8dcSSimon Schubert   relend = relocs + sec->reloc_count;
19335796c8dcSSimon Schubert   for (rel = relocs; rel < relend; rel++)
19345796c8dcSSimon Schubert     {
19355796c8dcSSimon Schubert       unsigned long r_symndx;
19365796c8dcSSimon Schubert       unsigned int r_type;
19375796c8dcSSimon Schubert       struct elf_link_hash_entry *h = NULL;
19385796c8dcSSimon Schubert 
1939c50c785cSJohn Marino       r_symndx = htab->r_sym (rel->r_info);
19405796c8dcSSimon Schubert       if (r_symndx >= symtab_hdr->sh_info)
19415796c8dcSSimon Schubert 	{
19425796c8dcSSimon Schubert 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
19435796c8dcSSimon Schubert 	  while (h->root.type == bfd_link_hash_indirect
19445796c8dcSSimon Schubert 		 || h->root.type == bfd_link_hash_warning)
19455796c8dcSSimon Schubert 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1946c50c785cSJohn Marino 	}
1947c50c785cSJohn Marino       else
1948c50c785cSJohn Marino 	{
1949c50c785cSJohn Marino 	  /* A local symbol.  */
1950c50c785cSJohn Marino 	  Elf_Internal_Sym *isym;
1951c50c785cSJohn Marino 
1952c50c785cSJohn Marino 	  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1953c50c785cSJohn Marino 					abfd, r_symndx);
1954c50c785cSJohn Marino 
1955c50c785cSJohn Marino 	  /* Check relocation against local STT_GNU_IFUNC symbol.  */
1956c50c785cSJohn Marino 	  if (isym != NULL
1957c50c785cSJohn Marino 	      && ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
1958c50c785cSJohn Marino 	    {
1959c50c785cSJohn Marino 	      h = elf_x86_64_get_local_sym_hash (htab, abfd, rel, FALSE);
1960c50c785cSJohn Marino 	      if (h == NULL)
1961c50c785cSJohn Marino 		abort ();
1962c50c785cSJohn Marino 	    }
1963c50c785cSJohn Marino 	}
1964c50c785cSJohn Marino 
1965c50c785cSJohn Marino       if (h)
1966c50c785cSJohn Marino 	{
1967c50c785cSJohn Marino 	  struct elf_x86_64_link_hash_entry *eh;
1968c50c785cSJohn Marino 	  struct elf_dyn_relocs **pp;
1969c50c785cSJohn Marino 	  struct elf_dyn_relocs *p;
1970c50c785cSJohn Marino 
1971c50c785cSJohn Marino 	  eh = (struct elf_x86_64_link_hash_entry *) h;
19725796c8dcSSimon Schubert 
19735796c8dcSSimon Schubert 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
19745796c8dcSSimon Schubert 	    if (p->sec == sec)
19755796c8dcSSimon Schubert 	      {
19765796c8dcSSimon Schubert 		/* Everything must go for SEC.  */
19775796c8dcSSimon Schubert 		*pp = p->next;
19785796c8dcSSimon Schubert 		break;
19795796c8dcSSimon Schubert 	      }
19805796c8dcSSimon Schubert 	}
19815796c8dcSSimon Schubert 
1982c50c785cSJohn Marino       r_type = ELF32_R_TYPE (rel->r_info);
1983c50c785cSJohn Marino       if (! elf_x86_64_tls_transition (info, abfd, sec, NULL,
19845796c8dcSSimon Schubert 				       symtab_hdr, sym_hashes,
19855796c8dcSSimon Schubert 				       &r_type, GOT_UNKNOWN,
19865796c8dcSSimon Schubert 				       rel, relend, h, r_symndx))
19875796c8dcSSimon Schubert 	return FALSE;
19885796c8dcSSimon Schubert 
19895796c8dcSSimon Schubert       switch (r_type)
19905796c8dcSSimon Schubert 	{
19915796c8dcSSimon Schubert 	case R_X86_64_TLSLD:
1992cf7f2e2dSJohn Marino 	  if (htab->tls_ld_got.refcount > 0)
1993cf7f2e2dSJohn Marino 	    htab->tls_ld_got.refcount -= 1;
19945796c8dcSSimon Schubert 	  break;
19955796c8dcSSimon Schubert 
19965796c8dcSSimon Schubert 	case R_X86_64_TLSGD:
19975796c8dcSSimon Schubert 	case R_X86_64_GOTPC32_TLSDESC:
19985796c8dcSSimon Schubert 	case R_X86_64_TLSDESC_CALL:
19995796c8dcSSimon Schubert 	case R_X86_64_GOTTPOFF:
20005796c8dcSSimon Schubert 	case R_X86_64_GOT32:
20015796c8dcSSimon Schubert 	case R_X86_64_GOTPCREL:
20025796c8dcSSimon Schubert 	case R_X86_64_GOT64:
20035796c8dcSSimon Schubert 	case R_X86_64_GOTPCREL64:
20045796c8dcSSimon Schubert 	case R_X86_64_GOTPLT64:
20055796c8dcSSimon Schubert 	  if (h != NULL)
20065796c8dcSSimon Schubert 	    {
20075796c8dcSSimon Schubert 	      if (r_type == R_X86_64_GOTPLT64 && h->plt.refcount > 0)
20085796c8dcSSimon Schubert 		h->plt.refcount -= 1;
20095796c8dcSSimon Schubert 	      if (h->got.refcount > 0)
20105796c8dcSSimon Schubert 		h->got.refcount -= 1;
2011c50c785cSJohn Marino 	      if (h->type == STT_GNU_IFUNC)
2012c50c785cSJohn Marino 		{
2013c50c785cSJohn Marino 		  if (h->plt.refcount > 0)
2014c50c785cSJohn Marino 		    h->plt.refcount -= 1;
2015c50c785cSJohn Marino 		}
20165796c8dcSSimon Schubert 	    }
20175796c8dcSSimon Schubert 	  else if (local_got_refcounts != NULL)
20185796c8dcSSimon Schubert 	    {
20195796c8dcSSimon Schubert 	      if (local_got_refcounts[r_symndx] > 0)
20205796c8dcSSimon Schubert 		local_got_refcounts[r_symndx] -= 1;
20215796c8dcSSimon Schubert 	    }
20225796c8dcSSimon Schubert 	  break;
20235796c8dcSSimon Schubert 
20245796c8dcSSimon Schubert 	case R_X86_64_8:
20255796c8dcSSimon Schubert 	case R_X86_64_16:
20265796c8dcSSimon Schubert 	case R_X86_64_32:
20275796c8dcSSimon Schubert 	case R_X86_64_64:
20285796c8dcSSimon Schubert 	case R_X86_64_32S:
20295796c8dcSSimon Schubert 	case R_X86_64_PC8:
20305796c8dcSSimon Schubert 	case R_X86_64_PC16:
20315796c8dcSSimon Schubert 	case R_X86_64_PC32:
20325796c8dcSSimon Schubert 	case R_X86_64_PC64:
2033*ef5ccd6cSJohn Marino 	case R_X86_64_SIZE32:
2034*ef5ccd6cSJohn Marino 	case R_X86_64_SIZE64:
2035c50c785cSJohn Marino 	  if (info->shared
2036c50c785cSJohn Marino 	      && (h == NULL || h->type != STT_GNU_IFUNC))
20375796c8dcSSimon Schubert 	    break;
20385796c8dcSSimon Schubert 	  /* Fall thru */
20395796c8dcSSimon Schubert 
20405796c8dcSSimon Schubert 	case R_X86_64_PLT32:
20415796c8dcSSimon Schubert 	case R_X86_64_PLTOFF64:
20425796c8dcSSimon Schubert 	  if (h != NULL)
20435796c8dcSSimon Schubert 	    {
20445796c8dcSSimon Schubert 	      if (h->plt.refcount > 0)
20455796c8dcSSimon Schubert 		h->plt.refcount -= 1;
20465796c8dcSSimon Schubert 	    }
20475796c8dcSSimon Schubert 	  break;
20485796c8dcSSimon Schubert 
20495796c8dcSSimon Schubert 	default:
20505796c8dcSSimon Schubert 	  break;
20515796c8dcSSimon Schubert 	}
20525796c8dcSSimon Schubert     }
20535796c8dcSSimon Schubert 
20545796c8dcSSimon Schubert   return TRUE;
20555796c8dcSSimon Schubert }
20565796c8dcSSimon Schubert 
20575796c8dcSSimon Schubert /* Adjust a symbol defined by a dynamic object and referenced by a
20585796c8dcSSimon Schubert    regular object.  The current definition is in some section of the
20595796c8dcSSimon Schubert    dynamic object, but we're not including those sections.  We have to
20605796c8dcSSimon Schubert    change the definition to something the rest of the link can
20615796c8dcSSimon Schubert    understand.	*/
20625796c8dcSSimon Schubert 
20635796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_adjust_dynamic_symbol(struct bfd_link_info * info,struct elf_link_hash_entry * h)2064c50c785cSJohn Marino elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
20655796c8dcSSimon Schubert 				  struct elf_link_hash_entry *h)
20665796c8dcSSimon Schubert {
2067c50c785cSJohn Marino   struct elf_x86_64_link_hash_table *htab;
20685796c8dcSSimon Schubert   asection *s;
2069*ef5ccd6cSJohn Marino   struct elf_x86_64_link_hash_entry *eh;
2070*ef5ccd6cSJohn Marino   struct elf_dyn_relocs *p;
20715796c8dcSSimon Schubert 
20725796c8dcSSimon Schubert   /* STT_GNU_IFUNC symbol must go through PLT. */
20735796c8dcSSimon Schubert   if (h->type == STT_GNU_IFUNC)
20745796c8dcSSimon Schubert     {
2075*ef5ccd6cSJohn Marino       /* All local STT_GNU_IFUNC references must be treate as local
2076*ef5ccd6cSJohn Marino 	 calls via local PLT.  */
2077*ef5ccd6cSJohn Marino       if (h->ref_regular
2078*ef5ccd6cSJohn Marino 	  && SYMBOL_CALLS_LOCAL (info, h))
2079*ef5ccd6cSJohn Marino 	{
2080*ef5ccd6cSJohn Marino 	  bfd_size_type pc_count = 0, count = 0;
2081*ef5ccd6cSJohn Marino 	  struct elf_dyn_relocs **pp;
2082*ef5ccd6cSJohn Marino 
2083*ef5ccd6cSJohn Marino 	  eh = (struct elf_x86_64_link_hash_entry *) h;
2084*ef5ccd6cSJohn Marino 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
2085*ef5ccd6cSJohn Marino 	    {
2086*ef5ccd6cSJohn Marino 	      pc_count += p->pc_count;
2087*ef5ccd6cSJohn Marino 	      p->count -= p->pc_count;
2088*ef5ccd6cSJohn Marino 	      p->pc_count = 0;
2089*ef5ccd6cSJohn Marino 	      count += p->count;
2090*ef5ccd6cSJohn Marino 	      if (p->count == 0)
2091*ef5ccd6cSJohn Marino 		*pp = p->next;
2092*ef5ccd6cSJohn Marino 	      else
2093*ef5ccd6cSJohn Marino 		pp = &p->next;
2094*ef5ccd6cSJohn Marino 	    }
2095*ef5ccd6cSJohn Marino 
2096*ef5ccd6cSJohn Marino 	  if (pc_count || count)
2097*ef5ccd6cSJohn Marino 	    {
2098*ef5ccd6cSJohn Marino 	      h->needs_plt = 1;
2099*ef5ccd6cSJohn Marino 	      h->non_got_ref = 1;
2100*ef5ccd6cSJohn Marino 	      if (h->plt.refcount <= 0)
2101*ef5ccd6cSJohn Marino 		h->plt.refcount = 1;
2102*ef5ccd6cSJohn Marino 	      else
2103*ef5ccd6cSJohn Marino 		h->plt.refcount += 1;
2104*ef5ccd6cSJohn Marino 	    }
2105*ef5ccd6cSJohn Marino 	}
2106*ef5ccd6cSJohn Marino 
21075796c8dcSSimon Schubert       if (h->plt.refcount <= 0)
21085796c8dcSSimon Schubert 	{
21095796c8dcSSimon Schubert 	  h->plt.offset = (bfd_vma) -1;
21105796c8dcSSimon Schubert 	  h->needs_plt = 0;
21115796c8dcSSimon Schubert 	}
21125796c8dcSSimon Schubert       return TRUE;
21135796c8dcSSimon Schubert     }
21145796c8dcSSimon Schubert 
21155796c8dcSSimon Schubert   /* If this is a function, put it in the procedure linkage table.  We
21165796c8dcSSimon Schubert      will fill in the contents of the procedure linkage table later,
21175796c8dcSSimon Schubert      when we know the address of the .got section.  */
21185796c8dcSSimon Schubert   if (h->type == STT_FUNC
21195796c8dcSSimon Schubert       || h->needs_plt)
21205796c8dcSSimon Schubert     {
21215796c8dcSSimon Schubert       if (h->plt.refcount <= 0
21225796c8dcSSimon Schubert 	  || SYMBOL_CALLS_LOCAL (info, h)
21235796c8dcSSimon Schubert 	  || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
21245796c8dcSSimon Schubert 	      && h->root.type == bfd_link_hash_undefweak))
21255796c8dcSSimon Schubert 	{
21265796c8dcSSimon Schubert 	  /* This case can occur if we saw a PLT32 reloc in an input
21275796c8dcSSimon Schubert 	     file, but the symbol was never referred to by a dynamic
21285796c8dcSSimon Schubert 	     object, or if all references were garbage collected.  In
21295796c8dcSSimon Schubert 	     such a case, we don't actually need to build a procedure
21305796c8dcSSimon Schubert 	     linkage table, and we can just do a PC32 reloc instead.  */
21315796c8dcSSimon Schubert 	  h->plt.offset = (bfd_vma) -1;
21325796c8dcSSimon Schubert 	  h->needs_plt = 0;
21335796c8dcSSimon Schubert 	}
21345796c8dcSSimon Schubert 
21355796c8dcSSimon Schubert       return TRUE;
21365796c8dcSSimon Schubert     }
21375796c8dcSSimon Schubert   else
21385796c8dcSSimon Schubert     /* It's possible that we incorrectly decided a .plt reloc was
21395796c8dcSSimon Schubert        needed for an R_X86_64_PC32 reloc to a non-function sym in
21405796c8dcSSimon Schubert        check_relocs.  We can't decide accurately between function and
21415796c8dcSSimon Schubert        non-function syms in check-relocs;  Objects loaded later in
21425796c8dcSSimon Schubert        the link may change h->type.  So fix it now.  */
21435796c8dcSSimon Schubert     h->plt.offset = (bfd_vma) -1;
21445796c8dcSSimon Schubert 
21455796c8dcSSimon Schubert   /* If this is a weak symbol, and there is a real definition, the
21465796c8dcSSimon Schubert      processor independent code will have arranged for us to see the
21475796c8dcSSimon Schubert      real definition first, and we can just use the same value.	 */
21485796c8dcSSimon Schubert   if (h->u.weakdef != NULL)
21495796c8dcSSimon Schubert     {
21505796c8dcSSimon Schubert       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
21515796c8dcSSimon Schubert 		  || h->u.weakdef->root.type == bfd_link_hash_defweak);
21525796c8dcSSimon Schubert       h->root.u.def.section = h->u.weakdef->root.u.def.section;
21535796c8dcSSimon Schubert       h->root.u.def.value = h->u.weakdef->root.u.def.value;
21545796c8dcSSimon Schubert       if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
21555796c8dcSSimon Schubert 	h->non_got_ref = h->u.weakdef->non_got_ref;
21565796c8dcSSimon Schubert       return TRUE;
21575796c8dcSSimon Schubert     }
21585796c8dcSSimon Schubert 
21595796c8dcSSimon Schubert   /* This is a reference to a symbol defined by a dynamic object which
21605796c8dcSSimon Schubert      is not a function.	 */
21615796c8dcSSimon Schubert 
21625796c8dcSSimon Schubert   /* If we are creating a shared library, we must presume that the
21635796c8dcSSimon Schubert      only references to the symbol are via the global offset table.
21645796c8dcSSimon Schubert      For such cases we need not do anything here; the relocations will
21655796c8dcSSimon Schubert      be handled correctly by relocate_section.	*/
21665796c8dcSSimon Schubert   if (info->shared)
21675796c8dcSSimon Schubert     return TRUE;
21685796c8dcSSimon Schubert 
21695796c8dcSSimon Schubert   /* If there are no references to this symbol that do not use the
21705796c8dcSSimon Schubert      GOT, we don't need to generate a copy reloc.  */
21715796c8dcSSimon Schubert   if (!h->non_got_ref)
21725796c8dcSSimon Schubert     return TRUE;
21735796c8dcSSimon Schubert 
21745796c8dcSSimon Schubert   /* If -z nocopyreloc was given, we won't generate them either.  */
21755796c8dcSSimon Schubert   if (info->nocopyreloc)
21765796c8dcSSimon Schubert     {
21775796c8dcSSimon Schubert       h->non_got_ref = 0;
21785796c8dcSSimon Schubert       return TRUE;
21795796c8dcSSimon Schubert     }
21805796c8dcSSimon Schubert 
21815796c8dcSSimon Schubert   if (ELIMINATE_COPY_RELOCS)
21825796c8dcSSimon Schubert     {
2183c50c785cSJohn Marino       eh = (struct elf_x86_64_link_hash_entry *) h;
21845796c8dcSSimon Schubert       for (p = eh->dyn_relocs; p != NULL; p = p->next)
21855796c8dcSSimon Schubert 	{
21865796c8dcSSimon Schubert 	  s = p->sec->output_section;
21875796c8dcSSimon Schubert 	  if (s != NULL && (s->flags & SEC_READONLY) != 0)
21885796c8dcSSimon Schubert 	    break;
21895796c8dcSSimon Schubert 	}
21905796c8dcSSimon Schubert 
21915796c8dcSSimon Schubert       /* If we didn't find any dynamic relocs in read-only sections, then
21925796c8dcSSimon Schubert 	 we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
21935796c8dcSSimon Schubert       if (p == NULL)
21945796c8dcSSimon Schubert 	{
21955796c8dcSSimon Schubert 	  h->non_got_ref = 0;
21965796c8dcSSimon Schubert 	  return TRUE;
21975796c8dcSSimon Schubert 	}
21985796c8dcSSimon Schubert     }
21995796c8dcSSimon Schubert 
22005796c8dcSSimon Schubert   /* We must allocate the symbol in our .dynbss section, which will
22015796c8dcSSimon Schubert      become part of the .bss section of the executable.	 There will be
22025796c8dcSSimon Schubert      an entry for this symbol in the .dynsym section.  The dynamic
22035796c8dcSSimon Schubert      object will contain position independent code, so all references
22045796c8dcSSimon Schubert      from the dynamic object to this symbol will go through the global
22055796c8dcSSimon Schubert      offset table.  The dynamic linker will use the .dynsym entry to
22065796c8dcSSimon Schubert      determine the address it must put in the global offset table, so
22075796c8dcSSimon Schubert      both the dynamic object and the regular object will refer to the
22085796c8dcSSimon Schubert      same memory location for the variable.  */
22095796c8dcSSimon Schubert 
2210c50c785cSJohn Marino   htab = elf_x86_64_hash_table (info);
2211cf7f2e2dSJohn Marino   if (htab == NULL)
2212cf7f2e2dSJohn Marino     return FALSE;
22135796c8dcSSimon Schubert 
22145796c8dcSSimon Schubert   /* We must generate a R_X86_64_COPY reloc to tell the dynamic linker
22155796c8dcSSimon Schubert      to copy the initial value out of the dynamic object and into the
22165796c8dcSSimon Schubert      runtime process image.  */
2217*ef5ccd6cSJohn Marino   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
22185796c8dcSSimon Schubert     {
2219c50c785cSJohn Marino       const struct elf_backend_data *bed;
2220c50c785cSJohn Marino       bed = get_elf_backend_data (info->output_bfd);
2221c50c785cSJohn Marino       htab->srelbss->size += bed->s->sizeof_rela;
22225796c8dcSSimon Schubert       h->needs_copy = 1;
22235796c8dcSSimon Schubert     }
22245796c8dcSSimon Schubert 
22255796c8dcSSimon Schubert   s = htab->sdynbss;
22265796c8dcSSimon Schubert 
22275796c8dcSSimon Schubert   return _bfd_elf_adjust_dynamic_copy (h, s);
22285796c8dcSSimon Schubert }
22295796c8dcSSimon Schubert 
22305796c8dcSSimon Schubert /* Allocate space in .plt, .got and associated reloc sections for
22315796c8dcSSimon Schubert    dynamic relocs.  */
22325796c8dcSSimon Schubert 
22335796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_allocate_dynrelocs(struct elf_link_hash_entry * h,void * inf)2234c50c785cSJohn Marino elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
22355796c8dcSSimon Schubert {
22365796c8dcSSimon Schubert   struct bfd_link_info *info;
2237c50c785cSJohn Marino   struct elf_x86_64_link_hash_table *htab;
2238c50c785cSJohn Marino   struct elf_x86_64_link_hash_entry *eh;
22395796c8dcSSimon Schubert   struct elf_dyn_relocs *p;
2240c50c785cSJohn Marino   const struct elf_backend_data *bed;
2241*ef5ccd6cSJohn Marino   unsigned int plt_entry_size;
22425796c8dcSSimon Schubert 
22435796c8dcSSimon Schubert   if (h->root.type == bfd_link_hash_indirect)
22445796c8dcSSimon Schubert     return TRUE;
22455796c8dcSSimon Schubert 
2246c50c785cSJohn Marino   eh = (struct elf_x86_64_link_hash_entry *) h;
22475796c8dcSSimon Schubert 
22485796c8dcSSimon Schubert   info = (struct bfd_link_info *) inf;
2249c50c785cSJohn Marino   htab = elf_x86_64_hash_table (info);
2250cf7f2e2dSJohn Marino   if (htab == NULL)
2251cf7f2e2dSJohn Marino     return FALSE;
2252c50c785cSJohn Marino   bed = get_elf_backend_data (info->output_bfd);
2253*ef5ccd6cSJohn Marino   plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
22545796c8dcSSimon Schubert 
22555796c8dcSSimon Schubert   /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
22565796c8dcSSimon Schubert      here if it is defined and referenced in a non-shared object.  */
22575796c8dcSSimon Schubert   if (h->type == STT_GNU_IFUNC
22585796c8dcSSimon Schubert       && h->def_regular)
22595796c8dcSSimon Schubert     return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
22605796c8dcSSimon Schubert 					       &eh->dyn_relocs,
2261*ef5ccd6cSJohn Marino 					       plt_entry_size,
22625796c8dcSSimon Schubert 					       GOT_ENTRY_SIZE);
22635796c8dcSSimon Schubert   else if (htab->elf.dynamic_sections_created
22645796c8dcSSimon Schubert 	   && h->plt.refcount > 0)
22655796c8dcSSimon Schubert     {
22665796c8dcSSimon Schubert       /* Make sure this symbol is output as a dynamic symbol.
22675796c8dcSSimon Schubert 	 Undefined weak syms won't yet be marked as dynamic.  */
22685796c8dcSSimon Schubert       if (h->dynindx == -1
22695796c8dcSSimon Schubert 	  && !h->forced_local)
22705796c8dcSSimon Schubert 	{
22715796c8dcSSimon Schubert 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
22725796c8dcSSimon Schubert 	    return FALSE;
22735796c8dcSSimon Schubert 	}
22745796c8dcSSimon Schubert 
22755796c8dcSSimon Schubert       if (info->shared
22765796c8dcSSimon Schubert 	  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
22775796c8dcSSimon Schubert 	{
22785796c8dcSSimon Schubert 	  asection *s = htab->elf.splt;
22795796c8dcSSimon Schubert 
22805796c8dcSSimon Schubert 	  /* If this is the first .plt entry, make room for the special
22815796c8dcSSimon Schubert 	     first entry.  */
22825796c8dcSSimon Schubert 	  if (s->size == 0)
2283*ef5ccd6cSJohn Marino 	    s->size += plt_entry_size;
22845796c8dcSSimon Schubert 
22855796c8dcSSimon Schubert 	  h->plt.offset = s->size;
22865796c8dcSSimon Schubert 
22875796c8dcSSimon Schubert 	  /* If this symbol is not defined in a regular file, and we are
22885796c8dcSSimon Schubert 	     not generating a shared library, then set the symbol to this
22895796c8dcSSimon Schubert 	     location in the .plt.  This is required to make function
22905796c8dcSSimon Schubert 	     pointers compare as equal between the normal executable and
22915796c8dcSSimon Schubert 	     the shared library.  */
22925796c8dcSSimon Schubert 	  if (! info->shared
22935796c8dcSSimon Schubert 	      && !h->def_regular)
22945796c8dcSSimon Schubert 	    {
22955796c8dcSSimon Schubert 	      h->root.u.def.section = s;
22965796c8dcSSimon Schubert 	      h->root.u.def.value = h->plt.offset;
22975796c8dcSSimon Schubert 	    }
22985796c8dcSSimon Schubert 
22995796c8dcSSimon Schubert 	  /* Make room for this entry.  */
2300*ef5ccd6cSJohn Marino 	  s->size += plt_entry_size;
23015796c8dcSSimon Schubert 
23025796c8dcSSimon Schubert 	  /* We also need to make an entry in the .got.plt section, which
23035796c8dcSSimon Schubert 	     will be placed in the .got section by the linker script.  */
23045796c8dcSSimon Schubert 	  htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
23055796c8dcSSimon Schubert 
23065796c8dcSSimon Schubert 	  /* We also need to make an entry in the .rela.plt section.  */
2307c50c785cSJohn Marino 	  htab->elf.srelplt->size += bed->s->sizeof_rela;
23085796c8dcSSimon Schubert 	  htab->elf.srelplt->reloc_count++;
23095796c8dcSSimon Schubert 	}
23105796c8dcSSimon Schubert       else
23115796c8dcSSimon Schubert 	{
23125796c8dcSSimon Schubert 	  h->plt.offset = (bfd_vma) -1;
23135796c8dcSSimon Schubert 	  h->needs_plt = 0;
23145796c8dcSSimon Schubert 	}
23155796c8dcSSimon Schubert     }
23165796c8dcSSimon Schubert   else
23175796c8dcSSimon Schubert     {
23185796c8dcSSimon Schubert       h->plt.offset = (bfd_vma) -1;
23195796c8dcSSimon Schubert       h->needs_plt = 0;
23205796c8dcSSimon Schubert     }
23215796c8dcSSimon Schubert 
23225796c8dcSSimon Schubert   eh->tlsdesc_got = (bfd_vma) -1;
23235796c8dcSSimon Schubert 
23245796c8dcSSimon Schubert   /* If R_X86_64_GOTTPOFF symbol is now local to the binary,
23255796c8dcSSimon Schubert      make it a R_X86_64_TPOFF32 requiring no GOT entry.  */
23265796c8dcSSimon Schubert   if (h->got.refcount > 0
23275796c8dcSSimon Schubert       && info->executable
23285796c8dcSSimon Schubert       && h->dynindx == -1
2329c50c785cSJohn Marino       && elf_x86_64_hash_entry (h)->tls_type == GOT_TLS_IE)
23305796c8dcSSimon Schubert     {
23315796c8dcSSimon Schubert       h->got.offset = (bfd_vma) -1;
23325796c8dcSSimon Schubert     }
23335796c8dcSSimon Schubert   else if (h->got.refcount > 0)
23345796c8dcSSimon Schubert     {
23355796c8dcSSimon Schubert       asection *s;
23365796c8dcSSimon Schubert       bfd_boolean dyn;
2337c50c785cSJohn Marino       int tls_type = elf_x86_64_hash_entry (h)->tls_type;
23385796c8dcSSimon Schubert 
23395796c8dcSSimon Schubert       /* Make sure this symbol is output as a dynamic symbol.
23405796c8dcSSimon Schubert 	 Undefined weak syms won't yet be marked as dynamic.  */
23415796c8dcSSimon Schubert       if (h->dynindx == -1
23425796c8dcSSimon Schubert 	  && !h->forced_local)
23435796c8dcSSimon Schubert 	{
23445796c8dcSSimon Schubert 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
23455796c8dcSSimon Schubert 	    return FALSE;
23465796c8dcSSimon Schubert 	}
23475796c8dcSSimon Schubert 
23485796c8dcSSimon Schubert       if (GOT_TLS_GDESC_P (tls_type))
23495796c8dcSSimon Schubert 	{
23505796c8dcSSimon Schubert 	  eh->tlsdesc_got = htab->elf.sgotplt->size
2351c50c785cSJohn Marino 	    - elf_x86_64_compute_jump_table_size (htab);
23525796c8dcSSimon Schubert 	  htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
23535796c8dcSSimon Schubert 	  h->got.offset = (bfd_vma) -2;
23545796c8dcSSimon Schubert 	}
23555796c8dcSSimon Schubert       if (! GOT_TLS_GDESC_P (tls_type)
23565796c8dcSSimon Schubert 	  || GOT_TLS_GD_P (tls_type))
23575796c8dcSSimon Schubert 	{
23585796c8dcSSimon Schubert 	  s = htab->elf.sgot;
23595796c8dcSSimon Schubert 	  h->got.offset = s->size;
23605796c8dcSSimon Schubert 	  s->size += GOT_ENTRY_SIZE;
23615796c8dcSSimon Schubert 	  if (GOT_TLS_GD_P (tls_type))
23625796c8dcSSimon Schubert 	    s->size += GOT_ENTRY_SIZE;
23635796c8dcSSimon Schubert 	}
23645796c8dcSSimon Schubert       dyn = htab->elf.dynamic_sections_created;
23655796c8dcSSimon Schubert       /* R_X86_64_TLSGD needs one dynamic relocation if local symbol
23665796c8dcSSimon Schubert 	 and two if global.
23675796c8dcSSimon Schubert 	 R_X86_64_GOTTPOFF needs one dynamic relocation.  */
23685796c8dcSSimon Schubert       if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
23695796c8dcSSimon Schubert 	  || tls_type == GOT_TLS_IE)
2370c50c785cSJohn Marino 	htab->elf.srelgot->size += bed->s->sizeof_rela;
23715796c8dcSSimon Schubert       else if (GOT_TLS_GD_P (tls_type))
2372c50c785cSJohn Marino 	htab->elf.srelgot->size += 2 * bed->s->sizeof_rela;
23735796c8dcSSimon Schubert       else if (! GOT_TLS_GDESC_P (tls_type)
23745796c8dcSSimon Schubert 	       && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
23755796c8dcSSimon Schubert 		   || h->root.type != bfd_link_hash_undefweak)
23765796c8dcSSimon Schubert 	       && (info->shared
23775796c8dcSSimon Schubert 		   || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
2378c50c785cSJohn Marino 	htab->elf.srelgot->size += bed->s->sizeof_rela;
23795796c8dcSSimon Schubert       if (GOT_TLS_GDESC_P (tls_type))
23805796c8dcSSimon Schubert 	{
2381c50c785cSJohn Marino 	  htab->elf.srelplt->size += bed->s->sizeof_rela;
23825796c8dcSSimon Schubert 	  htab->tlsdesc_plt = (bfd_vma) -1;
23835796c8dcSSimon Schubert 	}
23845796c8dcSSimon Schubert     }
23855796c8dcSSimon Schubert   else
23865796c8dcSSimon Schubert     h->got.offset = (bfd_vma) -1;
23875796c8dcSSimon Schubert 
23885796c8dcSSimon Schubert   if (eh->dyn_relocs == NULL)
23895796c8dcSSimon Schubert     return TRUE;
23905796c8dcSSimon Schubert 
23915796c8dcSSimon Schubert   /* In the shared -Bsymbolic case, discard space allocated for
23925796c8dcSSimon Schubert      dynamic pc-relative relocs against symbols which turn out to be
23935796c8dcSSimon Schubert      defined in regular objects.  For the normal shared case, discard
23945796c8dcSSimon Schubert      space for pc-relative relocs that have become local due to symbol
23955796c8dcSSimon Schubert      visibility changes.  */
23965796c8dcSSimon Schubert 
23975796c8dcSSimon Schubert   if (info->shared)
23985796c8dcSSimon Schubert     {
23995796c8dcSSimon Schubert       /* Relocs that use pc_count are those that appear on a call
24005796c8dcSSimon Schubert 	 insn, or certain REL relocs that can generated via assembly.
24015796c8dcSSimon Schubert 	 We want calls to protected symbols to resolve directly to the
24025796c8dcSSimon Schubert 	 function rather than going via the plt.  If people want
24035796c8dcSSimon Schubert 	 function pointer comparisons to work as expected then they
24045796c8dcSSimon Schubert 	 should avoid writing weird assembly.  */
24055796c8dcSSimon Schubert       if (SYMBOL_CALLS_LOCAL (info, h))
24065796c8dcSSimon Schubert 	{
24075796c8dcSSimon Schubert 	  struct elf_dyn_relocs **pp;
24085796c8dcSSimon Schubert 
24095796c8dcSSimon Schubert 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
24105796c8dcSSimon Schubert 	    {
24115796c8dcSSimon Schubert 	      p->count -= p->pc_count;
24125796c8dcSSimon Schubert 	      p->pc_count = 0;
24135796c8dcSSimon Schubert 	      if (p->count == 0)
24145796c8dcSSimon Schubert 		*pp = p->next;
24155796c8dcSSimon Schubert 	      else
24165796c8dcSSimon Schubert 		pp = &p->next;
24175796c8dcSSimon Schubert 	    }
24185796c8dcSSimon Schubert 	}
24195796c8dcSSimon Schubert 
24205796c8dcSSimon Schubert       /* Also discard relocs on undefined weak syms with non-default
24215796c8dcSSimon Schubert 	 visibility.  */
24225796c8dcSSimon Schubert       if (eh->dyn_relocs != NULL
24235796c8dcSSimon Schubert 	  && h->root.type == bfd_link_hash_undefweak)
24245796c8dcSSimon Schubert 	{
24255796c8dcSSimon Schubert 	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
24265796c8dcSSimon Schubert 	    eh->dyn_relocs = NULL;
24275796c8dcSSimon Schubert 
24285796c8dcSSimon Schubert 	  /* Make sure undefined weak symbols are output as a dynamic
24295796c8dcSSimon Schubert 	     symbol in PIEs.  */
24305796c8dcSSimon Schubert 	  else if (h->dynindx == -1
24315796c8dcSSimon Schubert 		   && ! h->forced_local
24325796c8dcSSimon Schubert 		   && ! bfd_elf_link_record_dynamic_symbol (info, h))
24335796c8dcSSimon Schubert 	    return FALSE;
24345796c8dcSSimon Schubert 	}
24355796c8dcSSimon Schubert 
24365796c8dcSSimon Schubert     }
24375796c8dcSSimon Schubert   else if (ELIMINATE_COPY_RELOCS)
24385796c8dcSSimon Schubert     {
24395796c8dcSSimon Schubert       /* For the non-shared case, discard space for relocs against
24405796c8dcSSimon Schubert 	 symbols which turn out to need copy relocs or are not
24415796c8dcSSimon Schubert 	 dynamic.  */
24425796c8dcSSimon Schubert 
24435796c8dcSSimon Schubert       if (!h->non_got_ref
24445796c8dcSSimon Schubert 	  && ((h->def_dynamic
24455796c8dcSSimon Schubert 	       && !h->def_regular)
24465796c8dcSSimon Schubert 	      || (htab->elf.dynamic_sections_created
24475796c8dcSSimon Schubert 		  && (h->root.type == bfd_link_hash_undefweak
24485796c8dcSSimon Schubert 		      || h->root.type == bfd_link_hash_undefined))))
24495796c8dcSSimon Schubert 	{
24505796c8dcSSimon Schubert 	  /* Make sure this symbol is output as a dynamic symbol.
24515796c8dcSSimon Schubert 	     Undefined weak syms won't yet be marked as dynamic.  */
24525796c8dcSSimon Schubert 	  if (h->dynindx == -1
24535796c8dcSSimon Schubert 	      && ! h->forced_local
24545796c8dcSSimon Schubert 	      && ! bfd_elf_link_record_dynamic_symbol (info, h))
24555796c8dcSSimon Schubert 	    return FALSE;
24565796c8dcSSimon Schubert 
24575796c8dcSSimon Schubert 	  /* If that succeeded, we know we'll be keeping all the
24585796c8dcSSimon Schubert 	     relocs.  */
24595796c8dcSSimon Schubert 	  if (h->dynindx != -1)
24605796c8dcSSimon Schubert 	    goto keep;
24615796c8dcSSimon Schubert 	}
24625796c8dcSSimon Schubert 
24635796c8dcSSimon Schubert       eh->dyn_relocs = NULL;
24645796c8dcSSimon Schubert 
24655796c8dcSSimon Schubert     keep: ;
24665796c8dcSSimon Schubert     }
24675796c8dcSSimon Schubert 
24685796c8dcSSimon Schubert   /* Finally, allocate space.  */
24695796c8dcSSimon Schubert   for (p = eh->dyn_relocs; p != NULL; p = p->next)
24705796c8dcSSimon Schubert     {
24715796c8dcSSimon Schubert       asection * sreloc;
24725796c8dcSSimon Schubert 
24735796c8dcSSimon Schubert       sreloc = elf_section_data (p->sec)->sreloc;
24745796c8dcSSimon Schubert 
24755796c8dcSSimon Schubert       BFD_ASSERT (sreloc != NULL);
24765796c8dcSSimon Schubert 
2477c50c785cSJohn Marino       sreloc->size += p->count * bed->s->sizeof_rela;
24785796c8dcSSimon Schubert     }
24795796c8dcSSimon Schubert 
24805796c8dcSSimon Schubert   return TRUE;
24815796c8dcSSimon Schubert }
24825796c8dcSSimon Schubert 
24835796c8dcSSimon Schubert /* Allocate space in .plt, .got and associated reloc sections for
24845796c8dcSSimon Schubert    local dynamic relocs.  */
24855796c8dcSSimon Schubert 
24865796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_allocate_local_dynrelocs(void ** slot,void * inf)2487c50c785cSJohn Marino elf_x86_64_allocate_local_dynrelocs (void **slot, void *inf)
24885796c8dcSSimon Schubert {
24895796c8dcSSimon Schubert   struct elf_link_hash_entry *h
24905796c8dcSSimon Schubert     = (struct elf_link_hash_entry *) *slot;
24915796c8dcSSimon Schubert 
24925796c8dcSSimon Schubert   if (h->type != STT_GNU_IFUNC
24935796c8dcSSimon Schubert       || !h->def_regular
24945796c8dcSSimon Schubert       || !h->ref_regular
24955796c8dcSSimon Schubert       || !h->forced_local
24965796c8dcSSimon Schubert       || h->root.type != bfd_link_hash_defined)
24975796c8dcSSimon Schubert     abort ();
24985796c8dcSSimon Schubert 
2499c50c785cSJohn Marino   return elf_x86_64_allocate_dynrelocs (h, inf);
25005796c8dcSSimon Schubert }
25015796c8dcSSimon Schubert 
25025796c8dcSSimon Schubert /* Find any dynamic relocs that apply to read-only sections.  */
25035796c8dcSSimon Schubert 
25045796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_readonly_dynrelocs(struct elf_link_hash_entry * h,void * inf)2505c50c785cSJohn Marino elf_x86_64_readonly_dynrelocs (struct elf_link_hash_entry *h,
2506c50c785cSJohn Marino 			       void * inf)
25075796c8dcSSimon Schubert {
2508c50c785cSJohn Marino   struct elf_x86_64_link_hash_entry *eh;
25095796c8dcSSimon Schubert   struct elf_dyn_relocs *p;
25105796c8dcSSimon Schubert 
2511a45ae5f8SJohn Marino   /* Skip local IFUNC symbols. */
2512a45ae5f8SJohn Marino   if (h->forced_local && h->type == STT_GNU_IFUNC)
2513a45ae5f8SJohn Marino     return TRUE;
25145796c8dcSSimon Schubert 
2515c50c785cSJohn Marino   eh = (struct elf_x86_64_link_hash_entry *) h;
25165796c8dcSSimon Schubert   for (p = eh->dyn_relocs; p != NULL; p = p->next)
25175796c8dcSSimon Schubert     {
25185796c8dcSSimon Schubert       asection *s = p->sec->output_section;
25195796c8dcSSimon Schubert 
25205796c8dcSSimon Schubert       if (s != NULL && (s->flags & SEC_READONLY) != 0)
25215796c8dcSSimon Schubert 	{
25225796c8dcSSimon Schubert 	  struct bfd_link_info *info = (struct bfd_link_info *) inf;
25235796c8dcSSimon Schubert 
25245796c8dcSSimon Schubert 	  info->flags |= DF_TEXTREL;
25255796c8dcSSimon Schubert 
2526a45ae5f8SJohn Marino 	  if (info->warn_shared_textrel && info->shared)
2527a45ae5f8SJohn Marino 	    info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"),
2528a45ae5f8SJohn Marino 				    p->sec->owner, h->root.root.string,
2529a45ae5f8SJohn Marino 				    p->sec);
2530a45ae5f8SJohn Marino 
25315796c8dcSSimon Schubert 	  /* Not an error, just cut short the traversal.  */
25325796c8dcSSimon Schubert 	  return FALSE;
25335796c8dcSSimon Schubert 	}
25345796c8dcSSimon Schubert     }
25355796c8dcSSimon Schubert   return TRUE;
25365796c8dcSSimon Schubert }
25375796c8dcSSimon Schubert 
2538*ef5ccd6cSJohn Marino /* Convert
2539*ef5ccd6cSJohn Marino    mov foo@GOTPCREL(%rip), %reg
2540*ef5ccd6cSJohn Marino    to
2541*ef5ccd6cSJohn Marino    lea foo(%rip), %reg
2542*ef5ccd6cSJohn Marino    with the local symbol, foo.  */
2543*ef5ccd6cSJohn Marino 
2544*ef5ccd6cSJohn Marino static bfd_boolean
elf_x86_64_convert_mov_to_lea(bfd * abfd,asection * sec,struct bfd_link_info * link_info)2545*ef5ccd6cSJohn Marino elf_x86_64_convert_mov_to_lea (bfd *abfd, asection *sec,
2546*ef5ccd6cSJohn Marino 			       struct bfd_link_info *link_info)
2547*ef5ccd6cSJohn Marino {
2548*ef5ccd6cSJohn Marino   Elf_Internal_Shdr *symtab_hdr;
2549*ef5ccd6cSJohn Marino   Elf_Internal_Rela *internal_relocs;
2550*ef5ccd6cSJohn Marino   Elf_Internal_Rela *irel, *irelend;
2551*ef5ccd6cSJohn Marino   bfd_byte *contents;
2552*ef5ccd6cSJohn Marino   struct elf_x86_64_link_hash_table *htab;
2553*ef5ccd6cSJohn Marino   bfd_boolean changed_contents;
2554*ef5ccd6cSJohn Marino   bfd_boolean changed_relocs;
2555*ef5ccd6cSJohn Marino   bfd_signed_vma *local_got_refcounts;
2556*ef5ccd6cSJohn Marino 
2557*ef5ccd6cSJohn Marino   /* Don't even try to convert non-ELF outputs.  */
2558*ef5ccd6cSJohn Marino   if (!is_elf_hash_table (link_info->hash))
2559*ef5ccd6cSJohn Marino     return FALSE;
2560*ef5ccd6cSJohn Marino 
2561*ef5ccd6cSJohn Marino   /* Nothing to do if there are no codes, no relocations or no output.  */
2562*ef5ccd6cSJohn Marino   if ((sec->flags & (SEC_CODE | SEC_RELOC)) != (SEC_CODE | SEC_RELOC)
2563*ef5ccd6cSJohn Marino       || sec->reloc_count == 0
2564*ef5ccd6cSJohn Marino       || discarded_section (sec))
2565*ef5ccd6cSJohn Marino     return TRUE;
2566*ef5ccd6cSJohn Marino 
2567*ef5ccd6cSJohn Marino   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2568*ef5ccd6cSJohn Marino 
2569*ef5ccd6cSJohn Marino   /* Load the relocations for this section.  */
2570*ef5ccd6cSJohn Marino   internal_relocs = (_bfd_elf_link_read_relocs
2571*ef5ccd6cSJohn Marino 		     (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
2572*ef5ccd6cSJohn Marino 		      link_info->keep_memory));
2573*ef5ccd6cSJohn Marino   if (internal_relocs == NULL)
2574*ef5ccd6cSJohn Marino     return FALSE;
2575*ef5ccd6cSJohn Marino 
2576*ef5ccd6cSJohn Marino   htab = elf_x86_64_hash_table (link_info);
2577*ef5ccd6cSJohn Marino   changed_contents = FALSE;
2578*ef5ccd6cSJohn Marino   changed_relocs = FALSE;
2579*ef5ccd6cSJohn Marino   local_got_refcounts = elf_local_got_refcounts (abfd);
2580*ef5ccd6cSJohn Marino 
2581*ef5ccd6cSJohn Marino   /* Get the section contents.  */
2582*ef5ccd6cSJohn Marino   if (elf_section_data (sec)->this_hdr.contents != NULL)
2583*ef5ccd6cSJohn Marino     contents = elf_section_data (sec)->this_hdr.contents;
2584*ef5ccd6cSJohn Marino   else
2585*ef5ccd6cSJohn Marino     {
2586*ef5ccd6cSJohn Marino       if (!bfd_malloc_and_get_section (abfd, sec, &contents))
2587*ef5ccd6cSJohn Marino 	goto error_return;
2588*ef5ccd6cSJohn Marino     }
2589*ef5ccd6cSJohn Marino 
2590*ef5ccd6cSJohn Marino   irelend = internal_relocs + sec->reloc_count;
2591*ef5ccd6cSJohn Marino   for (irel = internal_relocs; irel < irelend; irel++)
2592*ef5ccd6cSJohn Marino     {
2593*ef5ccd6cSJohn Marino       unsigned int r_type = ELF32_R_TYPE (irel->r_info);
2594*ef5ccd6cSJohn Marino       unsigned int r_symndx = htab->r_sym (irel->r_info);
2595*ef5ccd6cSJohn Marino       unsigned int indx;
2596*ef5ccd6cSJohn Marino       struct elf_link_hash_entry *h;
2597*ef5ccd6cSJohn Marino 
2598*ef5ccd6cSJohn Marino       if (r_type != R_X86_64_GOTPCREL)
2599*ef5ccd6cSJohn Marino 	continue;
2600*ef5ccd6cSJohn Marino 
2601*ef5ccd6cSJohn Marino       /* Get the symbol referred to by the reloc.  */
2602*ef5ccd6cSJohn Marino       if (r_symndx < symtab_hdr->sh_info)
2603*ef5ccd6cSJohn Marino 	{
2604*ef5ccd6cSJohn Marino 	  Elf_Internal_Sym *isym;
2605*ef5ccd6cSJohn Marino 
2606*ef5ccd6cSJohn Marino 	  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
2607*ef5ccd6cSJohn Marino 					abfd, r_symndx);
2608*ef5ccd6cSJohn Marino 
2609*ef5ccd6cSJohn Marino 	  /* STT_GNU_IFUNC must keep R_X86_64_GOTPCREL relocation.  */
2610*ef5ccd6cSJohn Marino 	  if (ELF_ST_TYPE (isym->st_info) != STT_GNU_IFUNC
2611*ef5ccd6cSJohn Marino 	      && bfd_get_8 (input_bfd,
2612*ef5ccd6cSJohn Marino 			    contents + irel->r_offset - 2) == 0x8b)
2613*ef5ccd6cSJohn Marino 	    {
2614*ef5ccd6cSJohn Marino 	      bfd_put_8 (output_bfd, 0x8d,
2615*ef5ccd6cSJohn Marino 			 contents + irel->r_offset - 2);
2616*ef5ccd6cSJohn Marino 	      irel->r_info = htab->r_info (r_symndx, R_X86_64_PC32);
2617*ef5ccd6cSJohn Marino 	      if (local_got_refcounts != NULL
2618*ef5ccd6cSJohn Marino 		  && local_got_refcounts[r_symndx] > 0)
2619*ef5ccd6cSJohn Marino 		local_got_refcounts[r_symndx] -= 1;
2620*ef5ccd6cSJohn Marino 	      changed_contents = TRUE;
2621*ef5ccd6cSJohn Marino 	      changed_relocs = TRUE;
2622*ef5ccd6cSJohn Marino 	    }
2623*ef5ccd6cSJohn Marino 	  continue;
2624*ef5ccd6cSJohn Marino 	}
2625*ef5ccd6cSJohn Marino 
2626*ef5ccd6cSJohn Marino       indx = r_symndx - symtab_hdr->sh_info;
2627*ef5ccd6cSJohn Marino       h = elf_sym_hashes (abfd)[indx];
2628*ef5ccd6cSJohn Marino       BFD_ASSERT (h != NULL);
2629*ef5ccd6cSJohn Marino 
2630*ef5ccd6cSJohn Marino       while (h->root.type == bfd_link_hash_indirect
2631*ef5ccd6cSJohn Marino 	     || h->root.type == bfd_link_hash_warning)
2632*ef5ccd6cSJohn Marino 	h = (struct elf_link_hash_entry *) h->root.u.i.link;
2633*ef5ccd6cSJohn Marino 
2634*ef5ccd6cSJohn Marino       /* STT_GNU_IFUNC must keep R_X86_64_GOTPCREL relocation.  We also
2635*ef5ccd6cSJohn Marino 	 avoid optimizing _DYNAMIC since ld.so may use its link-time
2636*ef5ccd6cSJohn Marino 	 address.  */
2637*ef5ccd6cSJohn Marino       if (h->def_regular
2638*ef5ccd6cSJohn Marino 	  && h->type != STT_GNU_IFUNC
2639*ef5ccd6cSJohn Marino 	  && h != htab->elf.hdynamic
2640*ef5ccd6cSJohn Marino 	  && SYMBOL_REFERENCES_LOCAL (link_info, h)
2641*ef5ccd6cSJohn Marino 	  && bfd_get_8 (input_bfd,
2642*ef5ccd6cSJohn Marino 			contents + irel->r_offset - 2) == 0x8b)
2643*ef5ccd6cSJohn Marino 	{
2644*ef5ccd6cSJohn Marino 	  bfd_put_8 (output_bfd, 0x8d,
2645*ef5ccd6cSJohn Marino 		     contents + irel->r_offset - 2);
2646*ef5ccd6cSJohn Marino 	  irel->r_info = htab->r_info (r_symndx, R_X86_64_PC32);
2647*ef5ccd6cSJohn Marino 	  if (h->got.refcount > 0)
2648*ef5ccd6cSJohn Marino 	    h->got.refcount -= 1;
2649*ef5ccd6cSJohn Marino 	  changed_contents = TRUE;
2650*ef5ccd6cSJohn Marino 	  changed_relocs = TRUE;
2651*ef5ccd6cSJohn Marino 	}
2652*ef5ccd6cSJohn Marino     }
2653*ef5ccd6cSJohn Marino 
2654*ef5ccd6cSJohn Marino   if (contents != NULL
2655*ef5ccd6cSJohn Marino       && elf_section_data (sec)->this_hdr.contents != contents)
2656*ef5ccd6cSJohn Marino     {
2657*ef5ccd6cSJohn Marino       if (!changed_contents && !link_info->keep_memory)
2658*ef5ccd6cSJohn Marino 	free (contents);
2659*ef5ccd6cSJohn Marino       else
2660*ef5ccd6cSJohn Marino 	{
2661*ef5ccd6cSJohn Marino 	  /* Cache the section contents for elf_link_input_bfd.  */
2662*ef5ccd6cSJohn Marino 	  elf_section_data (sec)->this_hdr.contents = contents;
2663*ef5ccd6cSJohn Marino 	}
2664*ef5ccd6cSJohn Marino     }
2665*ef5ccd6cSJohn Marino 
2666*ef5ccd6cSJohn Marino   if (elf_section_data (sec)->relocs != internal_relocs)
2667*ef5ccd6cSJohn Marino     {
2668*ef5ccd6cSJohn Marino       if (!changed_relocs)
2669*ef5ccd6cSJohn Marino 	free (internal_relocs);
2670*ef5ccd6cSJohn Marino       else
2671*ef5ccd6cSJohn Marino 	elf_section_data (sec)->relocs = internal_relocs;
2672*ef5ccd6cSJohn Marino     }
2673*ef5ccd6cSJohn Marino 
2674*ef5ccd6cSJohn Marino   return TRUE;
2675*ef5ccd6cSJohn Marino 
2676*ef5ccd6cSJohn Marino  error_return:
2677*ef5ccd6cSJohn Marino   if (contents != NULL
2678*ef5ccd6cSJohn Marino       && elf_section_data (sec)->this_hdr.contents != contents)
2679*ef5ccd6cSJohn Marino     free (contents);
2680*ef5ccd6cSJohn Marino   if (internal_relocs != NULL
2681*ef5ccd6cSJohn Marino       && elf_section_data (sec)->relocs != internal_relocs)
2682*ef5ccd6cSJohn Marino     free (internal_relocs);
2683*ef5ccd6cSJohn Marino   return FALSE;
2684*ef5ccd6cSJohn Marino }
2685*ef5ccd6cSJohn Marino 
26865796c8dcSSimon Schubert /* Set the sizes of the dynamic sections.  */
26875796c8dcSSimon Schubert 
26885796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_size_dynamic_sections(bfd * output_bfd,struct bfd_link_info * info)2689c50c785cSJohn Marino elf_x86_64_size_dynamic_sections (bfd *output_bfd,
26905796c8dcSSimon Schubert 				  struct bfd_link_info *info)
26915796c8dcSSimon Schubert {
2692c50c785cSJohn Marino   struct elf_x86_64_link_hash_table *htab;
26935796c8dcSSimon Schubert   bfd *dynobj;
26945796c8dcSSimon Schubert   asection *s;
26955796c8dcSSimon Schubert   bfd_boolean relocs;
26965796c8dcSSimon Schubert   bfd *ibfd;
2697c50c785cSJohn Marino   const struct elf_backend_data *bed;
26985796c8dcSSimon Schubert 
2699c50c785cSJohn Marino   htab = elf_x86_64_hash_table (info);
2700cf7f2e2dSJohn Marino   if (htab == NULL)
2701cf7f2e2dSJohn Marino     return FALSE;
2702c50c785cSJohn Marino   bed = get_elf_backend_data (output_bfd);
2703cf7f2e2dSJohn Marino 
27045796c8dcSSimon Schubert   dynobj = htab->elf.dynobj;
27055796c8dcSSimon Schubert   if (dynobj == NULL)
27065796c8dcSSimon Schubert     abort ();
27075796c8dcSSimon Schubert 
27085796c8dcSSimon Schubert   if (htab->elf.dynamic_sections_created)
27095796c8dcSSimon Schubert     {
27105796c8dcSSimon Schubert       /* Set the contents of the .interp section to the interpreter.  */
27115796c8dcSSimon Schubert       if (info->executable)
27125796c8dcSSimon Schubert 	{
2713*ef5ccd6cSJohn Marino 	  s = bfd_get_linker_section (dynobj, ".interp");
27145796c8dcSSimon Schubert 	  if (s == NULL)
27155796c8dcSSimon Schubert 	    abort ();
2716c50c785cSJohn Marino 	  s->size = htab->dynamic_interpreter_size;
2717c50c785cSJohn Marino 	  s->contents = (unsigned char *) htab->dynamic_interpreter;
27185796c8dcSSimon Schubert 	}
27195796c8dcSSimon Schubert     }
27205796c8dcSSimon Schubert 
27215796c8dcSSimon Schubert   /* Set up .got offsets for local syms, and space for local dynamic
27225796c8dcSSimon Schubert      relocs.  */
27235796c8dcSSimon Schubert   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
27245796c8dcSSimon Schubert     {
27255796c8dcSSimon Schubert       bfd_signed_vma *local_got;
27265796c8dcSSimon Schubert       bfd_signed_vma *end_local_got;
27275796c8dcSSimon Schubert       char *local_tls_type;
27285796c8dcSSimon Schubert       bfd_vma *local_tlsdesc_gotent;
27295796c8dcSSimon Schubert       bfd_size_type locsymcount;
27305796c8dcSSimon Schubert       Elf_Internal_Shdr *symtab_hdr;
27315796c8dcSSimon Schubert       asection *srel;
27325796c8dcSSimon Schubert 
27335796c8dcSSimon Schubert       if (! is_x86_64_elf (ibfd))
27345796c8dcSSimon Schubert 	continue;
27355796c8dcSSimon Schubert 
27365796c8dcSSimon Schubert       for (s = ibfd->sections; s != NULL; s = s->next)
27375796c8dcSSimon Schubert 	{
27385796c8dcSSimon Schubert 	  struct elf_dyn_relocs *p;
27395796c8dcSSimon Schubert 
2740*ef5ccd6cSJohn Marino 	  if (!elf_x86_64_convert_mov_to_lea (ibfd, s, info))
2741*ef5ccd6cSJohn Marino 	    return FALSE;
2742*ef5ccd6cSJohn Marino 
27435796c8dcSSimon Schubert 	  for (p = (struct elf_dyn_relocs *)
27445796c8dcSSimon Schubert 		    (elf_section_data (s)->local_dynrel);
27455796c8dcSSimon Schubert 	       p != NULL;
27465796c8dcSSimon Schubert 	       p = p->next)
27475796c8dcSSimon Schubert 	    {
27485796c8dcSSimon Schubert 	      if (!bfd_is_abs_section (p->sec)
27495796c8dcSSimon Schubert 		  && bfd_is_abs_section (p->sec->output_section))
27505796c8dcSSimon Schubert 		{
27515796c8dcSSimon Schubert 		  /* Input section has been discarded, either because
27525796c8dcSSimon Schubert 		     it is a copy of a linkonce section or due to
27535796c8dcSSimon Schubert 		     linker script /DISCARD/, so we'll be discarding
27545796c8dcSSimon Schubert 		     the relocs too.  */
27555796c8dcSSimon Schubert 		}
27565796c8dcSSimon Schubert 	      else if (p->count != 0)
27575796c8dcSSimon Schubert 		{
27585796c8dcSSimon Schubert 		  srel = elf_section_data (p->sec)->sreloc;
2759c50c785cSJohn Marino 		  srel->size += p->count * bed->s->sizeof_rela;
2760a45ae5f8SJohn Marino 		  if ((p->sec->output_section->flags & SEC_READONLY) != 0
2761a45ae5f8SJohn Marino 		      && (info->flags & DF_TEXTREL) == 0)
2762a45ae5f8SJohn Marino 		    {
27635796c8dcSSimon Schubert 		      info->flags |= DF_TEXTREL;
2764a45ae5f8SJohn Marino 		      if (info->warn_shared_textrel && info->shared)
2765a45ae5f8SJohn Marino 			info->callbacks->einfo (_("%P: %B: warning: relocation in readonly section `%A'.\n"),
2766a45ae5f8SJohn Marino 						p->sec->owner, p->sec);
2767a45ae5f8SJohn Marino 		    }
27685796c8dcSSimon Schubert 		}
27695796c8dcSSimon Schubert 	    }
27705796c8dcSSimon Schubert 	}
27715796c8dcSSimon Schubert 
27725796c8dcSSimon Schubert       local_got = elf_local_got_refcounts (ibfd);
27735796c8dcSSimon Schubert       if (!local_got)
27745796c8dcSSimon Schubert 	continue;
27755796c8dcSSimon Schubert 
27765796c8dcSSimon Schubert       symtab_hdr = &elf_symtab_hdr (ibfd);
27775796c8dcSSimon Schubert       locsymcount = symtab_hdr->sh_info;
27785796c8dcSSimon Schubert       end_local_got = local_got + locsymcount;
2779c50c785cSJohn Marino       local_tls_type = elf_x86_64_local_got_tls_type (ibfd);
2780c50c785cSJohn Marino       local_tlsdesc_gotent = elf_x86_64_local_tlsdesc_gotent (ibfd);
27815796c8dcSSimon Schubert       s = htab->elf.sgot;
27825796c8dcSSimon Schubert       srel = htab->elf.srelgot;
27835796c8dcSSimon Schubert       for (; local_got < end_local_got;
27845796c8dcSSimon Schubert 	   ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
27855796c8dcSSimon Schubert 	{
27865796c8dcSSimon Schubert 	  *local_tlsdesc_gotent = (bfd_vma) -1;
27875796c8dcSSimon Schubert 	  if (*local_got > 0)
27885796c8dcSSimon Schubert 	    {
27895796c8dcSSimon Schubert 	      if (GOT_TLS_GDESC_P (*local_tls_type))
27905796c8dcSSimon Schubert 		{
27915796c8dcSSimon Schubert 		  *local_tlsdesc_gotent = htab->elf.sgotplt->size
2792c50c785cSJohn Marino 		    - elf_x86_64_compute_jump_table_size (htab);
27935796c8dcSSimon Schubert 		  htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
27945796c8dcSSimon Schubert 		  *local_got = (bfd_vma) -2;
27955796c8dcSSimon Schubert 		}
27965796c8dcSSimon Schubert 	      if (! GOT_TLS_GDESC_P (*local_tls_type)
27975796c8dcSSimon Schubert 		  || GOT_TLS_GD_P (*local_tls_type))
27985796c8dcSSimon Schubert 		{
27995796c8dcSSimon Schubert 		  *local_got = s->size;
28005796c8dcSSimon Schubert 		  s->size += GOT_ENTRY_SIZE;
28015796c8dcSSimon Schubert 		  if (GOT_TLS_GD_P (*local_tls_type))
28025796c8dcSSimon Schubert 		    s->size += GOT_ENTRY_SIZE;
28035796c8dcSSimon Schubert 		}
28045796c8dcSSimon Schubert 	      if (info->shared
28055796c8dcSSimon Schubert 		  || GOT_TLS_GD_ANY_P (*local_tls_type)
28065796c8dcSSimon Schubert 		  || *local_tls_type == GOT_TLS_IE)
28075796c8dcSSimon Schubert 		{
28085796c8dcSSimon Schubert 		  if (GOT_TLS_GDESC_P (*local_tls_type))
28095796c8dcSSimon Schubert 		    {
28105796c8dcSSimon Schubert 		      htab->elf.srelplt->size
2811c50c785cSJohn Marino 			+= bed->s->sizeof_rela;
28125796c8dcSSimon Schubert 		      htab->tlsdesc_plt = (bfd_vma) -1;
28135796c8dcSSimon Schubert 		    }
28145796c8dcSSimon Schubert 		  if (! GOT_TLS_GDESC_P (*local_tls_type)
28155796c8dcSSimon Schubert 		      || GOT_TLS_GD_P (*local_tls_type))
2816c50c785cSJohn Marino 		    srel->size += bed->s->sizeof_rela;
28175796c8dcSSimon Schubert 		}
28185796c8dcSSimon Schubert 	    }
28195796c8dcSSimon Schubert 	  else
28205796c8dcSSimon Schubert 	    *local_got = (bfd_vma) -1;
28215796c8dcSSimon Schubert 	}
28225796c8dcSSimon Schubert     }
28235796c8dcSSimon Schubert 
28245796c8dcSSimon Schubert   if (htab->tls_ld_got.refcount > 0)
28255796c8dcSSimon Schubert     {
28265796c8dcSSimon Schubert       /* Allocate 2 got entries and 1 dynamic reloc for R_X86_64_TLSLD
28275796c8dcSSimon Schubert 	 relocs.  */
28285796c8dcSSimon Schubert       htab->tls_ld_got.offset = htab->elf.sgot->size;
28295796c8dcSSimon Schubert       htab->elf.sgot->size += 2 * GOT_ENTRY_SIZE;
2830c50c785cSJohn Marino       htab->elf.srelgot->size += bed->s->sizeof_rela;
28315796c8dcSSimon Schubert     }
28325796c8dcSSimon Schubert   else
28335796c8dcSSimon Schubert     htab->tls_ld_got.offset = -1;
28345796c8dcSSimon Schubert 
28355796c8dcSSimon Schubert   /* Allocate global sym .plt and .got entries, and space for global
28365796c8dcSSimon Schubert      sym dynamic relocs.  */
2837c50c785cSJohn Marino   elf_link_hash_traverse (&htab->elf, elf_x86_64_allocate_dynrelocs,
28385796c8dcSSimon Schubert 			  info);
28395796c8dcSSimon Schubert 
28405796c8dcSSimon Schubert   /* Allocate .plt and .got entries, and space for local symbols.  */
28415796c8dcSSimon Schubert   htab_traverse (htab->loc_hash_table,
2842c50c785cSJohn Marino 		 elf_x86_64_allocate_local_dynrelocs,
28435796c8dcSSimon Schubert 		 info);
28445796c8dcSSimon Schubert 
28455796c8dcSSimon Schubert   /* For every jump slot reserved in the sgotplt, reloc_count is
28465796c8dcSSimon Schubert      incremented.  However, when we reserve space for TLS descriptors,
28475796c8dcSSimon Schubert      it's not incremented, so in order to compute the space reserved
28485796c8dcSSimon Schubert      for them, it suffices to multiply the reloc count by the jump
2849a45ae5f8SJohn Marino      slot size.
2850a45ae5f8SJohn Marino 
2851a45ae5f8SJohn Marino      PR ld/13302: We start next_irelative_index at the end of .rela.plt
2852a45ae5f8SJohn Marino      so that R_X86_64_IRELATIVE entries come last.  */
28535796c8dcSSimon Schubert   if (htab->elf.srelplt)
2854a45ae5f8SJohn Marino     {
28555796c8dcSSimon Schubert       htab->sgotplt_jump_table_size
2856c50c785cSJohn Marino 	= elf_x86_64_compute_jump_table_size (htab);
2857a45ae5f8SJohn Marino       htab->next_irelative_index = htab->elf.srelplt->reloc_count - 1;
2858a45ae5f8SJohn Marino     }
2859a45ae5f8SJohn Marino   else if (htab->elf.irelplt)
2860a45ae5f8SJohn Marino     htab->next_irelative_index = htab->elf.irelplt->reloc_count - 1;
28615796c8dcSSimon Schubert 
28625796c8dcSSimon Schubert   if (htab->tlsdesc_plt)
28635796c8dcSSimon Schubert     {
28645796c8dcSSimon Schubert       /* If we're not using lazy TLS relocations, don't generate the
28655796c8dcSSimon Schubert 	 PLT and GOT entries they require.  */
28665796c8dcSSimon Schubert       if ((info->flags & DF_BIND_NOW))
28675796c8dcSSimon Schubert 	htab->tlsdesc_plt = 0;
28685796c8dcSSimon Schubert       else
28695796c8dcSSimon Schubert 	{
28705796c8dcSSimon Schubert 	  htab->tlsdesc_got = htab->elf.sgot->size;
28715796c8dcSSimon Schubert 	  htab->elf.sgot->size += GOT_ENTRY_SIZE;
28725796c8dcSSimon Schubert 	  /* Reserve room for the initial entry.
28735796c8dcSSimon Schubert 	     FIXME: we could probably do away with it in this case.  */
28745796c8dcSSimon Schubert 	  if (htab->elf.splt->size == 0)
2875*ef5ccd6cSJohn Marino 	    htab->elf.splt->size += GET_PLT_ENTRY_SIZE (output_bfd);
28765796c8dcSSimon Schubert 	  htab->tlsdesc_plt = htab->elf.splt->size;
2877*ef5ccd6cSJohn Marino 	  htab->elf.splt->size += GET_PLT_ENTRY_SIZE (output_bfd);
28785796c8dcSSimon Schubert 	}
28795796c8dcSSimon Schubert     }
28805796c8dcSSimon Schubert 
2881c50c785cSJohn Marino   if (htab->elf.sgotplt)
2882c50c785cSJohn Marino     {
2883c50c785cSJohn Marino       /* Don't allocate .got.plt section if there are no GOT nor PLT
2884c50c785cSJohn Marino 	 entries and there is no refeence to _GLOBAL_OFFSET_TABLE_.  */
2885*ef5ccd6cSJohn Marino       if ((htab->elf.hgot == NULL
2886*ef5ccd6cSJohn Marino 	   || !htab->elf.hgot->ref_regular_nonweak)
2887c50c785cSJohn Marino 	  && (htab->elf.sgotplt->size
2888c50c785cSJohn Marino 	      == get_elf_backend_data (output_bfd)->got_header_size)
2889c50c785cSJohn Marino 	  && (htab->elf.splt == NULL
2890c50c785cSJohn Marino 	      || htab->elf.splt->size == 0)
2891c50c785cSJohn Marino 	  && (htab->elf.sgot == NULL
2892c50c785cSJohn Marino 	      || htab->elf.sgot->size == 0)
2893c50c785cSJohn Marino 	  && (htab->elf.iplt == NULL
2894c50c785cSJohn Marino 	      || htab->elf.iplt->size == 0)
2895c50c785cSJohn Marino 	  && (htab->elf.igotplt == NULL
2896c50c785cSJohn Marino 	      || htab->elf.igotplt->size == 0))
2897c50c785cSJohn Marino 	htab->elf.sgotplt->size = 0;
2898c50c785cSJohn Marino     }
2899c50c785cSJohn Marino 
2900*ef5ccd6cSJohn Marino   if (htab->plt_eh_frame != NULL
2901*ef5ccd6cSJohn Marino       && htab->elf.splt != NULL
2902*ef5ccd6cSJohn Marino       && htab->elf.splt->size != 0
2903*ef5ccd6cSJohn Marino       && !bfd_is_abs_section (htab->elf.splt->output_section)
2904*ef5ccd6cSJohn Marino       && _bfd_elf_eh_frame_present (info))
2905*ef5ccd6cSJohn Marino     {
2906*ef5ccd6cSJohn Marino       const struct elf_x86_64_backend_data *arch_data
2907*ef5ccd6cSJohn Marino 	= (const struct elf_x86_64_backend_data *) bed->arch_data;
2908*ef5ccd6cSJohn Marino       htab->plt_eh_frame->size = arch_data->eh_frame_plt_size;
2909*ef5ccd6cSJohn Marino     }
2910*ef5ccd6cSJohn Marino 
29115796c8dcSSimon Schubert   /* We now have determined the sizes of the various dynamic sections.
29125796c8dcSSimon Schubert      Allocate memory for them.  */
29135796c8dcSSimon Schubert   relocs = FALSE;
29145796c8dcSSimon Schubert   for (s = dynobj->sections; s != NULL; s = s->next)
29155796c8dcSSimon Schubert     {
29165796c8dcSSimon Schubert       if ((s->flags & SEC_LINKER_CREATED) == 0)
29175796c8dcSSimon Schubert 	continue;
29185796c8dcSSimon Schubert 
29195796c8dcSSimon Schubert       if (s == htab->elf.splt
29205796c8dcSSimon Schubert 	  || s == htab->elf.sgot
29215796c8dcSSimon Schubert 	  || s == htab->elf.sgotplt
29225796c8dcSSimon Schubert 	  || s == htab->elf.iplt
29235796c8dcSSimon Schubert 	  || s == htab->elf.igotplt
2924*ef5ccd6cSJohn Marino 	  || s == htab->plt_eh_frame
29255796c8dcSSimon Schubert 	  || s == htab->sdynbss)
29265796c8dcSSimon Schubert 	{
29275796c8dcSSimon Schubert 	  /* Strip this section if we don't need it; see the
29285796c8dcSSimon Schubert 	     comment below.  */
29295796c8dcSSimon Schubert 	}
29305796c8dcSSimon Schubert       else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
29315796c8dcSSimon Schubert 	{
29325796c8dcSSimon Schubert 	  if (s->size != 0 && s != htab->elf.srelplt)
29335796c8dcSSimon Schubert 	    relocs = TRUE;
29345796c8dcSSimon Schubert 
29355796c8dcSSimon Schubert 	  /* We use the reloc_count field as a counter if we need
29365796c8dcSSimon Schubert 	     to copy relocs into the output file.  */
29375796c8dcSSimon Schubert 	  if (s != htab->elf.srelplt)
29385796c8dcSSimon Schubert 	    s->reloc_count = 0;
29395796c8dcSSimon Schubert 	}
29405796c8dcSSimon Schubert       else
29415796c8dcSSimon Schubert 	{
29425796c8dcSSimon Schubert 	  /* It's not one of our sections, so don't allocate space.  */
29435796c8dcSSimon Schubert 	  continue;
29445796c8dcSSimon Schubert 	}
29455796c8dcSSimon Schubert 
29465796c8dcSSimon Schubert       if (s->size == 0)
29475796c8dcSSimon Schubert 	{
29485796c8dcSSimon Schubert 	  /* If we don't need this section, strip it from the
29495796c8dcSSimon Schubert 	     output file.  This is mostly to handle .rela.bss and
29505796c8dcSSimon Schubert 	     .rela.plt.  We must create both sections in
29515796c8dcSSimon Schubert 	     create_dynamic_sections, because they must be created
29525796c8dcSSimon Schubert 	     before the linker maps input sections to output
29535796c8dcSSimon Schubert 	     sections.  The linker does that before
29545796c8dcSSimon Schubert 	     adjust_dynamic_symbol is called, and it is that
29555796c8dcSSimon Schubert 	     function which decides whether anything needs to go
29565796c8dcSSimon Schubert 	     into these sections.  */
29575796c8dcSSimon Schubert 
29585796c8dcSSimon Schubert 	  s->flags |= SEC_EXCLUDE;
29595796c8dcSSimon Schubert 	  continue;
29605796c8dcSSimon Schubert 	}
29615796c8dcSSimon Schubert 
29625796c8dcSSimon Schubert       if ((s->flags & SEC_HAS_CONTENTS) == 0)
29635796c8dcSSimon Schubert 	continue;
29645796c8dcSSimon Schubert 
29655796c8dcSSimon Schubert       /* Allocate memory for the section contents.  We use bfd_zalloc
29665796c8dcSSimon Schubert 	 here in case unused entries are not reclaimed before the
29675796c8dcSSimon Schubert 	 section's contents are written out.  This should not happen,
29685796c8dcSSimon Schubert 	 but this way if it does, we get a R_X86_64_NONE reloc instead
29695796c8dcSSimon Schubert 	 of garbage.  */
29705796c8dcSSimon Schubert       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
29715796c8dcSSimon Schubert       if (s->contents == NULL)
29725796c8dcSSimon Schubert 	return FALSE;
29735796c8dcSSimon Schubert     }
29745796c8dcSSimon Schubert 
2975a45ae5f8SJohn Marino   if (htab->plt_eh_frame != NULL
2976*ef5ccd6cSJohn Marino       && htab->plt_eh_frame->contents != NULL)
2977*ef5ccd6cSJohn Marino     {
2978*ef5ccd6cSJohn Marino       const struct elf_x86_64_backend_data *arch_data
2979*ef5ccd6cSJohn Marino 	= (const struct elf_x86_64_backend_data *) bed->arch_data;
2980*ef5ccd6cSJohn Marino 
2981*ef5ccd6cSJohn Marino       memcpy (htab->plt_eh_frame->contents,
2982*ef5ccd6cSJohn Marino 	      arch_data->eh_frame_plt, htab->plt_eh_frame->size);
2983a45ae5f8SJohn Marino       bfd_put_32 (dynobj, htab->elf.splt->size,
2984a45ae5f8SJohn Marino 		  htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
2985*ef5ccd6cSJohn Marino     }
2986a45ae5f8SJohn Marino 
29875796c8dcSSimon Schubert   if (htab->elf.dynamic_sections_created)
29885796c8dcSSimon Schubert     {
29895796c8dcSSimon Schubert       /* Add some entries to the .dynamic section.  We fill in the
2990c50c785cSJohn Marino 	 values later, in elf_x86_64_finish_dynamic_sections, but we
29915796c8dcSSimon Schubert 	 must add the entries now so that we get the correct size for
29925796c8dcSSimon Schubert 	 the .dynamic section.	The DT_DEBUG entry is filled in by the
29935796c8dcSSimon Schubert 	 dynamic linker and used by the debugger.  */
29945796c8dcSSimon Schubert #define add_dynamic_entry(TAG, VAL) \
29955796c8dcSSimon Schubert   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
29965796c8dcSSimon Schubert 
29975796c8dcSSimon Schubert       if (info->executable)
29985796c8dcSSimon Schubert 	{
29995796c8dcSSimon Schubert 	  if (!add_dynamic_entry (DT_DEBUG, 0))
30005796c8dcSSimon Schubert 	    return FALSE;
30015796c8dcSSimon Schubert 	}
30025796c8dcSSimon Schubert 
30035796c8dcSSimon Schubert       if (htab->elf.splt->size != 0)
30045796c8dcSSimon Schubert 	{
30055796c8dcSSimon Schubert 	  if (!add_dynamic_entry (DT_PLTGOT, 0)
30065796c8dcSSimon Schubert 	      || !add_dynamic_entry (DT_PLTRELSZ, 0)
30075796c8dcSSimon Schubert 	      || !add_dynamic_entry (DT_PLTREL, DT_RELA)
30085796c8dcSSimon Schubert 	      || !add_dynamic_entry (DT_JMPREL, 0))
30095796c8dcSSimon Schubert 	    return FALSE;
30105796c8dcSSimon Schubert 
30115796c8dcSSimon Schubert 	  if (htab->tlsdesc_plt
30125796c8dcSSimon Schubert 	      && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
30135796c8dcSSimon Schubert 		  || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
30145796c8dcSSimon Schubert 	    return FALSE;
30155796c8dcSSimon Schubert 	}
30165796c8dcSSimon Schubert 
30175796c8dcSSimon Schubert       if (relocs)
30185796c8dcSSimon Schubert 	{
30195796c8dcSSimon Schubert 	  if (!add_dynamic_entry (DT_RELA, 0)
30205796c8dcSSimon Schubert 	      || !add_dynamic_entry (DT_RELASZ, 0)
3021c50c785cSJohn Marino 	      || !add_dynamic_entry (DT_RELAENT, bed->s->sizeof_rela))
30225796c8dcSSimon Schubert 	    return FALSE;
30235796c8dcSSimon Schubert 
30245796c8dcSSimon Schubert 	  /* If any dynamic relocs apply to a read-only section,
30255796c8dcSSimon Schubert 	     then we need a DT_TEXTREL entry.  */
30265796c8dcSSimon Schubert 	  if ((info->flags & DF_TEXTREL) == 0)
30275796c8dcSSimon Schubert 	    elf_link_hash_traverse (&htab->elf,
3028c50c785cSJohn Marino 				    elf_x86_64_readonly_dynrelocs,
30295796c8dcSSimon Schubert 				    info);
30305796c8dcSSimon Schubert 
30315796c8dcSSimon Schubert 	  if ((info->flags & DF_TEXTREL) != 0)
30325796c8dcSSimon Schubert 	    {
30335796c8dcSSimon Schubert 	      if (!add_dynamic_entry (DT_TEXTREL, 0))
30345796c8dcSSimon Schubert 		return FALSE;
30355796c8dcSSimon Schubert 	    }
30365796c8dcSSimon Schubert 	}
30375796c8dcSSimon Schubert     }
30385796c8dcSSimon Schubert #undef add_dynamic_entry
30395796c8dcSSimon Schubert 
30405796c8dcSSimon Schubert   return TRUE;
30415796c8dcSSimon Schubert }
30425796c8dcSSimon Schubert 
30435796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_always_size_sections(bfd * output_bfd,struct bfd_link_info * info)3044c50c785cSJohn Marino elf_x86_64_always_size_sections (bfd *output_bfd,
30455796c8dcSSimon Schubert 				 struct bfd_link_info *info)
30465796c8dcSSimon Schubert {
30475796c8dcSSimon Schubert   asection *tls_sec = elf_hash_table (info)->tls_sec;
30485796c8dcSSimon Schubert 
30495796c8dcSSimon Schubert   if (tls_sec)
30505796c8dcSSimon Schubert     {
30515796c8dcSSimon Schubert       struct elf_link_hash_entry *tlsbase;
30525796c8dcSSimon Schubert 
30535796c8dcSSimon Schubert       tlsbase = elf_link_hash_lookup (elf_hash_table (info),
30545796c8dcSSimon Schubert 				      "_TLS_MODULE_BASE_",
30555796c8dcSSimon Schubert 				      FALSE, FALSE, FALSE);
30565796c8dcSSimon Schubert 
30575796c8dcSSimon Schubert       if (tlsbase && tlsbase->type == STT_TLS)
30585796c8dcSSimon Schubert 	{
3059c50c785cSJohn Marino 	  struct elf_x86_64_link_hash_table *htab;
30605796c8dcSSimon Schubert 	  struct bfd_link_hash_entry *bh = NULL;
30615796c8dcSSimon Schubert 	  const struct elf_backend_data *bed
30625796c8dcSSimon Schubert 	    = get_elf_backend_data (output_bfd);
30635796c8dcSSimon Schubert 
3064c50c785cSJohn Marino 	  htab = elf_x86_64_hash_table (info);
3065cf7f2e2dSJohn Marino 	  if (htab == NULL)
3066cf7f2e2dSJohn Marino 	    return FALSE;
3067cf7f2e2dSJohn Marino 
30685796c8dcSSimon Schubert 	  if (!(_bfd_generic_link_add_one_symbol
30695796c8dcSSimon Schubert 		(info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
30705796c8dcSSimon Schubert 		 tls_sec, 0, NULL, FALSE,
30715796c8dcSSimon Schubert 		 bed->collect, &bh)))
30725796c8dcSSimon Schubert 	    return FALSE;
30735796c8dcSSimon Schubert 
3074cf7f2e2dSJohn Marino 	  htab->tls_module_base = bh;
30755796c8dcSSimon Schubert 
30765796c8dcSSimon Schubert 	  tlsbase = (struct elf_link_hash_entry *)bh;
30775796c8dcSSimon Schubert 	  tlsbase->def_regular = 1;
30785796c8dcSSimon Schubert 	  tlsbase->other = STV_HIDDEN;
30795796c8dcSSimon Schubert 	  (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
30805796c8dcSSimon Schubert 	}
30815796c8dcSSimon Schubert     }
30825796c8dcSSimon Schubert 
30835796c8dcSSimon Schubert   return TRUE;
30845796c8dcSSimon Schubert }
30855796c8dcSSimon Schubert 
30865796c8dcSSimon Schubert /* _TLS_MODULE_BASE_ needs to be treated especially when linking
30875796c8dcSSimon Schubert    executables.  Rather than setting it to the beginning of the TLS
30885796c8dcSSimon Schubert    section, we have to set it to the end.  This function may be called
30895796c8dcSSimon Schubert    multiple times, it is idempotent.  */
30905796c8dcSSimon Schubert 
30915796c8dcSSimon Schubert static void
elf_x86_64_set_tls_module_base(struct bfd_link_info * info)3092c50c785cSJohn Marino elf_x86_64_set_tls_module_base (struct bfd_link_info *info)
30935796c8dcSSimon Schubert {
3094c50c785cSJohn Marino   struct elf_x86_64_link_hash_table *htab;
30955796c8dcSSimon Schubert   struct bfd_link_hash_entry *base;
30965796c8dcSSimon Schubert 
30975796c8dcSSimon Schubert   if (!info->executable)
30985796c8dcSSimon Schubert     return;
30995796c8dcSSimon Schubert 
3100c50c785cSJohn Marino   htab = elf_x86_64_hash_table (info);
3101cf7f2e2dSJohn Marino   if (htab == NULL)
31025796c8dcSSimon Schubert     return;
31035796c8dcSSimon Schubert 
3104cf7f2e2dSJohn Marino   base = htab->tls_module_base;
3105cf7f2e2dSJohn Marino   if (base == NULL)
3106cf7f2e2dSJohn Marino     return;
3107cf7f2e2dSJohn Marino 
3108cf7f2e2dSJohn Marino   base->u.def.value = htab->elf.tls_size;
31095796c8dcSSimon Schubert }
31105796c8dcSSimon Schubert 
31115796c8dcSSimon Schubert /* Return the base VMA address which should be subtracted from real addresses
31125796c8dcSSimon Schubert    when resolving @dtpoff relocation.
31135796c8dcSSimon Schubert    This is PT_TLS segment p_vaddr.  */
31145796c8dcSSimon Schubert 
31155796c8dcSSimon Schubert static bfd_vma
elf_x86_64_dtpoff_base(struct bfd_link_info * info)3116c50c785cSJohn Marino elf_x86_64_dtpoff_base (struct bfd_link_info *info)
31175796c8dcSSimon Schubert {
31185796c8dcSSimon Schubert   /* If tls_sec is NULL, we should have signalled an error already.  */
31195796c8dcSSimon Schubert   if (elf_hash_table (info)->tls_sec == NULL)
31205796c8dcSSimon Schubert     return 0;
31215796c8dcSSimon Schubert   return elf_hash_table (info)->tls_sec->vma;
31225796c8dcSSimon Schubert }
31235796c8dcSSimon Schubert 
31245796c8dcSSimon Schubert /* Return the relocation value for @tpoff relocation
31255796c8dcSSimon Schubert    if STT_TLS virtual address is ADDRESS.  */
31265796c8dcSSimon Schubert 
31275796c8dcSSimon Schubert static bfd_vma
elf_x86_64_tpoff(struct bfd_link_info * info,bfd_vma address)3128c50c785cSJohn Marino elf_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address)
31295796c8dcSSimon Schubert {
31305796c8dcSSimon Schubert   struct elf_link_hash_table *htab = elf_hash_table (info);
3131c50c785cSJohn Marino   const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
3132c50c785cSJohn Marino   bfd_vma static_tls_size;
31335796c8dcSSimon Schubert 
31345796c8dcSSimon Schubert   /* If tls_segment is NULL, we should have signalled an error already.  */
31355796c8dcSSimon Schubert   if (htab->tls_sec == NULL)
31365796c8dcSSimon Schubert     return 0;
3137c50c785cSJohn Marino 
3138c50c785cSJohn Marino   /* Consider special static TLS alignment requirements.  */
3139c50c785cSJohn Marino   static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment);
3140c50c785cSJohn Marino   return address - static_tls_size - htab->tls_sec->vma;
31415796c8dcSSimon Schubert }
31425796c8dcSSimon Schubert 
31435796c8dcSSimon Schubert /* Is the instruction before OFFSET in CONTENTS a 32bit relative
31445796c8dcSSimon Schubert    branch?  */
31455796c8dcSSimon Schubert 
31465796c8dcSSimon Schubert static bfd_boolean
is_32bit_relative_branch(bfd_byte * contents,bfd_vma offset)31475796c8dcSSimon Schubert is_32bit_relative_branch (bfd_byte *contents, bfd_vma offset)
31485796c8dcSSimon Schubert {
31495796c8dcSSimon Schubert   /* Opcode		Instruction
31505796c8dcSSimon Schubert      0xe8		call
31515796c8dcSSimon Schubert      0xe9		jump
31525796c8dcSSimon Schubert      0x0f 0x8x		conditional jump */
31535796c8dcSSimon Schubert   return ((offset > 0
31545796c8dcSSimon Schubert 	   && (contents [offset - 1] == 0xe8
31555796c8dcSSimon Schubert 	       || contents [offset - 1] == 0xe9))
31565796c8dcSSimon Schubert 	  || (offset > 1
31575796c8dcSSimon Schubert 	      && contents [offset - 2] == 0x0f
31585796c8dcSSimon Schubert 	      && (contents [offset - 1] & 0xf0) == 0x80));
31595796c8dcSSimon Schubert }
31605796c8dcSSimon Schubert 
31615796c8dcSSimon Schubert /* Relocate an x86_64 ELF section.  */
31625796c8dcSSimon Schubert 
31635796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_relocate_section(bfd * output_bfd,struct bfd_link_info * info,bfd * input_bfd,asection * input_section,bfd_byte * contents,Elf_Internal_Rela * relocs,Elf_Internal_Sym * local_syms,asection ** local_sections)3164c50c785cSJohn Marino elf_x86_64_relocate_section (bfd *output_bfd,
3165c50c785cSJohn Marino 			     struct bfd_link_info *info,
3166c50c785cSJohn Marino 			     bfd *input_bfd,
3167c50c785cSJohn Marino 			     asection *input_section,
3168c50c785cSJohn Marino 			     bfd_byte *contents,
3169c50c785cSJohn Marino 			     Elf_Internal_Rela *relocs,
31705796c8dcSSimon Schubert 			     Elf_Internal_Sym *local_syms,
31715796c8dcSSimon Schubert 			     asection **local_sections)
31725796c8dcSSimon Schubert {
3173c50c785cSJohn Marino   struct elf_x86_64_link_hash_table *htab;
31745796c8dcSSimon Schubert   Elf_Internal_Shdr *symtab_hdr;
31755796c8dcSSimon Schubert   struct elf_link_hash_entry **sym_hashes;
31765796c8dcSSimon Schubert   bfd_vma *local_got_offsets;
31775796c8dcSSimon Schubert   bfd_vma *local_tlsdesc_gotents;
31785796c8dcSSimon Schubert   Elf_Internal_Rela *rel;
31795796c8dcSSimon Schubert   Elf_Internal_Rela *relend;
3180*ef5ccd6cSJohn Marino   const unsigned int plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
31815796c8dcSSimon Schubert 
31825796c8dcSSimon Schubert   BFD_ASSERT (is_x86_64_elf (input_bfd));
31835796c8dcSSimon Schubert 
3184c50c785cSJohn Marino   htab = elf_x86_64_hash_table (info);
3185cf7f2e2dSJohn Marino   if (htab == NULL)
3186cf7f2e2dSJohn Marino     return FALSE;
31875796c8dcSSimon Schubert   symtab_hdr = &elf_symtab_hdr (input_bfd);
31885796c8dcSSimon Schubert   sym_hashes = elf_sym_hashes (input_bfd);
31895796c8dcSSimon Schubert   local_got_offsets = elf_local_got_offsets (input_bfd);
3190c50c785cSJohn Marino   local_tlsdesc_gotents = elf_x86_64_local_tlsdesc_gotent (input_bfd);
31915796c8dcSSimon Schubert 
3192c50c785cSJohn Marino   elf_x86_64_set_tls_module_base (info);
31935796c8dcSSimon Schubert 
31945796c8dcSSimon Schubert   rel = relocs;
31955796c8dcSSimon Schubert   relend = relocs + input_section->reloc_count;
31965796c8dcSSimon Schubert   for (; rel < relend; rel++)
31975796c8dcSSimon Schubert     {
31985796c8dcSSimon Schubert       unsigned int r_type;
31995796c8dcSSimon Schubert       reloc_howto_type *howto;
32005796c8dcSSimon Schubert       unsigned long r_symndx;
32015796c8dcSSimon Schubert       struct elf_link_hash_entry *h;
32025796c8dcSSimon Schubert       Elf_Internal_Sym *sym;
32035796c8dcSSimon Schubert       asection *sec;
32045796c8dcSSimon Schubert       bfd_vma off, offplt;
32055796c8dcSSimon Schubert       bfd_vma relocation;
32065796c8dcSSimon Schubert       bfd_boolean unresolved_reloc;
32075796c8dcSSimon Schubert       bfd_reloc_status_type r;
32085796c8dcSSimon Schubert       int tls_type;
32095796c8dcSSimon Schubert       asection *base_got;
3210*ef5ccd6cSJohn Marino       bfd_vma st_size;
32115796c8dcSSimon Schubert 
3212c50c785cSJohn Marino       r_type = ELF32_R_TYPE (rel->r_info);
32135796c8dcSSimon Schubert       if (r_type == (int) R_X86_64_GNU_VTINHERIT
32145796c8dcSSimon Schubert 	  || r_type == (int) R_X86_64_GNU_VTENTRY)
32155796c8dcSSimon Schubert 	continue;
32165796c8dcSSimon Schubert 
3217*ef5ccd6cSJohn Marino       if (r_type >= (int) R_X86_64_standard)
32185796c8dcSSimon Schubert 	{
3219*ef5ccd6cSJohn Marino 	  (*_bfd_error_handler)
3220*ef5ccd6cSJohn Marino 	    (_("%B: unrecognized relocation (0x%x) in section `%A'"),
3221*ef5ccd6cSJohn Marino 	     input_bfd, input_section, r_type);
32225796c8dcSSimon Schubert 	  bfd_set_error (bfd_error_bad_value);
32235796c8dcSSimon Schubert 	  return FALSE;
32245796c8dcSSimon Schubert 	}
32255796c8dcSSimon Schubert 
3226a45ae5f8SJohn Marino       if (r_type != (int) R_X86_64_32
3227a45ae5f8SJohn Marino 	  || ABI_64_P (output_bfd))
32285796c8dcSSimon Schubert 	howto = x86_64_elf_howto_table + r_type;
3229a45ae5f8SJohn Marino       else
3230a45ae5f8SJohn Marino 	howto = (x86_64_elf_howto_table
3231a45ae5f8SJohn Marino 		 + ARRAY_SIZE (x86_64_elf_howto_table) - 1);
3232c50c785cSJohn Marino       r_symndx = htab->r_sym (rel->r_info);
32335796c8dcSSimon Schubert       h = NULL;
32345796c8dcSSimon Schubert       sym = NULL;
32355796c8dcSSimon Schubert       sec = NULL;
32365796c8dcSSimon Schubert       unresolved_reloc = FALSE;
32375796c8dcSSimon Schubert       if (r_symndx < symtab_hdr->sh_info)
32385796c8dcSSimon Schubert 	{
32395796c8dcSSimon Schubert 	  sym = local_syms + r_symndx;
32405796c8dcSSimon Schubert 	  sec = local_sections[r_symndx];
32415796c8dcSSimon Schubert 
32425796c8dcSSimon Schubert 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym,
32435796c8dcSSimon Schubert 						&sec, rel);
3244*ef5ccd6cSJohn Marino 	  st_size = sym->st_size;
32455796c8dcSSimon Schubert 
32465796c8dcSSimon Schubert 	  /* Relocate against local STT_GNU_IFUNC symbol.  */
32475796c8dcSSimon Schubert 	  if (!info->relocatable
3248c50c785cSJohn Marino 	      && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
32495796c8dcSSimon Schubert 	    {
3250c50c785cSJohn Marino 	      h = elf_x86_64_get_local_sym_hash (htab, input_bfd,
32515796c8dcSSimon Schubert 						 rel, FALSE);
32525796c8dcSSimon Schubert 	      if (h == NULL)
32535796c8dcSSimon Schubert 		abort ();
32545796c8dcSSimon Schubert 
32555796c8dcSSimon Schubert 	      /* Set STT_GNU_IFUNC symbol value.  */
32565796c8dcSSimon Schubert 	      h->root.u.def.value = sym->st_value;
32575796c8dcSSimon Schubert 	      h->root.u.def.section = sec;
32585796c8dcSSimon Schubert 	    }
32595796c8dcSSimon Schubert 	}
32605796c8dcSSimon Schubert       else
32615796c8dcSSimon Schubert 	{
3262cf7f2e2dSJohn Marino 	  bfd_boolean warned ATTRIBUTE_UNUSED;
32635796c8dcSSimon Schubert 
32645796c8dcSSimon Schubert 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
32655796c8dcSSimon Schubert 				   r_symndx, symtab_hdr, sym_hashes,
32665796c8dcSSimon Schubert 				   h, sec, relocation,
32675796c8dcSSimon Schubert 				   unresolved_reloc, warned);
3268*ef5ccd6cSJohn Marino 	  st_size = h->size;
32695796c8dcSSimon Schubert 	}
32705796c8dcSSimon Schubert 
3271*ef5ccd6cSJohn Marino       if (sec != NULL && discarded_section (sec))
3272cf7f2e2dSJohn Marino 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
3273*ef5ccd6cSJohn Marino 					 rel, 1, relend, howto, 0, contents);
32745796c8dcSSimon Schubert 
32755796c8dcSSimon Schubert       if (info->relocatable)
32765796c8dcSSimon Schubert 	continue;
32775796c8dcSSimon Schubert 
3278*ef5ccd6cSJohn Marino       if (rel->r_addend == 0 && !ABI_64_P (output_bfd))
3279a45ae5f8SJohn Marino 	{
3280*ef5ccd6cSJohn Marino 	  if (r_type == R_X86_64_64)
3281*ef5ccd6cSJohn Marino 	    {
3282*ef5ccd6cSJohn Marino 	      /* For x32, treat R_X86_64_64 like R_X86_64_32 and
3283*ef5ccd6cSJohn Marino 		 zero-extend it to 64bit if addend is zero.  */
3284a45ae5f8SJohn Marino 	      r_type = R_X86_64_32;
3285a45ae5f8SJohn Marino 	      memset (contents + rel->r_offset + 4, 0, 4);
3286a45ae5f8SJohn Marino 	    }
3287*ef5ccd6cSJohn Marino 	  else if (r_type == R_X86_64_SIZE64)
3288*ef5ccd6cSJohn Marino 	    {
3289*ef5ccd6cSJohn Marino 	      /* For x32, treat R_X86_64_SIZE64 like R_X86_64_SIZE32 and
3290*ef5ccd6cSJohn Marino 		 zero-extend it to 64bit if addend is zero.  */
3291*ef5ccd6cSJohn Marino 	      r_type = R_X86_64_SIZE32;
3292*ef5ccd6cSJohn Marino 	      memset (contents + rel->r_offset + 4, 0, 4);
3293*ef5ccd6cSJohn Marino 	    }
3294*ef5ccd6cSJohn Marino 	}
3295a45ae5f8SJohn Marino 
32965796c8dcSSimon Schubert       /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
32975796c8dcSSimon Schubert 	 it here if it is defined in a non-shared object.  */
32985796c8dcSSimon Schubert       if (h != NULL
32995796c8dcSSimon Schubert 	  && h->type == STT_GNU_IFUNC
33005796c8dcSSimon Schubert 	  && h->def_regular)
33015796c8dcSSimon Schubert 	{
33025796c8dcSSimon Schubert 	  asection *plt;
33035796c8dcSSimon Schubert 	  bfd_vma plt_index;
33045796c8dcSSimon Schubert 	  const char *name;
33055796c8dcSSimon Schubert 
33065796c8dcSSimon Schubert 	  if ((input_section->flags & SEC_ALLOC) == 0
33075796c8dcSSimon Schubert 	      || h->plt.offset == (bfd_vma) -1)
33085796c8dcSSimon Schubert 	    abort ();
33095796c8dcSSimon Schubert 
33105796c8dcSSimon Schubert 	  /* STT_GNU_IFUNC symbol must go through PLT.  */
33115796c8dcSSimon Schubert 	  plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
33125796c8dcSSimon Schubert 	  relocation = (plt->output_section->vma
33135796c8dcSSimon Schubert 			+ plt->output_offset + h->plt.offset);
33145796c8dcSSimon Schubert 
33155796c8dcSSimon Schubert 	  switch (r_type)
33165796c8dcSSimon Schubert 	    {
33175796c8dcSSimon Schubert 	    default:
33185796c8dcSSimon Schubert 	      if (h->root.root.string)
33195796c8dcSSimon Schubert 		name = h->root.root.string;
33205796c8dcSSimon Schubert 	      else
33215796c8dcSSimon Schubert 		name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
33225796c8dcSSimon Schubert 					 NULL);
33235796c8dcSSimon Schubert 	      (*_bfd_error_handler)
33245796c8dcSSimon Schubert 		(_("%B: relocation %s against STT_GNU_IFUNC "
33255796c8dcSSimon Schubert 		   "symbol `%s' isn't handled by %s"), input_bfd,
33265796c8dcSSimon Schubert 		 x86_64_elf_howto_table[r_type].name,
33275796c8dcSSimon Schubert 		 name, __FUNCTION__);
33285796c8dcSSimon Schubert 	      bfd_set_error (bfd_error_bad_value);
33295796c8dcSSimon Schubert 	      return FALSE;
33305796c8dcSSimon Schubert 
33315796c8dcSSimon Schubert 	    case R_X86_64_32S:
33325796c8dcSSimon Schubert 	      if (info->shared)
33335796c8dcSSimon Schubert 		abort ();
33345796c8dcSSimon Schubert 	      goto do_relocation;
33355796c8dcSSimon Schubert 
3336c50c785cSJohn Marino 	    case R_X86_64_32:
3337c50c785cSJohn Marino 	      if (ABI_64_P (output_bfd))
3338c50c785cSJohn Marino 		goto do_relocation;
3339c50c785cSJohn Marino 	      /* FALLTHROUGH */
33405796c8dcSSimon Schubert 	    case R_X86_64_64:
33415796c8dcSSimon Schubert 	      if (rel->r_addend != 0)
33425796c8dcSSimon Schubert 		{
33435796c8dcSSimon Schubert 		  if (h->root.root.string)
33445796c8dcSSimon Schubert 		    name = h->root.root.string;
33455796c8dcSSimon Schubert 		  else
33465796c8dcSSimon Schubert 		    name = bfd_elf_sym_name (input_bfd, symtab_hdr,
33475796c8dcSSimon Schubert 					     sym, NULL);
33485796c8dcSSimon Schubert 		  (*_bfd_error_handler)
33495796c8dcSSimon Schubert 		    (_("%B: relocation %s against STT_GNU_IFUNC "
33505796c8dcSSimon Schubert 		       "symbol `%s' has non-zero addend: %d"),
33515796c8dcSSimon Schubert 		     input_bfd, x86_64_elf_howto_table[r_type].name,
33525796c8dcSSimon Schubert 		     name, rel->r_addend);
33535796c8dcSSimon Schubert 		  bfd_set_error (bfd_error_bad_value);
33545796c8dcSSimon Schubert 		  return FALSE;
33555796c8dcSSimon Schubert 		}
33565796c8dcSSimon Schubert 
33575796c8dcSSimon Schubert 	      /* Generate dynamic relcoation only when there is a
3358a45ae5f8SJohn Marino 		 non-GOT reference in a shared object.  */
33595796c8dcSSimon Schubert 	      if (info->shared && h->non_got_ref)
33605796c8dcSSimon Schubert 		{
33615796c8dcSSimon Schubert 		  Elf_Internal_Rela outrel;
33625796c8dcSSimon Schubert 		  asection *sreloc;
33635796c8dcSSimon Schubert 
33645796c8dcSSimon Schubert 		  /* Need a dynamic relocation to get the real function
33655796c8dcSSimon Schubert 		     address.  */
33665796c8dcSSimon Schubert 		  outrel.r_offset = _bfd_elf_section_offset (output_bfd,
33675796c8dcSSimon Schubert 							     info,
33685796c8dcSSimon Schubert 							     input_section,
33695796c8dcSSimon Schubert 							     rel->r_offset);
33705796c8dcSSimon Schubert 		  if (outrel.r_offset == (bfd_vma) -1
33715796c8dcSSimon Schubert 		      || outrel.r_offset == (bfd_vma) -2)
33725796c8dcSSimon Schubert 		    abort ();
33735796c8dcSSimon Schubert 
33745796c8dcSSimon Schubert 		  outrel.r_offset += (input_section->output_section->vma
33755796c8dcSSimon Schubert 				      + input_section->output_offset);
33765796c8dcSSimon Schubert 
33775796c8dcSSimon Schubert 		  if (h->dynindx == -1
33785796c8dcSSimon Schubert 		      || h->forced_local
33795796c8dcSSimon Schubert 		      || info->executable)
33805796c8dcSSimon Schubert 		    {
33815796c8dcSSimon Schubert 		      /* This symbol is resolved locally.  */
3382*ef5ccd6cSJohn Marino 		      outrel.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
3383*ef5ccd6cSJohn Marino 		      outrel.r_addend = (h->root.u.def.value
3384*ef5ccd6cSJohn Marino 					 + h->root.u.def.section->output_section->vma
3385*ef5ccd6cSJohn Marino 					 + h->root.u.def.section->output_offset);
33865796c8dcSSimon Schubert 		    }
33875796c8dcSSimon Schubert 		  else
33885796c8dcSSimon Schubert 		    {
3389c50c785cSJohn Marino 		      outrel.r_info = htab->r_info (h->dynindx, r_type);
33905796c8dcSSimon Schubert 		      outrel.r_addend = 0;
33915796c8dcSSimon Schubert 		    }
33925796c8dcSSimon Schubert 
33935796c8dcSSimon Schubert 		  sreloc = htab->elf.irelifunc;
3394c50c785cSJohn Marino 		  elf_append_rela (output_bfd, sreloc, &outrel);
33955796c8dcSSimon Schubert 
33965796c8dcSSimon Schubert 		  /* If this reloc is against an external symbol, we
33975796c8dcSSimon Schubert 		     do not want to fiddle with the addend.  Otherwise,
33985796c8dcSSimon Schubert 		     we need to include the symbol value so that it
33995796c8dcSSimon Schubert 		     becomes an addend for the dynamic reloc.  For an
34005796c8dcSSimon Schubert 		     internal symbol, we have updated addend.  */
34015796c8dcSSimon Schubert 		  continue;
34025796c8dcSSimon Schubert 		}
3403c50c785cSJohn Marino 	      /* FALLTHROUGH */
34045796c8dcSSimon Schubert 	    case R_X86_64_PC32:
34055796c8dcSSimon Schubert 	    case R_X86_64_PC64:
34065796c8dcSSimon Schubert 	    case R_X86_64_PLT32:
34075796c8dcSSimon Schubert 	      goto do_relocation;
34085796c8dcSSimon Schubert 
34095796c8dcSSimon Schubert 	    case R_X86_64_GOTPCREL:
34105796c8dcSSimon Schubert 	    case R_X86_64_GOTPCREL64:
34115796c8dcSSimon Schubert 	      base_got = htab->elf.sgot;
34125796c8dcSSimon Schubert 	      off = h->got.offset;
34135796c8dcSSimon Schubert 
34145796c8dcSSimon Schubert 	      if (base_got == NULL)
34155796c8dcSSimon Schubert 		abort ();
34165796c8dcSSimon Schubert 
34175796c8dcSSimon Schubert 	      if (off == (bfd_vma) -1)
34185796c8dcSSimon Schubert 		{
34195796c8dcSSimon Schubert 		  /* We can't use h->got.offset here to save state, or
34205796c8dcSSimon Schubert 		     even just remember the offset, as finish_dynamic_symbol
34215796c8dcSSimon Schubert 		     would use that as offset into .got.  */
34225796c8dcSSimon Schubert 
34235796c8dcSSimon Schubert 		  if (htab->elf.splt != NULL)
34245796c8dcSSimon Schubert 		    {
3425*ef5ccd6cSJohn Marino 		      plt_index = h->plt.offset / plt_entry_size - 1;
34265796c8dcSSimon Schubert 		      off = (plt_index + 3) * GOT_ENTRY_SIZE;
34275796c8dcSSimon Schubert 		      base_got = htab->elf.sgotplt;
34285796c8dcSSimon Schubert 		    }
34295796c8dcSSimon Schubert 		  else
34305796c8dcSSimon Schubert 		    {
3431*ef5ccd6cSJohn Marino 		      plt_index = h->plt.offset / plt_entry_size;
34325796c8dcSSimon Schubert 		      off = plt_index * GOT_ENTRY_SIZE;
34335796c8dcSSimon Schubert 		      base_got = htab->elf.igotplt;
34345796c8dcSSimon Schubert 		    }
34355796c8dcSSimon Schubert 
34365796c8dcSSimon Schubert 		  if (h->dynindx == -1
34375796c8dcSSimon Schubert 		      || h->forced_local
34385796c8dcSSimon Schubert 		      || info->symbolic)
34395796c8dcSSimon Schubert 		    {
34405796c8dcSSimon Schubert 		      /* This references the local defitionion.  We must
34415796c8dcSSimon Schubert 			 initialize this entry in the global offset table.
34425796c8dcSSimon Schubert 			 Since the offset must always be a multiple of 8,
34435796c8dcSSimon Schubert 			 we use the least significant bit to record
34445796c8dcSSimon Schubert 			 whether we have initialized it already.
34455796c8dcSSimon Schubert 
34465796c8dcSSimon Schubert 			 When doing a dynamic link, we create a .rela.got
34475796c8dcSSimon Schubert 			 relocation entry to initialize the value.  This
34485796c8dcSSimon Schubert 			 is done in the finish_dynamic_symbol routine.	 */
34495796c8dcSSimon Schubert 		      if ((off & 1) != 0)
34505796c8dcSSimon Schubert 			off &= ~1;
34515796c8dcSSimon Schubert 		      else
34525796c8dcSSimon Schubert 			{
34535796c8dcSSimon Schubert 			  bfd_put_64 (output_bfd, relocation,
34545796c8dcSSimon Schubert 				      base_got->contents + off);
34555796c8dcSSimon Schubert 			  /* Note that this is harmless for the GOTPLT64
34565796c8dcSSimon Schubert 			     case, as -1 | 1 still is -1.  */
34575796c8dcSSimon Schubert 			  h->got.offset |= 1;
34585796c8dcSSimon Schubert 			}
34595796c8dcSSimon Schubert 		    }
34605796c8dcSSimon Schubert 		}
34615796c8dcSSimon Schubert 
34625796c8dcSSimon Schubert 	      relocation = (base_got->output_section->vma
34635796c8dcSSimon Schubert 			    + base_got->output_offset + off);
34645796c8dcSSimon Schubert 
34655796c8dcSSimon Schubert 	      goto do_relocation;
34665796c8dcSSimon Schubert 	    }
34675796c8dcSSimon Schubert 	}
34685796c8dcSSimon Schubert 
34695796c8dcSSimon Schubert       /* When generating a shared object, the relocations handled here are
34705796c8dcSSimon Schubert 	 copied into the output file to be resolved at run time.  */
34715796c8dcSSimon Schubert       switch (r_type)
34725796c8dcSSimon Schubert 	{
34735796c8dcSSimon Schubert 	case R_X86_64_GOT32:
34745796c8dcSSimon Schubert 	case R_X86_64_GOT64:
34755796c8dcSSimon Schubert 	  /* Relocation is to the entry for this symbol in the global
34765796c8dcSSimon Schubert 	     offset table.  */
34775796c8dcSSimon Schubert 	case R_X86_64_GOTPCREL:
34785796c8dcSSimon Schubert 	case R_X86_64_GOTPCREL64:
34795796c8dcSSimon Schubert 	  /* Use global offset table entry as symbol value.  */
34805796c8dcSSimon Schubert 	case R_X86_64_GOTPLT64:
34815796c8dcSSimon Schubert 	  /* This is the same as GOT64 for relocation purposes, but
34825796c8dcSSimon Schubert 	     indicates the existence of a PLT entry.  The difficulty is,
34835796c8dcSSimon Schubert 	     that we must calculate the GOT slot offset from the PLT
34845796c8dcSSimon Schubert 	     offset, if this symbol got a PLT entry (it was global).
34855796c8dcSSimon Schubert 	     Additionally if it's computed from the PLT entry, then that
34865796c8dcSSimon Schubert 	     GOT offset is relative to .got.plt, not to .got.  */
34875796c8dcSSimon Schubert 	  base_got = htab->elf.sgot;
34885796c8dcSSimon Schubert 
34895796c8dcSSimon Schubert 	  if (htab->elf.sgot == NULL)
34905796c8dcSSimon Schubert 	    abort ();
34915796c8dcSSimon Schubert 
34925796c8dcSSimon Schubert 	  if (h != NULL)
34935796c8dcSSimon Schubert 	    {
34945796c8dcSSimon Schubert 	      bfd_boolean dyn;
34955796c8dcSSimon Schubert 
34965796c8dcSSimon Schubert 	      off = h->got.offset;
34975796c8dcSSimon Schubert 	      if (h->needs_plt
34985796c8dcSSimon Schubert 		  && h->plt.offset != (bfd_vma)-1
34995796c8dcSSimon Schubert 		  && off == (bfd_vma)-1)
35005796c8dcSSimon Schubert 		{
35015796c8dcSSimon Schubert 		  /* We can't use h->got.offset here to save
35025796c8dcSSimon Schubert 		     state, or even just remember the offset, as
35035796c8dcSSimon Schubert 		     finish_dynamic_symbol would use that as offset into
35045796c8dcSSimon Schubert 		     .got.  */
3505*ef5ccd6cSJohn Marino 		  bfd_vma plt_index = h->plt.offset / plt_entry_size - 1;
35065796c8dcSSimon Schubert 		  off = (plt_index + 3) * GOT_ENTRY_SIZE;
35075796c8dcSSimon Schubert 		  base_got = htab->elf.sgotplt;
35085796c8dcSSimon Schubert 		}
35095796c8dcSSimon Schubert 
35105796c8dcSSimon Schubert 	      dyn = htab->elf.dynamic_sections_created;
35115796c8dcSSimon Schubert 
35125796c8dcSSimon Schubert 	      if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
35135796c8dcSSimon Schubert 		  || (info->shared
35145796c8dcSSimon Schubert 		      && SYMBOL_REFERENCES_LOCAL (info, h))
35155796c8dcSSimon Schubert 		  || (ELF_ST_VISIBILITY (h->other)
35165796c8dcSSimon Schubert 		      && h->root.type == bfd_link_hash_undefweak))
35175796c8dcSSimon Schubert 		{
35185796c8dcSSimon Schubert 		  /* This is actually a static link, or it is a -Bsymbolic
35195796c8dcSSimon Schubert 		     link and the symbol is defined locally, or the symbol
35205796c8dcSSimon Schubert 		     was forced to be local because of a version file.	We
35215796c8dcSSimon Schubert 		     must initialize this entry in the global offset table.
35225796c8dcSSimon Schubert 		     Since the offset must always be a multiple of 8, we
35235796c8dcSSimon Schubert 		     use the least significant bit to record whether we
35245796c8dcSSimon Schubert 		     have initialized it already.
35255796c8dcSSimon Schubert 
35265796c8dcSSimon Schubert 		     When doing a dynamic link, we create a .rela.got
35275796c8dcSSimon Schubert 		     relocation entry to initialize the value.	This is
35285796c8dcSSimon Schubert 		     done in the finish_dynamic_symbol routine.	 */
35295796c8dcSSimon Schubert 		  if ((off & 1) != 0)
35305796c8dcSSimon Schubert 		    off &= ~1;
35315796c8dcSSimon Schubert 		  else
35325796c8dcSSimon Schubert 		    {
35335796c8dcSSimon Schubert 		      bfd_put_64 (output_bfd, relocation,
35345796c8dcSSimon Schubert 				  base_got->contents + off);
35355796c8dcSSimon Schubert 		      /* Note that this is harmless for the GOTPLT64 case,
35365796c8dcSSimon Schubert 			 as -1 | 1 still is -1.  */
35375796c8dcSSimon Schubert 		      h->got.offset |= 1;
35385796c8dcSSimon Schubert 		    }
35395796c8dcSSimon Schubert 		}
35405796c8dcSSimon Schubert 	      else
35415796c8dcSSimon Schubert 		unresolved_reloc = FALSE;
35425796c8dcSSimon Schubert 	    }
35435796c8dcSSimon Schubert 	  else
35445796c8dcSSimon Schubert 	    {
35455796c8dcSSimon Schubert 	      if (local_got_offsets == NULL)
35465796c8dcSSimon Schubert 		abort ();
35475796c8dcSSimon Schubert 
35485796c8dcSSimon Schubert 	      off = local_got_offsets[r_symndx];
35495796c8dcSSimon Schubert 
35505796c8dcSSimon Schubert 	      /* The offset must always be a multiple of 8.  We use
35515796c8dcSSimon Schubert 		 the least significant bit to record whether we have
35525796c8dcSSimon Schubert 		 already generated the necessary reloc.	 */
35535796c8dcSSimon Schubert 	      if ((off & 1) != 0)
35545796c8dcSSimon Schubert 		off &= ~1;
35555796c8dcSSimon Schubert 	      else
35565796c8dcSSimon Schubert 		{
35575796c8dcSSimon Schubert 		  bfd_put_64 (output_bfd, relocation,
35585796c8dcSSimon Schubert 			      base_got->contents + off);
35595796c8dcSSimon Schubert 
35605796c8dcSSimon Schubert 		  if (info->shared)
35615796c8dcSSimon Schubert 		    {
35625796c8dcSSimon Schubert 		      asection *s;
35635796c8dcSSimon Schubert 		      Elf_Internal_Rela outrel;
35645796c8dcSSimon Schubert 
35655796c8dcSSimon Schubert 		      /* We need to generate a R_X86_64_RELATIVE reloc
35665796c8dcSSimon Schubert 			 for the dynamic linker.  */
35675796c8dcSSimon Schubert 		      s = htab->elf.srelgot;
35685796c8dcSSimon Schubert 		      if (s == NULL)
35695796c8dcSSimon Schubert 			abort ();
35705796c8dcSSimon Schubert 
35715796c8dcSSimon Schubert 		      outrel.r_offset = (base_got->output_section->vma
35725796c8dcSSimon Schubert 					 + base_got->output_offset
35735796c8dcSSimon Schubert 					 + off);
3574c50c785cSJohn Marino 		      outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
35755796c8dcSSimon Schubert 		      outrel.r_addend = relocation;
3576c50c785cSJohn Marino 		      elf_append_rela (output_bfd, s, &outrel);
35775796c8dcSSimon Schubert 		    }
35785796c8dcSSimon Schubert 
35795796c8dcSSimon Schubert 		  local_got_offsets[r_symndx] |= 1;
35805796c8dcSSimon Schubert 		}
35815796c8dcSSimon Schubert 	    }
35825796c8dcSSimon Schubert 
35835796c8dcSSimon Schubert 	  if (off >= (bfd_vma) -2)
35845796c8dcSSimon Schubert 	    abort ();
35855796c8dcSSimon Schubert 
35865796c8dcSSimon Schubert 	  relocation = base_got->output_section->vma
35875796c8dcSSimon Schubert 		       + base_got->output_offset + off;
35885796c8dcSSimon Schubert 	  if (r_type != R_X86_64_GOTPCREL && r_type != R_X86_64_GOTPCREL64)
35895796c8dcSSimon Schubert 	    relocation -= htab->elf.sgotplt->output_section->vma
35905796c8dcSSimon Schubert 			  - htab->elf.sgotplt->output_offset;
35915796c8dcSSimon Schubert 
35925796c8dcSSimon Schubert 	  break;
35935796c8dcSSimon Schubert 
35945796c8dcSSimon Schubert 	case R_X86_64_GOTOFF64:
35955796c8dcSSimon Schubert 	  /* Relocation is relative to the start of the global offset
35965796c8dcSSimon Schubert 	     table.  */
35975796c8dcSSimon Schubert 
35985796c8dcSSimon Schubert 	  /* Check to make sure it isn't a protected function symbol
35995796c8dcSSimon Schubert 	     for shared library since it may not be local when used
36005796c8dcSSimon Schubert 	     as function address.  */
3601*ef5ccd6cSJohn Marino 	  if (!info->executable
36025796c8dcSSimon Schubert 	      && h
3603*ef5ccd6cSJohn Marino 	      && !SYMBOLIC_BIND (info, h)
36045796c8dcSSimon Schubert 	      && h->def_regular
36055796c8dcSSimon Schubert 	      && h->type == STT_FUNC
36065796c8dcSSimon Schubert 	      && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
36075796c8dcSSimon Schubert 	    {
36085796c8dcSSimon Schubert 	      (*_bfd_error_handler)
36095796c8dcSSimon Schubert 		(_("%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"),
36105796c8dcSSimon Schubert 		 input_bfd, h->root.root.string);
36115796c8dcSSimon Schubert 	      bfd_set_error (bfd_error_bad_value);
36125796c8dcSSimon Schubert 	      return FALSE;
36135796c8dcSSimon Schubert 	    }
36145796c8dcSSimon Schubert 
36155796c8dcSSimon Schubert 	  /* Note that sgot is not involved in this
36165796c8dcSSimon Schubert 	     calculation.  We always want the start of .got.plt.  If we
36175796c8dcSSimon Schubert 	     defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
36185796c8dcSSimon Schubert 	     permitted by the ABI, we might have to change this
36195796c8dcSSimon Schubert 	     calculation.  */
36205796c8dcSSimon Schubert 	  relocation -= htab->elf.sgotplt->output_section->vma
36215796c8dcSSimon Schubert 			+ htab->elf.sgotplt->output_offset;
36225796c8dcSSimon Schubert 	  break;
36235796c8dcSSimon Schubert 
36245796c8dcSSimon Schubert 	case R_X86_64_GOTPC32:
36255796c8dcSSimon Schubert 	case R_X86_64_GOTPC64:
36265796c8dcSSimon Schubert 	  /* Use global offset table as symbol value.  */
36275796c8dcSSimon Schubert 	  relocation = htab->elf.sgotplt->output_section->vma
36285796c8dcSSimon Schubert 		       + htab->elf.sgotplt->output_offset;
36295796c8dcSSimon Schubert 	  unresolved_reloc = FALSE;
36305796c8dcSSimon Schubert 	  break;
36315796c8dcSSimon Schubert 
36325796c8dcSSimon Schubert 	case R_X86_64_PLTOFF64:
36335796c8dcSSimon Schubert 	  /* Relocation is PLT entry relative to GOT.  For local
36345796c8dcSSimon Schubert 	     symbols it's the symbol itself relative to GOT.  */
36355796c8dcSSimon Schubert 	  if (h != NULL
36365796c8dcSSimon Schubert 	      /* See PLT32 handling.  */
36375796c8dcSSimon Schubert 	      && h->plt.offset != (bfd_vma) -1
36385796c8dcSSimon Schubert 	      && htab->elf.splt != NULL)
36395796c8dcSSimon Schubert 	    {
36405796c8dcSSimon Schubert 	      relocation = (htab->elf.splt->output_section->vma
36415796c8dcSSimon Schubert 			    + htab->elf.splt->output_offset
36425796c8dcSSimon Schubert 			    + h->plt.offset);
36435796c8dcSSimon Schubert 	      unresolved_reloc = FALSE;
36445796c8dcSSimon Schubert 	    }
36455796c8dcSSimon Schubert 
36465796c8dcSSimon Schubert 	  relocation -= htab->elf.sgotplt->output_section->vma
36475796c8dcSSimon Schubert 			+ htab->elf.sgotplt->output_offset;
36485796c8dcSSimon Schubert 	  break;
36495796c8dcSSimon Schubert 
36505796c8dcSSimon Schubert 	case R_X86_64_PLT32:
36515796c8dcSSimon Schubert 	  /* Relocation is to the entry for this symbol in the
36525796c8dcSSimon Schubert 	     procedure linkage table.  */
36535796c8dcSSimon Schubert 
36545796c8dcSSimon Schubert 	  /* Resolve a PLT32 reloc against a local symbol directly,
36555796c8dcSSimon Schubert 	     without using the procedure linkage table.	 */
36565796c8dcSSimon Schubert 	  if (h == NULL)
36575796c8dcSSimon Schubert 	    break;
36585796c8dcSSimon Schubert 
36595796c8dcSSimon Schubert 	  if (h->plt.offset == (bfd_vma) -1
36605796c8dcSSimon Schubert 	      || htab->elf.splt == NULL)
36615796c8dcSSimon Schubert 	    {
36625796c8dcSSimon Schubert 	      /* We didn't make a PLT entry for this symbol.  This
36635796c8dcSSimon Schubert 		 happens when statically linking PIC code, or when
36645796c8dcSSimon Schubert 		 using -Bsymbolic.  */
36655796c8dcSSimon Schubert 	      break;
36665796c8dcSSimon Schubert 	    }
36675796c8dcSSimon Schubert 
36685796c8dcSSimon Schubert 	  relocation = (htab->elf.splt->output_section->vma
36695796c8dcSSimon Schubert 			+ htab->elf.splt->output_offset
36705796c8dcSSimon Schubert 			+ h->plt.offset);
36715796c8dcSSimon Schubert 	  unresolved_reloc = FALSE;
36725796c8dcSSimon Schubert 	  break;
36735796c8dcSSimon Schubert 
3674*ef5ccd6cSJohn Marino 	case R_X86_64_SIZE32:
3675*ef5ccd6cSJohn Marino 	case R_X86_64_SIZE64:
3676*ef5ccd6cSJohn Marino 	  /* Set to symbol size.  */
3677*ef5ccd6cSJohn Marino 	  relocation = st_size;
3678*ef5ccd6cSJohn Marino 	  goto direct;
3679*ef5ccd6cSJohn Marino 
36805796c8dcSSimon Schubert 	case R_X86_64_PC8:
36815796c8dcSSimon Schubert 	case R_X86_64_PC16:
36825796c8dcSSimon Schubert 	case R_X86_64_PC32:
36835796c8dcSSimon Schubert 	  if (info->shared
36845796c8dcSSimon Schubert 	      && (input_section->flags & SEC_ALLOC) != 0
36855796c8dcSSimon Schubert 	      && (input_section->flags & SEC_READONLY) != 0
36865796c8dcSSimon Schubert 	      && h != NULL)
36875796c8dcSSimon Schubert 	    {
36885796c8dcSSimon Schubert 	      bfd_boolean fail = FALSE;
36895796c8dcSSimon Schubert 	      bfd_boolean branch
36905796c8dcSSimon Schubert 		= (r_type == R_X86_64_PC32
36915796c8dcSSimon Schubert 		   && is_32bit_relative_branch (contents, rel->r_offset));
36925796c8dcSSimon Schubert 
36935796c8dcSSimon Schubert 	      if (SYMBOL_REFERENCES_LOCAL (info, h))
36945796c8dcSSimon Schubert 		{
36955796c8dcSSimon Schubert 		  /* Symbol is referenced locally.  Make sure it is
36965796c8dcSSimon Schubert 		     defined locally or for a branch.  */
36975796c8dcSSimon Schubert 		  fail = !h->def_regular && !branch;
36985796c8dcSSimon Schubert 		}
36995796c8dcSSimon Schubert 	      else
37005796c8dcSSimon Schubert 		{
37015796c8dcSSimon Schubert 		  /* Symbol isn't referenced locally.  We only allow
37025796c8dcSSimon Schubert 		     branch to symbol with non-default visibility. */
37035796c8dcSSimon Schubert 		  fail = (!branch
37045796c8dcSSimon Schubert 			  || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT);
37055796c8dcSSimon Schubert 		}
37065796c8dcSSimon Schubert 
37075796c8dcSSimon Schubert 	      if (fail)
37085796c8dcSSimon Schubert 		{
37095796c8dcSSimon Schubert 		  const char *fmt;
37105796c8dcSSimon Schubert 		  const char *v;
37115796c8dcSSimon Schubert 		  const char *pic = "";
37125796c8dcSSimon Schubert 
37135796c8dcSSimon Schubert 		  switch (ELF_ST_VISIBILITY (h->other))
37145796c8dcSSimon Schubert 		    {
37155796c8dcSSimon Schubert 		    case STV_HIDDEN:
37165796c8dcSSimon Schubert 		      v = _("hidden symbol");
37175796c8dcSSimon Schubert 		      break;
37185796c8dcSSimon Schubert 		    case STV_INTERNAL:
37195796c8dcSSimon Schubert 		      v = _("internal symbol");
37205796c8dcSSimon Schubert 		      break;
37215796c8dcSSimon Schubert 		    case STV_PROTECTED:
37225796c8dcSSimon Schubert 		      v = _("protected symbol");
37235796c8dcSSimon Schubert 		      break;
37245796c8dcSSimon Schubert 		    default:
37255796c8dcSSimon Schubert 		      v = _("symbol");
37265796c8dcSSimon Schubert 		      pic = _("; recompile with -fPIC");
37275796c8dcSSimon Schubert 		      break;
37285796c8dcSSimon Schubert 		    }
37295796c8dcSSimon Schubert 
37305796c8dcSSimon Schubert 		  if (h->def_regular)
37315796c8dcSSimon Schubert 		    fmt = _("%B: relocation %s against %s `%s' can not be used when making a shared object%s");
37325796c8dcSSimon Schubert 		  else
37335796c8dcSSimon Schubert 		    fmt = _("%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s");
37345796c8dcSSimon Schubert 
37355796c8dcSSimon Schubert 		  (*_bfd_error_handler) (fmt, input_bfd,
37365796c8dcSSimon Schubert 					 x86_64_elf_howto_table[r_type].name,
37375796c8dcSSimon Schubert 					 v,  h->root.root.string, pic);
37385796c8dcSSimon Schubert 		  bfd_set_error (bfd_error_bad_value);
37395796c8dcSSimon Schubert 		  return FALSE;
37405796c8dcSSimon Schubert 		}
37415796c8dcSSimon Schubert 	    }
37425796c8dcSSimon Schubert 	  /* Fall through.  */
37435796c8dcSSimon Schubert 
37445796c8dcSSimon Schubert 	case R_X86_64_8:
37455796c8dcSSimon Schubert 	case R_X86_64_16:
37465796c8dcSSimon Schubert 	case R_X86_64_32:
37475796c8dcSSimon Schubert 	case R_X86_64_PC64:
37485796c8dcSSimon Schubert 	case R_X86_64_64:
37495796c8dcSSimon Schubert 	  /* FIXME: The ABI says the linker should make sure the value is
37505796c8dcSSimon Schubert 	     the same when it's zeroextended to 64 bit.	 */
37515796c8dcSSimon Schubert 
3752*ef5ccd6cSJohn Marino direct:
37535796c8dcSSimon Schubert 	  if ((input_section->flags & SEC_ALLOC) == 0)
37545796c8dcSSimon Schubert 	    break;
37555796c8dcSSimon Schubert 
37565796c8dcSSimon Schubert 	  if ((info->shared
37575796c8dcSSimon Schubert 	       && (h == NULL
37585796c8dcSSimon Schubert 		   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
37595796c8dcSSimon Schubert 		   || h->root.type != bfd_link_hash_undefweak)
3760*ef5ccd6cSJohn Marino 	       && ((! IS_X86_64_PCREL_TYPE (r_type)
3761*ef5ccd6cSJohn Marino 		      && r_type != R_X86_64_SIZE32
3762*ef5ccd6cSJohn Marino 		      && r_type != R_X86_64_SIZE64)
37635796c8dcSSimon Schubert 		   || ! SYMBOL_CALLS_LOCAL (info, h)))
37645796c8dcSSimon Schubert 	      || (ELIMINATE_COPY_RELOCS
37655796c8dcSSimon Schubert 		  && !info->shared
37665796c8dcSSimon Schubert 		  && h != NULL
37675796c8dcSSimon Schubert 		  && h->dynindx != -1
37685796c8dcSSimon Schubert 		  && !h->non_got_ref
37695796c8dcSSimon Schubert 		  && ((h->def_dynamic
37705796c8dcSSimon Schubert 		       && !h->def_regular)
37715796c8dcSSimon Schubert 		      || h->root.type == bfd_link_hash_undefweak
37725796c8dcSSimon Schubert 		      || h->root.type == bfd_link_hash_undefined)))
37735796c8dcSSimon Schubert 	    {
37745796c8dcSSimon Schubert 	      Elf_Internal_Rela outrel;
37755796c8dcSSimon Schubert 	      bfd_boolean skip, relocate;
37765796c8dcSSimon Schubert 	      asection *sreloc;
37775796c8dcSSimon Schubert 
37785796c8dcSSimon Schubert 	      /* When generating a shared object, these relocations
37795796c8dcSSimon Schubert 		 are copied into the output file to be resolved at run
37805796c8dcSSimon Schubert 		 time.	*/
37815796c8dcSSimon Schubert 	      skip = FALSE;
37825796c8dcSSimon Schubert 	      relocate = FALSE;
37835796c8dcSSimon Schubert 
37845796c8dcSSimon Schubert 	      outrel.r_offset =
37855796c8dcSSimon Schubert 		_bfd_elf_section_offset (output_bfd, info, input_section,
37865796c8dcSSimon Schubert 					 rel->r_offset);
37875796c8dcSSimon Schubert 	      if (outrel.r_offset == (bfd_vma) -1)
37885796c8dcSSimon Schubert 		skip = TRUE;
37895796c8dcSSimon Schubert 	      else if (outrel.r_offset == (bfd_vma) -2)
37905796c8dcSSimon Schubert 		skip = TRUE, relocate = TRUE;
37915796c8dcSSimon Schubert 
37925796c8dcSSimon Schubert 	      outrel.r_offset += (input_section->output_section->vma
37935796c8dcSSimon Schubert 				  + input_section->output_offset);
37945796c8dcSSimon Schubert 
37955796c8dcSSimon Schubert 	      if (skip)
37965796c8dcSSimon Schubert 		memset (&outrel, 0, sizeof outrel);
37975796c8dcSSimon Schubert 
37985796c8dcSSimon Schubert 	      /* h->dynindx may be -1 if this symbol was marked to
37995796c8dcSSimon Schubert 		 become local.  */
38005796c8dcSSimon Schubert 	      else if (h != NULL
38015796c8dcSSimon Schubert 		       && h->dynindx != -1
38025796c8dcSSimon Schubert 		       && (IS_X86_64_PCREL_TYPE (r_type)
38035796c8dcSSimon Schubert 			   || ! info->shared
38045796c8dcSSimon Schubert 			   || ! SYMBOLIC_BIND (info, h)
38055796c8dcSSimon Schubert 			   || ! h->def_regular))
38065796c8dcSSimon Schubert 		{
3807c50c785cSJohn Marino 		  outrel.r_info = htab->r_info (h->dynindx, r_type);
38085796c8dcSSimon Schubert 		  outrel.r_addend = rel->r_addend;
38095796c8dcSSimon Schubert 		}
38105796c8dcSSimon Schubert 	      else
38115796c8dcSSimon Schubert 		{
38125796c8dcSSimon Schubert 		  /* This symbol is local, or marked to become local.  */
3813c50c785cSJohn Marino 		  if (r_type == htab->pointer_r_type)
38145796c8dcSSimon Schubert 		    {
38155796c8dcSSimon Schubert 		      relocate = TRUE;
3816c50c785cSJohn Marino 		      outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
38175796c8dcSSimon Schubert 		      outrel.r_addend = relocation + rel->r_addend;
38185796c8dcSSimon Schubert 		    }
3819a45ae5f8SJohn Marino 		  else if (r_type == R_X86_64_64
3820a45ae5f8SJohn Marino 			   && !ABI_64_P (output_bfd))
3821a45ae5f8SJohn Marino 		    {
3822a45ae5f8SJohn Marino 		      relocate = TRUE;
3823a45ae5f8SJohn Marino 		      outrel.r_info = htab->r_info (0,
3824a45ae5f8SJohn Marino 						    R_X86_64_RELATIVE64);
3825a45ae5f8SJohn Marino 		      outrel.r_addend = relocation + rel->r_addend;
3826*ef5ccd6cSJohn Marino 		      /* Check addend overflow.  */
3827*ef5ccd6cSJohn Marino 		      if ((outrel.r_addend & 0x80000000)
3828*ef5ccd6cSJohn Marino 			  != (rel->r_addend & 0x80000000))
3829*ef5ccd6cSJohn Marino 			{
3830*ef5ccd6cSJohn Marino 			  const char *name;
3831*ef5ccd6cSJohn Marino 			  int addend = rel->r_addend;
3832*ef5ccd6cSJohn Marino 			  if (h && h->root.root.string)
3833*ef5ccd6cSJohn Marino 			    name = h->root.root.string;
3834*ef5ccd6cSJohn Marino 			  else
3835*ef5ccd6cSJohn Marino 			    name = bfd_elf_sym_name (input_bfd, symtab_hdr,
3836*ef5ccd6cSJohn Marino 						     sym, NULL);
3837*ef5ccd6cSJohn Marino 			  if (addend < 0)
3838*ef5ccd6cSJohn Marino 			    (*_bfd_error_handler)
3839*ef5ccd6cSJohn Marino 			      (_("%B: addend -0x%x in relocation %s against "
3840*ef5ccd6cSJohn Marino 				 "symbol `%s' at 0x%lx in section `%A' is "
3841*ef5ccd6cSJohn Marino 				 "out of range"),
3842*ef5ccd6cSJohn Marino 			       input_bfd, input_section, addend,
3843*ef5ccd6cSJohn Marino 			       x86_64_elf_howto_table[r_type].name,
3844*ef5ccd6cSJohn Marino 			       name, (unsigned long) rel->r_offset);
3845*ef5ccd6cSJohn Marino 			  else
3846*ef5ccd6cSJohn Marino 			    (*_bfd_error_handler)
3847*ef5ccd6cSJohn Marino 			      (_("%B: addend 0x%x in relocation %s against "
3848*ef5ccd6cSJohn Marino 				 "symbol `%s' at 0x%lx in section `%A' is "
3849*ef5ccd6cSJohn Marino 				 "out of range"),
3850*ef5ccd6cSJohn Marino 			       input_bfd, input_section, addend,
3851*ef5ccd6cSJohn Marino 			       x86_64_elf_howto_table[r_type].name,
3852*ef5ccd6cSJohn Marino 			       name, (unsigned long) rel->r_offset);
3853*ef5ccd6cSJohn Marino 			  bfd_set_error (bfd_error_bad_value);
3854*ef5ccd6cSJohn Marino 			  return FALSE;
3855*ef5ccd6cSJohn Marino 			}
3856a45ae5f8SJohn Marino 		    }
38575796c8dcSSimon Schubert 		  else
38585796c8dcSSimon Schubert 		    {
38595796c8dcSSimon Schubert 		      long sindx;
38605796c8dcSSimon Schubert 
38615796c8dcSSimon Schubert 		      if (bfd_is_abs_section (sec))
38625796c8dcSSimon Schubert 			sindx = 0;
38635796c8dcSSimon Schubert 		      else if (sec == NULL || sec->owner == NULL)
38645796c8dcSSimon Schubert 			{
38655796c8dcSSimon Schubert 			  bfd_set_error (bfd_error_bad_value);
38665796c8dcSSimon Schubert 			  return FALSE;
38675796c8dcSSimon Schubert 			}
38685796c8dcSSimon Schubert 		      else
38695796c8dcSSimon Schubert 			{
38705796c8dcSSimon Schubert 			  asection *osec;
38715796c8dcSSimon Schubert 
38725796c8dcSSimon Schubert 			  /* We are turning this relocation into one
38735796c8dcSSimon Schubert 			     against a section symbol.  It would be
38745796c8dcSSimon Schubert 			     proper to subtract the symbol's value,
38755796c8dcSSimon Schubert 			     osec->vma, from the emitted reloc addend,
38765796c8dcSSimon Schubert 			     but ld.so expects buggy relocs.  */
38775796c8dcSSimon Schubert 			  osec = sec->output_section;
38785796c8dcSSimon Schubert 			  sindx = elf_section_data (osec)->dynindx;
38795796c8dcSSimon Schubert 			  if (sindx == 0)
38805796c8dcSSimon Schubert 			    {
38815796c8dcSSimon Schubert 			      asection *oi = htab->elf.text_index_section;
38825796c8dcSSimon Schubert 			      sindx = elf_section_data (oi)->dynindx;
38835796c8dcSSimon Schubert 			    }
38845796c8dcSSimon Schubert 			  BFD_ASSERT (sindx != 0);
38855796c8dcSSimon Schubert 			}
38865796c8dcSSimon Schubert 
3887c50c785cSJohn Marino 		      outrel.r_info = htab->r_info (sindx, r_type);
38885796c8dcSSimon Schubert 		      outrel.r_addend = relocation + rel->r_addend;
38895796c8dcSSimon Schubert 		    }
38905796c8dcSSimon Schubert 		}
38915796c8dcSSimon Schubert 
38925796c8dcSSimon Schubert 	      sreloc = elf_section_data (input_section)->sreloc;
38935796c8dcSSimon Schubert 
3894a45ae5f8SJohn Marino 	      if (sreloc == NULL || sreloc->contents == NULL)
3895a45ae5f8SJohn Marino 		{
3896a45ae5f8SJohn Marino 		  r = bfd_reloc_notsupported;
3897a45ae5f8SJohn Marino 		  goto check_relocation_error;
3898a45ae5f8SJohn Marino 		}
38995796c8dcSSimon Schubert 
3900c50c785cSJohn Marino 	      elf_append_rela (output_bfd, sreloc, &outrel);
39015796c8dcSSimon Schubert 
39025796c8dcSSimon Schubert 	      /* If this reloc is against an external symbol, we do
39035796c8dcSSimon Schubert 		 not want to fiddle with the addend.  Otherwise, we
39045796c8dcSSimon Schubert 		 need to include the symbol value so that it becomes
39055796c8dcSSimon Schubert 		 an addend for the dynamic reloc.  */
39065796c8dcSSimon Schubert 	      if (! relocate)
39075796c8dcSSimon Schubert 		continue;
39085796c8dcSSimon Schubert 	    }
39095796c8dcSSimon Schubert 
39105796c8dcSSimon Schubert 	  break;
39115796c8dcSSimon Schubert 
39125796c8dcSSimon Schubert 	case R_X86_64_TLSGD:
39135796c8dcSSimon Schubert 	case R_X86_64_GOTPC32_TLSDESC:
39145796c8dcSSimon Schubert 	case R_X86_64_TLSDESC_CALL:
39155796c8dcSSimon Schubert 	case R_X86_64_GOTTPOFF:
39165796c8dcSSimon Schubert 	  tls_type = GOT_UNKNOWN;
39175796c8dcSSimon Schubert 	  if (h == NULL && local_got_offsets)
3918c50c785cSJohn Marino 	    tls_type = elf_x86_64_local_got_tls_type (input_bfd) [r_symndx];
39195796c8dcSSimon Schubert 	  else if (h != NULL)
3920c50c785cSJohn Marino 	    tls_type = elf_x86_64_hash_entry (h)->tls_type;
39215796c8dcSSimon Schubert 
3922c50c785cSJohn Marino 	  if (! elf_x86_64_tls_transition (info, input_bfd,
39235796c8dcSSimon Schubert 					   input_section, contents,
39245796c8dcSSimon Schubert 					   symtab_hdr, sym_hashes,
39255796c8dcSSimon Schubert 					   &r_type, tls_type, rel,
39265796c8dcSSimon Schubert 					   relend, h, r_symndx))
39275796c8dcSSimon Schubert 	    return FALSE;
39285796c8dcSSimon Schubert 
39295796c8dcSSimon Schubert 	  if (r_type == R_X86_64_TPOFF32)
39305796c8dcSSimon Schubert 	    {
39315796c8dcSSimon Schubert 	      bfd_vma roff = rel->r_offset;
39325796c8dcSSimon Schubert 
39335796c8dcSSimon Schubert 	      BFD_ASSERT (! unresolved_reloc);
39345796c8dcSSimon Schubert 
3935c50c785cSJohn Marino 	      if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
39365796c8dcSSimon Schubert 		{
3937c50c785cSJohn Marino 		  /* GD->LE transition.  For 64bit, change
39385796c8dcSSimon Schubert 		     .byte 0x66; leaq foo@tlsgd(%rip), %rdi
39395796c8dcSSimon Schubert 		     .word 0x6666; rex64; call __tls_get_addr
3940c50c785cSJohn Marino 		     into:
39415796c8dcSSimon Schubert 		     movq %fs:0, %rax
3942c50c785cSJohn Marino 		     leaq foo@tpoff(%rax), %rax
3943c50c785cSJohn Marino 		     For 32bit, change
3944c50c785cSJohn Marino 		     leaq foo@tlsgd(%rip), %rdi
3945c50c785cSJohn Marino 		     .word 0x6666; rex64; call __tls_get_addr
3946c50c785cSJohn Marino 		     into:
3947c50c785cSJohn Marino 		     movl %fs:0, %eax
39485796c8dcSSimon Schubert 		     leaq foo@tpoff(%rax), %rax */
3949c50c785cSJohn Marino 		  if (ABI_64_P (output_bfd))
39505796c8dcSSimon Schubert 		    memcpy (contents + roff - 4,
39515796c8dcSSimon Schubert 			    "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
39525796c8dcSSimon Schubert 			    16);
3953c50c785cSJohn Marino 		  else
3954c50c785cSJohn Marino 		    memcpy (contents + roff - 3,
3955c50c785cSJohn Marino 			    "\x64\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
3956c50c785cSJohn Marino 			    15);
39575796c8dcSSimon Schubert 		  bfd_put_32 (output_bfd,
3958c50c785cSJohn Marino 			      elf_x86_64_tpoff (info, relocation),
39595796c8dcSSimon Schubert 			      contents + roff + 8);
39605796c8dcSSimon Schubert 		  /* Skip R_X86_64_PC32/R_X86_64_PLT32.  */
39615796c8dcSSimon Schubert 		  rel++;
39625796c8dcSSimon Schubert 		  continue;
39635796c8dcSSimon Schubert 		}
3964c50c785cSJohn Marino 	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
39655796c8dcSSimon Schubert 		{
39665796c8dcSSimon Schubert 		  /* GDesc -> LE transition.
39675796c8dcSSimon Schubert 		     It's originally something like:
39685796c8dcSSimon Schubert 		     leaq x@tlsdesc(%rip), %rax
39695796c8dcSSimon Schubert 
39705796c8dcSSimon Schubert 		     Change it to:
3971cf7f2e2dSJohn Marino 		     movl $x@tpoff, %rax.  */
39725796c8dcSSimon Schubert 
3973cf7f2e2dSJohn Marino 		  unsigned int val, type;
39745796c8dcSSimon Schubert 
39755796c8dcSSimon Schubert 		  type = bfd_get_8 (input_bfd, contents + roff - 3);
39765796c8dcSSimon Schubert 		  val = bfd_get_8 (input_bfd, contents + roff - 1);
39775796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0x48 | ((type >> 2) & 1),
39785796c8dcSSimon Schubert 			     contents + roff - 3);
39795796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0xc7, contents + roff - 2);
39805796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
39815796c8dcSSimon Schubert 			     contents + roff - 1);
39825796c8dcSSimon Schubert 		  bfd_put_32 (output_bfd,
3983c50c785cSJohn Marino 			      elf_x86_64_tpoff (info, relocation),
39845796c8dcSSimon Schubert 			      contents + roff);
39855796c8dcSSimon Schubert 		  continue;
39865796c8dcSSimon Schubert 		}
3987c50c785cSJohn Marino 	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
39885796c8dcSSimon Schubert 		{
39895796c8dcSSimon Schubert 		  /* GDesc -> LE transition.
39905796c8dcSSimon Schubert 		     It's originally:
39915796c8dcSSimon Schubert 		     call *(%rax)
39925796c8dcSSimon Schubert 		     Turn it into:
39935796c8dcSSimon Schubert 		     xchg %ax,%ax.  */
39945796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0x66, contents + roff);
39955796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
39965796c8dcSSimon Schubert 		  continue;
39975796c8dcSSimon Schubert 		}
3998c50c785cSJohn Marino 	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTTPOFF)
39995796c8dcSSimon Schubert 		{
40005796c8dcSSimon Schubert 		  /* IE->LE transition:
40015796c8dcSSimon Schubert 		     Originally it can be one of:
40025796c8dcSSimon Schubert 		     movq foo@gottpoff(%rip), %reg
40035796c8dcSSimon Schubert 		     addq foo@gottpoff(%rip), %reg
40045796c8dcSSimon Schubert 		     We change it into:
40055796c8dcSSimon Schubert 		     movq $foo, %reg
40065796c8dcSSimon Schubert 		     leaq foo(%reg), %reg
40075796c8dcSSimon Schubert 		     addq $foo, %reg.  */
40085796c8dcSSimon Schubert 
40095796c8dcSSimon Schubert 		  unsigned int val, type, reg;
40105796c8dcSSimon Schubert 
40115796c8dcSSimon Schubert 		  val = bfd_get_8 (input_bfd, contents + roff - 3);
40125796c8dcSSimon Schubert 		  type = bfd_get_8 (input_bfd, contents + roff - 2);
40135796c8dcSSimon Schubert 		  reg = bfd_get_8 (input_bfd, contents + roff - 1);
40145796c8dcSSimon Schubert 		  reg >>= 3;
40155796c8dcSSimon Schubert 		  if (type == 0x8b)
40165796c8dcSSimon Schubert 		    {
40175796c8dcSSimon Schubert 		      /* movq */
40185796c8dcSSimon Schubert 		      if (val == 0x4c)
40195796c8dcSSimon Schubert 			bfd_put_8 (output_bfd, 0x49,
40205796c8dcSSimon Schubert 				   contents + roff - 3);
4021c50c785cSJohn Marino 		      else if (!ABI_64_P (output_bfd) && val == 0x44)
4022c50c785cSJohn Marino 			bfd_put_8 (output_bfd, 0x41,
4023c50c785cSJohn Marino 				   contents + roff - 3);
40245796c8dcSSimon Schubert 		      bfd_put_8 (output_bfd, 0xc7,
40255796c8dcSSimon Schubert 				 contents + roff - 2);
40265796c8dcSSimon Schubert 		      bfd_put_8 (output_bfd, 0xc0 | reg,
40275796c8dcSSimon Schubert 				 contents + roff - 1);
40285796c8dcSSimon Schubert 		    }
40295796c8dcSSimon Schubert 		  else if (reg == 4)
40305796c8dcSSimon Schubert 		    {
40315796c8dcSSimon Schubert 		      /* addq -> addq - addressing with %rsp/%r12 is
40325796c8dcSSimon Schubert 			 special  */
40335796c8dcSSimon Schubert 		      if (val == 0x4c)
40345796c8dcSSimon Schubert 			bfd_put_8 (output_bfd, 0x49,
40355796c8dcSSimon Schubert 				   contents + roff - 3);
4036c50c785cSJohn Marino 		      else if (!ABI_64_P (output_bfd) && val == 0x44)
4037c50c785cSJohn Marino 			bfd_put_8 (output_bfd, 0x41,
4038c50c785cSJohn Marino 				   contents + roff - 3);
40395796c8dcSSimon Schubert 		      bfd_put_8 (output_bfd, 0x81,
40405796c8dcSSimon Schubert 				 contents + roff - 2);
40415796c8dcSSimon Schubert 		      bfd_put_8 (output_bfd, 0xc0 | reg,
40425796c8dcSSimon Schubert 				 contents + roff - 1);
40435796c8dcSSimon Schubert 		    }
40445796c8dcSSimon Schubert 		  else
40455796c8dcSSimon Schubert 		    {
40465796c8dcSSimon Schubert 		      /* addq -> leaq */
40475796c8dcSSimon Schubert 		      if (val == 0x4c)
40485796c8dcSSimon Schubert 			bfd_put_8 (output_bfd, 0x4d,
40495796c8dcSSimon Schubert 				   contents + roff - 3);
4050c50c785cSJohn Marino 		      else if (!ABI_64_P (output_bfd) && val == 0x44)
4051c50c785cSJohn Marino 			bfd_put_8 (output_bfd, 0x45,
4052c50c785cSJohn Marino 				   contents + roff - 3);
40535796c8dcSSimon Schubert 		      bfd_put_8 (output_bfd, 0x8d,
40545796c8dcSSimon Schubert 				 contents + roff - 2);
40555796c8dcSSimon Schubert 		      bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3),
40565796c8dcSSimon Schubert 				 contents + roff - 1);
40575796c8dcSSimon Schubert 		    }
40585796c8dcSSimon Schubert 		  bfd_put_32 (output_bfd,
4059c50c785cSJohn Marino 			      elf_x86_64_tpoff (info, relocation),
40605796c8dcSSimon Schubert 			      contents + roff);
40615796c8dcSSimon Schubert 		  continue;
40625796c8dcSSimon Schubert 		}
40635796c8dcSSimon Schubert 	      else
40645796c8dcSSimon Schubert 		BFD_ASSERT (FALSE);
40655796c8dcSSimon Schubert 	    }
40665796c8dcSSimon Schubert 
40675796c8dcSSimon Schubert 	  if (htab->elf.sgot == NULL)
40685796c8dcSSimon Schubert 	    abort ();
40695796c8dcSSimon Schubert 
40705796c8dcSSimon Schubert 	  if (h != NULL)
40715796c8dcSSimon Schubert 	    {
40725796c8dcSSimon Schubert 	      off = h->got.offset;
4073c50c785cSJohn Marino 	      offplt = elf_x86_64_hash_entry (h)->tlsdesc_got;
40745796c8dcSSimon Schubert 	    }
40755796c8dcSSimon Schubert 	  else
40765796c8dcSSimon Schubert 	    {
40775796c8dcSSimon Schubert 	      if (local_got_offsets == NULL)
40785796c8dcSSimon Schubert 		abort ();
40795796c8dcSSimon Schubert 
40805796c8dcSSimon Schubert 	      off = local_got_offsets[r_symndx];
40815796c8dcSSimon Schubert 	      offplt = local_tlsdesc_gotents[r_symndx];
40825796c8dcSSimon Schubert 	    }
40835796c8dcSSimon Schubert 
40845796c8dcSSimon Schubert 	  if ((off & 1) != 0)
40855796c8dcSSimon Schubert 	    off &= ~1;
40865796c8dcSSimon Schubert 	  else
40875796c8dcSSimon Schubert 	    {
40885796c8dcSSimon Schubert 	      Elf_Internal_Rela outrel;
40895796c8dcSSimon Schubert 	      int dr_type, indx;
40905796c8dcSSimon Schubert 	      asection *sreloc;
40915796c8dcSSimon Schubert 
40925796c8dcSSimon Schubert 	      if (htab->elf.srelgot == NULL)
40935796c8dcSSimon Schubert 		abort ();
40945796c8dcSSimon Schubert 
40955796c8dcSSimon Schubert 	      indx = h && h->dynindx != -1 ? h->dynindx : 0;
40965796c8dcSSimon Schubert 
40975796c8dcSSimon Schubert 	      if (GOT_TLS_GDESC_P (tls_type))
40985796c8dcSSimon Schubert 		{
4099c50c785cSJohn Marino 		  outrel.r_info = htab->r_info (indx, R_X86_64_TLSDESC);
41005796c8dcSSimon Schubert 		  BFD_ASSERT (htab->sgotplt_jump_table_size + offplt
41015796c8dcSSimon Schubert 			      + 2 * GOT_ENTRY_SIZE <= htab->elf.sgotplt->size);
41025796c8dcSSimon Schubert 		  outrel.r_offset = (htab->elf.sgotplt->output_section->vma
41035796c8dcSSimon Schubert 				     + htab->elf.sgotplt->output_offset
41045796c8dcSSimon Schubert 				     + offplt
41055796c8dcSSimon Schubert 				     + htab->sgotplt_jump_table_size);
41065796c8dcSSimon Schubert 		  sreloc = htab->elf.srelplt;
41075796c8dcSSimon Schubert 		  if (indx == 0)
4108c50c785cSJohn Marino 		    outrel.r_addend = relocation - elf_x86_64_dtpoff_base (info);
41095796c8dcSSimon Schubert 		  else
41105796c8dcSSimon Schubert 		    outrel.r_addend = 0;
4111c50c785cSJohn Marino 		  elf_append_rela (output_bfd, sreloc, &outrel);
41125796c8dcSSimon Schubert 		}
41135796c8dcSSimon Schubert 
41145796c8dcSSimon Schubert 	      sreloc = htab->elf.srelgot;
41155796c8dcSSimon Schubert 
41165796c8dcSSimon Schubert 	      outrel.r_offset = (htab->elf.sgot->output_section->vma
41175796c8dcSSimon Schubert 				 + htab->elf.sgot->output_offset + off);
41185796c8dcSSimon Schubert 
41195796c8dcSSimon Schubert 	      if (GOT_TLS_GD_P (tls_type))
41205796c8dcSSimon Schubert 		dr_type = R_X86_64_DTPMOD64;
41215796c8dcSSimon Schubert 	      else if (GOT_TLS_GDESC_P (tls_type))
41225796c8dcSSimon Schubert 		goto dr_done;
41235796c8dcSSimon Schubert 	      else
41245796c8dcSSimon Schubert 		dr_type = R_X86_64_TPOFF64;
41255796c8dcSSimon Schubert 
41265796c8dcSSimon Schubert 	      bfd_put_64 (output_bfd, 0, htab->elf.sgot->contents + off);
41275796c8dcSSimon Schubert 	      outrel.r_addend = 0;
41285796c8dcSSimon Schubert 	      if ((dr_type == R_X86_64_TPOFF64
41295796c8dcSSimon Schubert 		   || dr_type == R_X86_64_TLSDESC) && indx == 0)
4130c50c785cSJohn Marino 		outrel.r_addend = relocation - elf_x86_64_dtpoff_base (info);
4131c50c785cSJohn Marino 	      outrel.r_info = htab->r_info (indx, dr_type);
41325796c8dcSSimon Schubert 
4133c50c785cSJohn Marino 	      elf_append_rela (output_bfd, sreloc, &outrel);
41345796c8dcSSimon Schubert 
41355796c8dcSSimon Schubert 	      if (GOT_TLS_GD_P (tls_type))
41365796c8dcSSimon Schubert 		{
41375796c8dcSSimon Schubert 		  if (indx == 0)
41385796c8dcSSimon Schubert 		    {
41395796c8dcSSimon Schubert 		      BFD_ASSERT (! unresolved_reloc);
41405796c8dcSSimon Schubert 		      bfd_put_64 (output_bfd,
4141c50c785cSJohn Marino 				  relocation - elf_x86_64_dtpoff_base (info),
41425796c8dcSSimon Schubert 				  htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
41435796c8dcSSimon Schubert 		    }
41445796c8dcSSimon Schubert 		  else
41455796c8dcSSimon Schubert 		    {
41465796c8dcSSimon Schubert 		      bfd_put_64 (output_bfd, 0,
41475796c8dcSSimon Schubert 				  htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
4148c50c785cSJohn Marino 		      outrel.r_info = htab->r_info (indx,
41495796c8dcSSimon Schubert 						    R_X86_64_DTPOFF64);
41505796c8dcSSimon Schubert 		      outrel.r_offset += GOT_ENTRY_SIZE;
4151c50c785cSJohn Marino 		      elf_append_rela (output_bfd, sreloc,
4152cf7f2e2dSJohn Marino 						&outrel);
41535796c8dcSSimon Schubert 		    }
41545796c8dcSSimon Schubert 		}
41555796c8dcSSimon Schubert 
41565796c8dcSSimon Schubert 	    dr_done:
41575796c8dcSSimon Schubert 	      if (h != NULL)
41585796c8dcSSimon Schubert 		h->got.offset |= 1;
41595796c8dcSSimon Schubert 	      else
41605796c8dcSSimon Schubert 		local_got_offsets[r_symndx] |= 1;
41615796c8dcSSimon Schubert 	    }
41625796c8dcSSimon Schubert 
41635796c8dcSSimon Schubert 	  if (off >= (bfd_vma) -2
41645796c8dcSSimon Schubert 	      && ! GOT_TLS_GDESC_P (tls_type))
41655796c8dcSSimon Schubert 	    abort ();
4166c50c785cSJohn Marino 	  if (r_type == ELF32_R_TYPE (rel->r_info))
41675796c8dcSSimon Schubert 	    {
41685796c8dcSSimon Schubert 	      if (r_type == R_X86_64_GOTPC32_TLSDESC
41695796c8dcSSimon Schubert 		  || r_type == R_X86_64_TLSDESC_CALL)
41705796c8dcSSimon Schubert 		relocation = htab->elf.sgotplt->output_section->vma
41715796c8dcSSimon Schubert 		  + htab->elf.sgotplt->output_offset
41725796c8dcSSimon Schubert 		  + offplt + htab->sgotplt_jump_table_size;
41735796c8dcSSimon Schubert 	      else
41745796c8dcSSimon Schubert 		relocation = htab->elf.sgot->output_section->vma
41755796c8dcSSimon Schubert 		  + htab->elf.sgot->output_offset + off;
41765796c8dcSSimon Schubert 	      unresolved_reloc = FALSE;
41775796c8dcSSimon Schubert 	    }
41785796c8dcSSimon Schubert 	  else
41795796c8dcSSimon Schubert 	    {
41805796c8dcSSimon Schubert 	      bfd_vma roff = rel->r_offset;
41815796c8dcSSimon Schubert 
4182c50c785cSJohn Marino 	      if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
41835796c8dcSSimon Schubert 		{
4184c50c785cSJohn Marino 		  /* GD->IE transition.  For 64bit, change
41855796c8dcSSimon Schubert 		     .byte 0x66; leaq foo@tlsgd(%rip), %rdi
41865796c8dcSSimon Schubert 		     .word 0x6666; rex64; call __tls_get_addr@plt
4187c50c785cSJohn Marino 		     into:
41885796c8dcSSimon Schubert 		     movq %fs:0, %rax
4189c50c785cSJohn Marino 		     addq foo@gottpoff(%rip), %rax
4190c50c785cSJohn Marino 		     For 32bit, change
4191c50c785cSJohn Marino 		     leaq foo@tlsgd(%rip), %rdi
4192c50c785cSJohn Marino 		     .word 0x6666; rex64; call __tls_get_addr@plt
4193c50c785cSJohn Marino 		     into:
4194c50c785cSJohn Marino 		     movl %fs:0, %eax
41955796c8dcSSimon Schubert 		     addq foo@gottpoff(%rip), %rax */
4196c50c785cSJohn Marino 		  if (ABI_64_P (output_bfd))
41975796c8dcSSimon Schubert 		    memcpy (contents + roff - 4,
41985796c8dcSSimon Schubert 			    "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
41995796c8dcSSimon Schubert 			    16);
4200c50c785cSJohn Marino 		  else
4201c50c785cSJohn Marino 		    memcpy (contents + roff - 3,
4202c50c785cSJohn Marino 			    "\x64\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
4203c50c785cSJohn Marino 			    15);
42045796c8dcSSimon Schubert 
42055796c8dcSSimon Schubert 		  relocation = (htab->elf.sgot->output_section->vma
42065796c8dcSSimon Schubert 				+ htab->elf.sgot->output_offset + off
42075796c8dcSSimon Schubert 				- roff
42085796c8dcSSimon Schubert 				- input_section->output_section->vma
42095796c8dcSSimon Schubert 				- input_section->output_offset
42105796c8dcSSimon Schubert 				- 12);
42115796c8dcSSimon Schubert 		  bfd_put_32 (output_bfd, relocation,
42125796c8dcSSimon Schubert 			      contents + roff + 8);
42135796c8dcSSimon Schubert 		  /* Skip R_X86_64_PLT32.  */
42145796c8dcSSimon Schubert 		  rel++;
42155796c8dcSSimon Schubert 		  continue;
42165796c8dcSSimon Schubert 		}
4217c50c785cSJohn Marino 	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
42185796c8dcSSimon Schubert 		{
42195796c8dcSSimon Schubert 		  /* GDesc -> IE transition.
42205796c8dcSSimon Schubert 		     It's originally something like:
42215796c8dcSSimon Schubert 		     leaq x@tlsdesc(%rip), %rax
42225796c8dcSSimon Schubert 
42235796c8dcSSimon Schubert 		     Change it to:
4224cf7f2e2dSJohn Marino 		     movq x@gottpoff(%rip), %rax # before xchg %ax,%ax.  */
42255796c8dcSSimon Schubert 
42265796c8dcSSimon Schubert 		  /* Now modify the instruction as appropriate. To
42275796c8dcSSimon Schubert 		     turn a leaq into a movq in the form we use it, it
42285796c8dcSSimon Schubert 		     suffices to change the second byte from 0x8d to
42295796c8dcSSimon Schubert 		     0x8b.  */
42305796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
42315796c8dcSSimon Schubert 
42325796c8dcSSimon Schubert 		  bfd_put_32 (output_bfd,
42335796c8dcSSimon Schubert 			      htab->elf.sgot->output_section->vma
42345796c8dcSSimon Schubert 			      + htab->elf.sgot->output_offset + off
42355796c8dcSSimon Schubert 			      - rel->r_offset
42365796c8dcSSimon Schubert 			      - input_section->output_section->vma
42375796c8dcSSimon Schubert 			      - input_section->output_offset
42385796c8dcSSimon Schubert 			      - 4,
42395796c8dcSSimon Schubert 			      contents + roff);
42405796c8dcSSimon Schubert 		  continue;
42415796c8dcSSimon Schubert 		}
4242c50c785cSJohn Marino 	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
42435796c8dcSSimon Schubert 		{
42445796c8dcSSimon Schubert 		  /* GDesc -> IE transition.
42455796c8dcSSimon Schubert 		     It's originally:
42465796c8dcSSimon Schubert 		     call *(%rax)
42475796c8dcSSimon Schubert 
42485796c8dcSSimon Schubert 		     Change it to:
42495796c8dcSSimon Schubert 		     xchg %ax, %ax.  */
42505796c8dcSSimon Schubert 
42515796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0x66, contents + roff);
42525796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
42535796c8dcSSimon Schubert 		  continue;
42545796c8dcSSimon Schubert 		}
42555796c8dcSSimon Schubert 	      else
42565796c8dcSSimon Schubert 		BFD_ASSERT (FALSE);
42575796c8dcSSimon Schubert 	    }
42585796c8dcSSimon Schubert 	  break;
42595796c8dcSSimon Schubert 
42605796c8dcSSimon Schubert 	case R_X86_64_TLSLD:
4261c50c785cSJohn Marino 	  if (! elf_x86_64_tls_transition (info, input_bfd,
42625796c8dcSSimon Schubert 					   input_section, contents,
42635796c8dcSSimon Schubert 					   symtab_hdr, sym_hashes,
42645796c8dcSSimon Schubert 					   &r_type, GOT_UNKNOWN,
42655796c8dcSSimon Schubert 					   rel, relend, h, r_symndx))
42665796c8dcSSimon Schubert 	    return FALSE;
42675796c8dcSSimon Schubert 
42685796c8dcSSimon Schubert 	  if (r_type != R_X86_64_TLSLD)
42695796c8dcSSimon Schubert 	    {
42705796c8dcSSimon Schubert 	      /* LD->LE transition:
42715796c8dcSSimon Schubert 		 leaq foo@tlsld(%rip), %rdi; call __tls_get_addr.
4272c50c785cSJohn Marino 		 For 64bit, we change it into:
4273c50c785cSJohn Marino 		 .word 0x6666; .byte 0x66; movq %fs:0, %rax.
4274c50c785cSJohn Marino 		 For 32bit, we change it into:
4275c50c785cSJohn Marino 		 nopl 0x0(%rax); movl %fs:0, %eax.  */
42765796c8dcSSimon Schubert 
42775796c8dcSSimon Schubert 	      BFD_ASSERT (r_type == R_X86_64_TPOFF32);
4278c50c785cSJohn Marino 	      if (ABI_64_P (output_bfd))
42795796c8dcSSimon Schubert 		memcpy (contents + rel->r_offset - 3,
42805796c8dcSSimon Schubert 			"\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
4281c50c785cSJohn Marino 	      else
4282c50c785cSJohn Marino 		memcpy (contents + rel->r_offset - 3,
4283c50c785cSJohn Marino 			"\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12);
42845796c8dcSSimon Schubert 	      /* Skip R_X86_64_PC32/R_X86_64_PLT32.  */
42855796c8dcSSimon Schubert 	      rel++;
42865796c8dcSSimon Schubert 	      continue;
42875796c8dcSSimon Schubert 	    }
42885796c8dcSSimon Schubert 
42895796c8dcSSimon Schubert 	  if (htab->elf.sgot == NULL)
42905796c8dcSSimon Schubert 	    abort ();
42915796c8dcSSimon Schubert 
42925796c8dcSSimon Schubert 	  off = htab->tls_ld_got.offset;
42935796c8dcSSimon Schubert 	  if (off & 1)
42945796c8dcSSimon Schubert 	    off &= ~1;
42955796c8dcSSimon Schubert 	  else
42965796c8dcSSimon Schubert 	    {
42975796c8dcSSimon Schubert 	      Elf_Internal_Rela outrel;
42985796c8dcSSimon Schubert 
42995796c8dcSSimon Schubert 	      if (htab->elf.srelgot == NULL)
43005796c8dcSSimon Schubert 		abort ();
43015796c8dcSSimon Schubert 
43025796c8dcSSimon Schubert 	      outrel.r_offset = (htab->elf.sgot->output_section->vma
43035796c8dcSSimon Schubert 				 + htab->elf.sgot->output_offset + off);
43045796c8dcSSimon Schubert 
43055796c8dcSSimon Schubert 	      bfd_put_64 (output_bfd, 0,
43065796c8dcSSimon Schubert 			  htab->elf.sgot->contents + off);
43075796c8dcSSimon Schubert 	      bfd_put_64 (output_bfd, 0,
43085796c8dcSSimon Schubert 			  htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
4309c50c785cSJohn Marino 	      outrel.r_info = htab->r_info (0, R_X86_64_DTPMOD64);
43105796c8dcSSimon Schubert 	      outrel.r_addend = 0;
4311c50c785cSJohn Marino 	      elf_append_rela (output_bfd, htab->elf.srelgot,
4312cf7f2e2dSJohn Marino 					&outrel);
43135796c8dcSSimon Schubert 	      htab->tls_ld_got.offset |= 1;
43145796c8dcSSimon Schubert 	    }
43155796c8dcSSimon Schubert 	  relocation = htab->elf.sgot->output_section->vma
43165796c8dcSSimon Schubert 		       + htab->elf.sgot->output_offset + off;
43175796c8dcSSimon Schubert 	  unresolved_reloc = FALSE;
43185796c8dcSSimon Schubert 	  break;
43195796c8dcSSimon Schubert 
43205796c8dcSSimon Schubert 	case R_X86_64_DTPOFF32:
43215796c8dcSSimon Schubert 	  if (!info->executable|| (input_section->flags & SEC_CODE) == 0)
4322c50c785cSJohn Marino 	    relocation -= elf_x86_64_dtpoff_base (info);
43235796c8dcSSimon Schubert 	  else
4324c50c785cSJohn Marino 	    relocation = elf_x86_64_tpoff (info, relocation);
43255796c8dcSSimon Schubert 	  break;
43265796c8dcSSimon Schubert 
43275796c8dcSSimon Schubert 	case R_X86_64_TPOFF32:
4328a45ae5f8SJohn Marino 	case R_X86_64_TPOFF64:
43295796c8dcSSimon Schubert 	  BFD_ASSERT (info->executable);
4330c50c785cSJohn Marino 	  relocation = elf_x86_64_tpoff (info, relocation);
43315796c8dcSSimon Schubert 	  break;
43325796c8dcSSimon Schubert 
43335796c8dcSSimon Schubert 	default:
43345796c8dcSSimon Schubert 	  break;
43355796c8dcSSimon Schubert 	}
43365796c8dcSSimon Schubert 
43375796c8dcSSimon Schubert       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
43385796c8dcSSimon Schubert 	 because such sections are not SEC_ALLOC and thus ld.so will
43395796c8dcSSimon Schubert 	 not process them.  */
43405796c8dcSSimon Schubert       if (unresolved_reloc
43415796c8dcSSimon Schubert 	  && !((input_section->flags & SEC_DEBUGGING) != 0
4342a45ae5f8SJohn Marino 	       && h->def_dynamic)
4343a45ae5f8SJohn Marino 	  && _bfd_elf_section_offset (output_bfd, info, input_section,
4344a45ae5f8SJohn Marino 				      rel->r_offset) != (bfd_vma) -1)
4345*ef5ccd6cSJohn Marino 	{
43465796c8dcSSimon Schubert 	  (*_bfd_error_handler)
43475796c8dcSSimon Schubert 	    (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
43485796c8dcSSimon Schubert 	     input_bfd,
43495796c8dcSSimon Schubert 	     input_section,
43505796c8dcSSimon Schubert 	     (long) rel->r_offset,
43515796c8dcSSimon Schubert 	     howto->name,
43525796c8dcSSimon Schubert 	     h->root.root.string);
4353*ef5ccd6cSJohn Marino 	  return FALSE;
4354*ef5ccd6cSJohn Marino 	}
43555796c8dcSSimon Schubert 
43565796c8dcSSimon Schubert do_relocation:
43575796c8dcSSimon Schubert       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
43585796c8dcSSimon Schubert 				    contents, rel->r_offset,
43595796c8dcSSimon Schubert 				    relocation, rel->r_addend);
43605796c8dcSSimon Schubert 
4361a45ae5f8SJohn Marino check_relocation_error:
43625796c8dcSSimon Schubert       if (r != bfd_reloc_ok)
43635796c8dcSSimon Schubert 	{
43645796c8dcSSimon Schubert 	  const char *name;
43655796c8dcSSimon Schubert 
43665796c8dcSSimon Schubert 	  if (h != NULL)
43675796c8dcSSimon Schubert 	    name = h->root.root.string;
43685796c8dcSSimon Schubert 	  else
43695796c8dcSSimon Schubert 	    {
43705796c8dcSSimon Schubert 	      name = bfd_elf_string_from_elf_section (input_bfd,
43715796c8dcSSimon Schubert 						      symtab_hdr->sh_link,
43725796c8dcSSimon Schubert 						      sym->st_name);
43735796c8dcSSimon Schubert 	      if (name == NULL)
43745796c8dcSSimon Schubert 		return FALSE;
43755796c8dcSSimon Schubert 	      if (*name == '\0')
43765796c8dcSSimon Schubert 		name = bfd_section_name (input_bfd, sec);
43775796c8dcSSimon Schubert 	    }
43785796c8dcSSimon Schubert 
43795796c8dcSSimon Schubert 	  if (r == bfd_reloc_overflow)
43805796c8dcSSimon Schubert 	    {
43815796c8dcSSimon Schubert 	      if (! ((*info->callbacks->reloc_overflow)
43825796c8dcSSimon Schubert 		     (info, (h ? &h->root : NULL), name, howto->name,
43835796c8dcSSimon Schubert 		      (bfd_vma) 0, input_bfd, input_section,
43845796c8dcSSimon Schubert 		      rel->r_offset)))
43855796c8dcSSimon Schubert 		return FALSE;
43865796c8dcSSimon Schubert 	    }
43875796c8dcSSimon Schubert 	  else
43885796c8dcSSimon Schubert 	    {
43895796c8dcSSimon Schubert 	      (*_bfd_error_handler)
43905796c8dcSSimon Schubert 		(_("%B(%A+0x%lx): reloc against `%s': error %d"),
43915796c8dcSSimon Schubert 		 input_bfd, input_section,
43925796c8dcSSimon Schubert 		 (long) rel->r_offset, name, (int) r);
43935796c8dcSSimon Schubert 	      return FALSE;
43945796c8dcSSimon Schubert 	    }
43955796c8dcSSimon Schubert 	}
43965796c8dcSSimon Schubert     }
43975796c8dcSSimon Schubert 
43985796c8dcSSimon Schubert   return TRUE;
43995796c8dcSSimon Schubert }
44005796c8dcSSimon Schubert 
44015796c8dcSSimon Schubert /* Finish up dynamic symbol handling.  We set the contents of various
44025796c8dcSSimon Schubert    dynamic sections here.  */
44035796c8dcSSimon Schubert 
44045796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_finish_dynamic_symbol(bfd * output_bfd,struct bfd_link_info * info,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym ATTRIBUTE_UNUSED)4405c50c785cSJohn Marino elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
44065796c8dcSSimon Schubert 				  struct bfd_link_info *info,
44075796c8dcSSimon Schubert 				  struct elf_link_hash_entry *h,
4408*ef5ccd6cSJohn Marino 				  Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
44095796c8dcSSimon Schubert {
4410c50c785cSJohn Marino   struct elf_x86_64_link_hash_table *htab;
4411*ef5ccd6cSJohn Marino   const struct elf_x86_64_backend_data *const abed
4412*ef5ccd6cSJohn Marino     = get_elf_x86_64_backend_data (output_bfd);
44135796c8dcSSimon Schubert 
4414c50c785cSJohn Marino   htab = elf_x86_64_hash_table (info);
4415cf7f2e2dSJohn Marino   if (htab == NULL)
4416cf7f2e2dSJohn Marino     return FALSE;
44175796c8dcSSimon Schubert 
44185796c8dcSSimon Schubert   if (h->plt.offset != (bfd_vma) -1)
44195796c8dcSSimon Schubert     {
44205796c8dcSSimon Schubert       bfd_vma plt_index;
44215796c8dcSSimon Schubert       bfd_vma got_offset;
44225796c8dcSSimon Schubert       Elf_Internal_Rela rela;
44235796c8dcSSimon Schubert       bfd_byte *loc;
44245796c8dcSSimon Schubert       asection *plt, *gotplt, *relplt;
4425c50c785cSJohn Marino       const struct elf_backend_data *bed;
44265796c8dcSSimon Schubert 
44275796c8dcSSimon Schubert       /* When building a static executable, use .iplt, .igot.plt and
44285796c8dcSSimon Schubert 	 .rela.iplt sections for STT_GNU_IFUNC symbols.  */
44295796c8dcSSimon Schubert       if (htab->elf.splt != NULL)
44305796c8dcSSimon Schubert 	{
44315796c8dcSSimon Schubert 	  plt = htab->elf.splt;
44325796c8dcSSimon Schubert 	  gotplt = htab->elf.sgotplt;
44335796c8dcSSimon Schubert 	  relplt = htab->elf.srelplt;
44345796c8dcSSimon Schubert 	}
44355796c8dcSSimon Schubert       else
44365796c8dcSSimon Schubert 	{
44375796c8dcSSimon Schubert 	  plt = htab->elf.iplt;
44385796c8dcSSimon Schubert 	  gotplt = htab->elf.igotplt;
44395796c8dcSSimon Schubert 	  relplt = htab->elf.irelplt;
44405796c8dcSSimon Schubert 	}
44415796c8dcSSimon Schubert 
44425796c8dcSSimon Schubert       /* This symbol has an entry in the procedure linkage table.  Set
44435796c8dcSSimon Schubert 	 it up.	 */
44445796c8dcSSimon Schubert       if ((h->dynindx == -1
44455796c8dcSSimon Schubert 	   && !((h->forced_local || info->executable)
44465796c8dcSSimon Schubert 		&& h->def_regular
44475796c8dcSSimon Schubert 		&& h->type == STT_GNU_IFUNC))
44485796c8dcSSimon Schubert 	  || plt == NULL
44495796c8dcSSimon Schubert 	  || gotplt == NULL
44505796c8dcSSimon Schubert 	  || relplt == NULL)
4451*ef5ccd6cSJohn Marino 	abort ();
44525796c8dcSSimon Schubert 
44535796c8dcSSimon Schubert       /* Get the index in the procedure linkage table which
44545796c8dcSSimon Schubert 	 corresponds to this symbol.  This is the index of this symbol
44555796c8dcSSimon Schubert 	 in all the symbols for which we are making plt entries.  The
44565796c8dcSSimon Schubert 	 first entry in the procedure linkage table is reserved.
44575796c8dcSSimon Schubert 
44585796c8dcSSimon Schubert 	 Get the offset into the .got table of the entry that
44595796c8dcSSimon Schubert 	 corresponds to this function.	Each .got entry is GOT_ENTRY_SIZE
44605796c8dcSSimon Schubert 	 bytes. The first three are reserved for the dynamic linker.
44615796c8dcSSimon Schubert 
44625796c8dcSSimon Schubert 	 For static executables, we don't reserve anything.  */
44635796c8dcSSimon Schubert 
44645796c8dcSSimon Schubert       if (plt == htab->elf.splt)
44655796c8dcSSimon Schubert 	{
4466*ef5ccd6cSJohn Marino 	  got_offset = h->plt.offset / abed->plt_entry_size - 1;
4467a45ae5f8SJohn Marino 	  got_offset = (got_offset + 3) * GOT_ENTRY_SIZE;
44685796c8dcSSimon Schubert 	}
44695796c8dcSSimon Schubert       else
44705796c8dcSSimon Schubert 	{
4471*ef5ccd6cSJohn Marino 	  got_offset = h->plt.offset / abed->plt_entry_size;
4472a45ae5f8SJohn Marino 	  got_offset = got_offset * GOT_ENTRY_SIZE;
44735796c8dcSSimon Schubert 	}
44745796c8dcSSimon Schubert 
44755796c8dcSSimon Schubert       /* Fill in the entry in the procedure linkage table.  */
4476*ef5ccd6cSJohn Marino       memcpy (plt->contents + h->plt.offset, abed->plt_entry,
4477*ef5ccd6cSJohn Marino 	      abed->plt_entry_size);
44785796c8dcSSimon Schubert 
4479*ef5ccd6cSJohn Marino       /* Insert the relocation positions of the plt section.  */
4480*ef5ccd6cSJohn Marino 
4481*ef5ccd6cSJohn Marino       /* Put offset the PC-relative instruction referring to the GOT entry,
4482*ef5ccd6cSJohn Marino 	 subtracting the size of that instruction.  */
44835796c8dcSSimon Schubert       bfd_put_32 (output_bfd,
44845796c8dcSSimon Schubert 		  (gotplt->output_section->vma
44855796c8dcSSimon Schubert 		   + gotplt->output_offset
44865796c8dcSSimon Schubert 		   + got_offset
44875796c8dcSSimon Schubert 		   - plt->output_section->vma
44885796c8dcSSimon Schubert 		   - plt->output_offset
44895796c8dcSSimon Schubert 		   - h->plt.offset
4490*ef5ccd6cSJohn Marino 		   - abed->plt_got_insn_size),
4491*ef5ccd6cSJohn Marino 		  plt->contents + h->plt.offset + abed->plt_got_offset);
44925796c8dcSSimon Schubert 
44935796c8dcSSimon Schubert       /* Fill in the entry in the global offset table, initially this
4494*ef5ccd6cSJohn Marino 	 points to the second part of the PLT entry.  */
44955796c8dcSSimon Schubert       bfd_put_64 (output_bfd, (plt->output_section->vma
44965796c8dcSSimon Schubert 			       + plt->output_offset
4497*ef5ccd6cSJohn Marino 			       + h->plt.offset + abed->plt_lazy_offset),
44985796c8dcSSimon Schubert 		  gotplt->contents + got_offset);
44995796c8dcSSimon Schubert 
45005796c8dcSSimon Schubert       /* Fill in the entry in the .rela.plt section.  */
45015796c8dcSSimon Schubert       rela.r_offset = (gotplt->output_section->vma
45025796c8dcSSimon Schubert 		       + gotplt->output_offset
45035796c8dcSSimon Schubert 		       + got_offset);
45045796c8dcSSimon Schubert       if (h->dynindx == -1
45055796c8dcSSimon Schubert 	  || ((info->executable
45065796c8dcSSimon Schubert 	       || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
45075796c8dcSSimon Schubert 	      && h->def_regular
45085796c8dcSSimon Schubert 	      && h->type == STT_GNU_IFUNC))
45095796c8dcSSimon Schubert 	{
45105796c8dcSSimon Schubert 	  /* If an STT_GNU_IFUNC symbol is locally defined, generate
45115796c8dcSSimon Schubert 	     R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT.  */
4512c50c785cSJohn Marino 	  rela.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
45135796c8dcSSimon Schubert 	  rela.r_addend = (h->root.u.def.value
45145796c8dcSSimon Schubert 			   + h->root.u.def.section->output_section->vma
45155796c8dcSSimon Schubert 			   + h->root.u.def.section->output_offset);
4516a45ae5f8SJohn Marino 	  /* R_X86_64_IRELATIVE comes last.  */
4517a45ae5f8SJohn Marino 	  plt_index = htab->next_irelative_index--;
45185796c8dcSSimon Schubert 	}
45195796c8dcSSimon Schubert       else
45205796c8dcSSimon Schubert 	{
4521c50c785cSJohn Marino 	  rela.r_info = htab->r_info (h->dynindx, R_X86_64_JUMP_SLOT);
45225796c8dcSSimon Schubert 	  rela.r_addend = 0;
4523a45ae5f8SJohn Marino 	  plt_index = htab->next_jump_slot_index++;
4524a45ae5f8SJohn Marino 	}
4525a45ae5f8SJohn Marino 
4526a45ae5f8SJohn Marino       /* Don't fill PLT entry for static executables.  */
4527a45ae5f8SJohn Marino       if (plt == htab->elf.splt)
4528a45ae5f8SJohn Marino 	{
4529a45ae5f8SJohn Marino 	  /* Put relocation index.  */
4530a45ae5f8SJohn Marino 	  bfd_put_32 (output_bfd, plt_index,
4531*ef5ccd6cSJohn Marino 		      plt->contents + h->plt.offset + abed->plt_reloc_offset);
4532a45ae5f8SJohn Marino 	  /* Put offset for jmp .PLT0.  */
4533*ef5ccd6cSJohn Marino 	  bfd_put_32 (output_bfd, - (h->plt.offset + abed->plt_plt_insn_end),
4534*ef5ccd6cSJohn Marino 		      plt->contents + h->plt.offset + abed->plt_plt_offset);
45355796c8dcSSimon Schubert 	}
4536c50c785cSJohn Marino 
4537c50c785cSJohn Marino       bed = get_elf_backend_data (output_bfd);
4538c50c785cSJohn Marino       loc = relplt->contents + plt_index * bed->s->sizeof_rela;
4539c50c785cSJohn Marino       bed->s->swap_reloca_out (output_bfd, &rela, loc);
45405796c8dcSSimon Schubert 
45415796c8dcSSimon Schubert       if (!h->def_regular)
45425796c8dcSSimon Schubert 	{
45435796c8dcSSimon Schubert 	  /* Mark the symbol as undefined, rather than as defined in
45445796c8dcSSimon Schubert 	     the .plt section.  Leave the value if there were any
45455796c8dcSSimon Schubert 	     relocations where pointer equality matters (this is a clue
45465796c8dcSSimon Schubert 	     for the dynamic linker, to make function pointer
45475796c8dcSSimon Schubert 	     comparisons work between an application and shared
45485796c8dcSSimon Schubert 	     library), otherwise set it to zero.  If a function is only
45495796c8dcSSimon Schubert 	     called from a binary, there is no need to slow down
45505796c8dcSSimon Schubert 	     shared libraries because of that.  */
45515796c8dcSSimon Schubert 	  sym->st_shndx = SHN_UNDEF;
45525796c8dcSSimon Schubert 	  if (!h->pointer_equality_needed)
45535796c8dcSSimon Schubert 	    sym->st_value = 0;
45545796c8dcSSimon Schubert 	}
45555796c8dcSSimon Schubert     }
45565796c8dcSSimon Schubert 
45575796c8dcSSimon Schubert   if (h->got.offset != (bfd_vma) -1
4558c50c785cSJohn Marino       && ! GOT_TLS_GD_ANY_P (elf_x86_64_hash_entry (h)->tls_type)
4559c50c785cSJohn Marino       && elf_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE)
45605796c8dcSSimon Schubert     {
45615796c8dcSSimon Schubert       Elf_Internal_Rela rela;
45625796c8dcSSimon Schubert 
45635796c8dcSSimon Schubert       /* This symbol has an entry in the global offset table.  Set it
45645796c8dcSSimon Schubert 	 up.  */
45655796c8dcSSimon Schubert       if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
45665796c8dcSSimon Schubert 	abort ();
45675796c8dcSSimon Schubert 
45685796c8dcSSimon Schubert       rela.r_offset = (htab->elf.sgot->output_section->vma
45695796c8dcSSimon Schubert 		       + htab->elf.sgot->output_offset
45705796c8dcSSimon Schubert 		       + (h->got.offset &~ (bfd_vma) 1));
45715796c8dcSSimon Schubert 
45725796c8dcSSimon Schubert       /* If this is a static link, or it is a -Bsymbolic link and the
45735796c8dcSSimon Schubert 	 symbol is defined locally or was forced to be local because
45745796c8dcSSimon Schubert 	 of a version file, we just want to emit a RELATIVE reloc.
45755796c8dcSSimon Schubert 	 The entry in the global offset table will already have been
45765796c8dcSSimon Schubert 	 initialized in the relocate_section function.  */
45775796c8dcSSimon Schubert       if (h->def_regular
45785796c8dcSSimon Schubert 	  && h->type == STT_GNU_IFUNC)
45795796c8dcSSimon Schubert 	{
45805796c8dcSSimon Schubert 	  if (info->shared)
45815796c8dcSSimon Schubert 	    {
45825796c8dcSSimon Schubert 	      /* Generate R_X86_64_GLOB_DAT.  */
45835796c8dcSSimon Schubert 	      goto do_glob_dat;
45845796c8dcSSimon Schubert 	    }
45855796c8dcSSimon Schubert 	  else
45865796c8dcSSimon Schubert 	    {
45875796c8dcSSimon Schubert 	      asection *plt;
45885796c8dcSSimon Schubert 
45895796c8dcSSimon Schubert 	      if (!h->pointer_equality_needed)
45905796c8dcSSimon Schubert 		abort ();
45915796c8dcSSimon Schubert 
45925796c8dcSSimon Schubert 	      /* For non-shared object, we can't use .got.plt, which
45935796c8dcSSimon Schubert 		 contains the real function addres if we need pointer
45945796c8dcSSimon Schubert 		 equality.  We load the GOT entry with the PLT entry.  */
45955796c8dcSSimon Schubert 	      plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
45965796c8dcSSimon Schubert 	      bfd_put_64 (output_bfd, (plt->output_section->vma
45975796c8dcSSimon Schubert 				       + plt->output_offset
45985796c8dcSSimon Schubert 				       + h->plt.offset),
45995796c8dcSSimon Schubert 			  htab->elf.sgot->contents + h->got.offset);
46005796c8dcSSimon Schubert 	      return TRUE;
46015796c8dcSSimon Schubert 	    }
46025796c8dcSSimon Schubert 	}
46035796c8dcSSimon Schubert       else if (info->shared
46045796c8dcSSimon Schubert 	       && SYMBOL_REFERENCES_LOCAL (info, h))
46055796c8dcSSimon Schubert 	{
46065796c8dcSSimon Schubert 	  if (!h->def_regular)
46075796c8dcSSimon Schubert 	    return FALSE;
46085796c8dcSSimon Schubert 	  BFD_ASSERT((h->got.offset & 1) != 0);
4609c50c785cSJohn Marino 	  rela.r_info = htab->r_info (0, R_X86_64_RELATIVE);
46105796c8dcSSimon Schubert 	  rela.r_addend = (h->root.u.def.value
46115796c8dcSSimon Schubert 			   + h->root.u.def.section->output_section->vma
46125796c8dcSSimon Schubert 			   + h->root.u.def.section->output_offset);
46135796c8dcSSimon Schubert 	}
46145796c8dcSSimon Schubert       else
46155796c8dcSSimon Schubert 	{
46165796c8dcSSimon Schubert 	  BFD_ASSERT((h->got.offset & 1) == 0);
46175796c8dcSSimon Schubert do_glob_dat:
46185796c8dcSSimon Schubert 	  bfd_put_64 (output_bfd, (bfd_vma) 0,
46195796c8dcSSimon Schubert 		      htab->elf.sgot->contents + h->got.offset);
4620c50c785cSJohn Marino 	  rela.r_info = htab->r_info (h->dynindx, R_X86_64_GLOB_DAT);
46215796c8dcSSimon Schubert 	  rela.r_addend = 0;
46225796c8dcSSimon Schubert 	}
46235796c8dcSSimon Schubert 
4624c50c785cSJohn Marino       elf_append_rela (output_bfd, htab->elf.srelgot, &rela);
46255796c8dcSSimon Schubert     }
46265796c8dcSSimon Schubert 
46275796c8dcSSimon Schubert   if (h->needs_copy)
46285796c8dcSSimon Schubert     {
46295796c8dcSSimon Schubert       Elf_Internal_Rela rela;
46305796c8dcSSimon Schubert 
46315796c8dcSSimon Schubert       /* This symbol needs a copy reloc.  Set it up.  */
46325796c8dcSSimon Schubert 
46335796c8dcSSimon Schubert       if (h->dynindx == -1
46345796c8dcSSimon Schubert 	  || (h->root.type != bfd_link_hash_defined
46355796c8dcSSimon Schubert 	      && h->root.type != bfd_link_hash_defweak)
46365796c8dcSSimon Schubert 	  || htab->srelbss == NULL)
46375796c8dcSSimon Schubert 	abort ();
46385796c8dcSSimon Schubert 
46395796c8dcSSimon Schubert       rela.r_offset = (h->root.u.def.value
46405796c8dcSSimon Schubert 		       + h->root.u.def.section->output_section->vma
46415796c8dcSSimon Schubert 		       + h->root.u.def.section->output_offset);
4642c50c785cSJohn Marino       rela.r_info = htab->r_info (h->dynindx, R_X86_64_COPY);
46435796c8dcSSimon Schubert       rela.r_addend = 0;
4644c50c785cSJohn Marino       elf_append_rela (output_bfd, htab->srelbss, &rela);
46455796c8dcSSimon Schubert     }
46465796c8dcSSimon Schubert 
46475796c8dcSSimon Schubert   return TRUE;
46485796c8dcSSimon Schubert }
46495796c8dcSSimon Schubert 
46505796c8dcSSimon Schubert /* Finish up local dynamic symbol handling.  We set the contents of
46515796c8dcSSimon Schubert    various dynamic sections here.  */
46525796c8dcSSimon Schubert 
46535796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_finish_local_dynamic_symbol(void ** slot,void * inf)4654c50c785cSJohn Marino elf_x86_64_finish_local_dynamic_symbol (void **slot, void *inf)
46555796c8dcSSimon Schubert {
46565796c8dcSSimon Schubert   struct elf_link_hash_entry *h
46575796c8dcSSimon Schubert     = (struct elf_link_hash_entry *) *slot;
46585796c8dcSSimon Schubert   struct bfd_link_info *info
46595796c8dcSSimon Schubert     = (struct bfd_link_info *) inf;
46605796c8dcSSimon Schubert 
4661c50c785cSJohn Marino   return elf_x86_64_finish_dynamic_symbol (info->output_bfd,
46625796c8dcSSimon Schubert 					     info, h, NULL);
46635796c8dcSSimon Schubert }
46645796c8dcSSimon Schubert 
46655796c8dcSSimon Schubert /* Used to decide how to sort relocs in an optimal manner for the
46665796c8dcSSimon Schubert    dynamic linker, before writing them out.  */
46675796c8dcSSimon Schubert 
46685796c8dcSSimon Schubert static enum elf_reloc_type_class
elf_x86_64_reloc_type_class(const Elf_Internal_Rela * rela)4669c50c785cSJohn Marino elf_x86_64_reloc_type_class (const Elf_Internal_Rela *rela)
46705796c8dcSSimon Schubert {
4671c50c785cSJohn Marino   switch ((int) ELF32_R_TYPE (rela->r_info))
46725796c8dcSSimon Schubert     {
46735796c8dcSSimon Schubert     case R_X86_64_RELATIVE:
4674*ef5ccd6cSJohn Marino     case R_X86_64_RELATIVE64:
46755796c8dcSSimon Schubert       return reloc_class_relative;
46765796c8dcSSimon Schubert     case R_X86_64_JUMP_SLOT:
46775796c8dcSSimon Schubert       return reloc_class_plt;
46785796c8dcSSimon Schubert     case R_X86_64_COPY:
46795796c8dcSSimon Schubert       return reloc_class_copy;
46805796c8dcSSimon Schubert     default:
46815796c8dcSSimon Schubert       return reloc_class_normal;
46825796c8dcSSimon Schubert     }
46835796c8dcSSimon Schubert }
46845796c8dcSSimon Schubert 
46855796c8dcSSimon Schubert /* Finish up the dynamic sections.  */
46865796c8dcSSimon Schubert 
46875796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_finish_dynamic_sections(bfd * output_bfd,struct bfd_link_info * info)4688c50c785cSJohn Marino elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
4689c50c785cSJohn Marino 				    struct bfd_link_info *info)
46905796c8dcSSimon Schubert {
4691c50c785cSJohn Marino   struct elf_x86_64_link_hash_table *htab;
46925796c8dcSSimon Schubert   bfd *dynobj;
46935796c8dcSSimon Schubert   asection *sdyn;
4694*ef5ccd6cSJohn Marino   const struct elf_x86_64_backend_data *const abed
4695*ef5ccd6cSJohn Marino     = get_elf_x86_64_backend_data (output_bfd);
46965796c8dcSSimon Schubert 
4697c50c785cSJohn Marino   htab = elf_x86_64_hash_table (info);
4698cf7f2e2dSJohn Marino   if (htab == NULL)
4699cf7f2e2dSJohn Marino     return FALSE;
4700cf7f2e2dSJohn Marino 
47015796c8dcSSimon Schubert   dynobj = htab->elf.dynobj;
4702*ef5ccd6cSJohn Marino   sdyn = bfd_get_linker_section (dynobj, ".dynamic");
47035796c8dcSSimon Schubert 
47045796c8dcSSimon Schubert   if (htab->elf.dynamic_sections_created)
47055796c8dcSSimon Schubert     {
4706c50c785cSJohn Marino       bfd_byte *dyncon, *dynconend;
4707c50c785cSJohn Marino       const struct elf_backend_data *bed;
4708c50c785cSJohn Marino       bfd_size_type sizeof_dyn;
47095796c8dcSSimon Schubert 
47105796c8dcSSimon Schubert       if (sdyn == NULL || htab->elf.sgot == NULL)
47115796c8dcSSimon Schubert 	abort ();
47125796c8dcSSimon Schubert 
4713c50c785cSJohn Marino       bed = get_elf_backend_data (dynobj);
4714c50c785cSJohn Marino       sizeof_dyn = bed->s->sizeof_dyn;
4715c50c785cSJohn Marino       dyncon = sdyn->contents;
4716c50c785cSJohn Marino       dynconend = sdyn->contents + sdyn->size;
4717c50c785cSJohn Marino       for (; dyncon < dynconend; dyncon += sizeof_dyn)
47185796c8dcSSimon Schubert 	{
47195796c8dcSSimon Schubert 	  Elf_Internal_Dyn dyn;
47205796c8dcSSimon Schubert 	  asection *s;
47215796c8dcSSimon Schubert 
4722c50c785cSJohn Marino 	  (*bed->s->swap_dyn_in) (dynobj, dyncon, &dyn);
47235796c8dcSSimon Schubert 
47245796c8dcSSimon Schubert 	  switch (dyn.d_tag)
47255796c8dcSSimon Schubert 	    {
47265796c8dcSSimon Schubert 	    default:
47275796c8dcSSimon Schubert 	      continue;
47285796c8dcSSimon Schubert 
47295796c8dcSSimon Schubert 	    case DT_PLTGOT:
47305796c8dcSSimon Schubert 	      s = htab->elf.sgotplt;
47315796c8dcSSimon Schubert 	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
47325796c8dcSSimon Schubert 	      break;
47335796c8dcSSimon Schubert 
47345796c8dcSSimon Schubert 	    case DT_JMPREL:
47355796c8dcSSimon Schubert 	      dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
47365796c8dcSSimon Schubert 	      break;
47375796c8dcSSimon Schubert 
47385796c8dcSSimon Schubert 	    case DT_PLTRELSZ:
47395796c8dcSSimon Schubert 	      s = htab->elf.srelplt->output_section;
47405796c8dcSSimon Schubert 	      dyn.d_un.d_val = s->size;
47415796c8dcSSimon Schubert 	      break;
47425796c8dcSSimon Schubert 
47435796c8dcSSimon Schubert 	    case DT_RELASZ:
47445796c8dcSSimon Schubert 	      /* The procedure linkage table relocs (DT_JMPREL) should
47455796c8dcSSimon Schubert 		 not be included in the overall relocs (DT_RELA).
47465796c8dcSSimon Schubert 		 Therefore, we override the DT_RELASZ entry here to
47475796c8dcSSimon Schubert 		 make it not include the JMPREL relocs.  Since the
47485796c8dcSSimon Schubert 		 linker script arranges for .rela.plt to follow all
47495796c8dcSSimon Schubert 		 other relocation sections, we don't have to worry
47505796c8dcSSimon Schubert 		 about changing the DT_RELA entry.  */
47515796c8dcSSimon Schubert 	      if (htab->elf.srelplt != NULL)
47525796c8dcSSimon Schubert 		{
47535796c8dcSSimon Schubert 		  s = htab->elf.srelplt->output_section;
47545796c8dcSSimon Schubert 		  dyn.d_un.d_val -= s->size;
47555796c8dcSSimon Schubert 		}
47565796c8dcSSimon Schubert 	      break;
47575796c8dcSSimon Schubert 
47585796c8dcSSimon Schubert 	    case DT_TLSDESC_PLT:
47595796c8dcSSimon Schubert 	      s = htab->elf.splt;
47605796c8dcSSimon Schubert 	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
47615796c8dcSSimon Schubert 		+ htab->tlsdesc_plt;
47625796c8dcSSimon Schubert 	      break;
47635796c8dcSSimon Schubert 
47645796c8dcSSimon Schubert 	    case DT_TLSDESC_GOT:
47655796c8dcSSimon Schubert 	      s = htab->elf.sgot;
47665796c8dcSSimon Schubert 	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
47675796c8dcSSimon Schubert 		+ htab->tlsdesc_got;
47685796c8dcSSimon Schubert 	      break;
47695796c8dcSSimon Schubert 	    }
47705796c8dcSSimon Schubert 
4771c50c785cSJohn Marino 	  (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon);
47725796c8dcSSimon Schubert 	}
47735796c8dcSSimon Schubert 
47745796c8dcSSimon Schubert       /* Fill in the special first entry in the procedure linkage table.  */
47755796c8dcSSimon Schubert       if (htab->elf.splt && htab->elf.splt->size > 0)
47765796c8dcSSimon Schubert 	{
47775796c8dcSSimon Schubert 	  /* Fill in the first entry in the procedure linkage table.  */
4778*ef5ccd6cSJohn Marino 	  memcpy (htab->elf.splt->contents,
4779*ef5ccd6cSJohn Marino 		  abed->plt0_entry, abed->plt_entry_size);
47805796c8dcSSimon Schubert 	  /* Add offset for pushq GOT+8(%rip), since the instruction
47815796c8dcSSimon Schubert 	     uses 6 bytes subtract this value.  */
47825796c8dcSSimon Schubert 	  bfd_put_32 (output_bfd,
47835796c8dcSSimon Schubert 		      (htab->elf.sgotplt->output_section->vma
47845796c8dcSSimon Schubert 		       + htab->elf.sgotplt->output_offset
47855796c8dcSSimon Schubert 		       + 8
47865796c8dcSSimon Schubert 		       - htab->elf.splt->output_section->vma
47875796c8dcSSimon Schubert 		       - htab->elf.splt->output_offset
47885796c8dcSSimon Schubert 		       - 6),
4789*ef5ccd6cSJohn Marino 		      htab->elf.splt->contents + abed->plt0_got1_offset);
4790*ef5ccd6cSJohn Marino 	  /* Add offset for the PC-relative instruction accessing GOT+16,
4791*ef5ccd6cSJohn Marino 	     subtracting the offset to the end of that instruction.  */
47925796c8dcSSimon Schubert 	  bfd_put_32 (output_bfd,
47935796c8dcSSimon Schubert 		      (htab->elf.sgotplt->output_section->vma
47945796c8dcSSimon Schubert 		       + htab->elf.sgotplt->output_offset
47955796c8dcSSimon Schubert 		       + 16
47965796c8dcSSimon Schubert 		       - htab->elf.splt->output_section->vma
47975796c8dcSSimon Schubert 		       - htab->elf.splt->output_offset
4798*ef5ccd6cSJohn Marino 		       - abed->plt0_got2_insn_end),
4799*ef5ccd6cSJohn Marino 		      htab->elf.splt->contents + abed->plt0_got2_offset);
48005796c8dcSSimon Schubert 
4801*ef5ccd6cSJohn Marino 	  elf_section_data (htab->elf.splt->output_section)
4802*ef5ccd6cSJohn Marino 	    ->this_hdr.sh_entsize = abed->plt_entry_size;
48035796c8dcSSimon Schubert 
48045796c8dcSSimon Schubert 	  if (htab->tlsdesc_plt)
48055796c8dcSSimon Schubert 	    {
48065796c8dcSSimon Schubert 	      bfd_put_64 (output_bfd, (bfd_vma) 0,
48075796c8dcSSimon Schubert 			  htab->elf.sgot->contents + htab->tlsdesc_got);
48085796c8dcSSimon Schubert 
48095796c8dcSSimon Schubert 	      memcpy (htab->elf.splt->contents + htab->tlsdesc_plt,
4810*ef5ccd6cSJohn Marino 		      abed->plt0_entry, abed->plt_entry_size);
48115796c8dcSSimon Schubert 
48125796c8dcSSimon Schubert 	      /* Add offset for pushq GOT+8(%rip), since the
48135796c8dcSSimon Schubert 		 instruction uses 6 bytes subtract this value.  */
48145796c8dcSSimon Schubert 	      bfd_put_32 (output_bfd,
48155796c8dcSSimon Schubert 			  (htab->elf.sgotplt->output_section->vma
48165796c8dcSSimon Schubert 			   + htab->elf.sgotplt->output_offset
48175796c8dcSSimon Schubert 			   + 8
48185796c8dcSSimon Schubert 			   - htab->elf.splt->output_section->vma
48195796c8dcSSimon Schubert 			   - htab->elf.splt->output_offset
48205796c8dcSSimon Schubert 			   - htab->tlsdesc_plt
48215796c8dcSSimon Schubert 			   - 6),
4822*ef5ccd6cSJohn Marino 			  htab->elf.splt->contents
4823*ef5ccd6cSJohn Marino 			  + htab->tlsdesc_plt + abed->plt0_got1_offset);
4824*ef5ccd6cSJohn Marino 	  /* Add offset for the PC-relative instruction accessing GOT+TDG,
4825*ef5ccd6cSJohn Marino 	     where TGD stands for htab->tlsdesc_got, subtracting the offset
4826*ef5ccd6cSJohn Marino 	     to the end of that instruction.  */
48275796c8dcSSimon Schubert 	      bfd_put_32 (output_bfd,
48285796c8dcSSimon Schubert 			  (htab->elf.sgot->output_section->vma
48295796c8dcSSimon Schubert 			   + htab->elf.sgot->output_offset
48305796c8dcSSimon Schubert 			   + htab->tlsdesc_got
48315796c8dcSSimon Schubert 			   - htab->elf.splt->output_section->vma
48325796c8dcSSimon Schubert 			   - htab->elf.splt->output_offset
48335796c8dcSSimon Schubert 			   - htab->tlsdesc_plt
4834*ef5ccd6cSJohn Marino 			   - abed->plt0_got2_insn_end),
4835*ef5ccd6cSJohn Marino 			  htab->elf.splt->contents
4836*ef5ccd6cSJohn Marino 			  + htab->tlsdesc_plt + abed->plt0_got2_offset);
48375796c8dcSSimon Schubert 	    }
48385796c8dcSSimon Schubert 	}
48395796c8dcSSimon Schubert     }
48405796c8dcSSimon Schubert 
48415796c8dcSSimon Schubert   if (htab->elf.sgotplt)
48425796c8dcSSimon Schubert     {
4843c50c785cSJohn Marino       if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
4844c50c785cSJohn Marino 	{
4845c50c785cSJohn Marino 	  (*_bfd_error_handler)
4846c50c785cSJohn Marino 	    (_("discarded output section: `%A'"), htab->elf.sgotplt);
4847c50c785cSJohn Marino 	  return FALSE;
4848c50c785cSJohn Marino 	}
4849c50c785cSJohn Marino 
48505796c8dcSSimon Schubert       /* Fill in the first three entries in the global offset table.  */
48515796c8dcSSimon Schubert       if (htab->elf.sgotplt->size > 0)
48525796c8dcSSimon Schubert 	{
48535796c8dcSSimon Schubert 	  /* Set the first entry in the global offset table to the address of
48545796c8dcSSimon Schubert 	     the dynamic section.  */
48555796c8dcSSimon Schubert 	  if (sdyn == NULL)
48565796c8dcSSimon Schubert 	    bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents);
48575796c8dcSSimon Schubert 	  else
48585796c8dcSSimon Schubert 	    bfd_put_64 (output_bfd,
48595796c8dcSSimon Schubert 			sdyn->output_section->vma + sdyn->output_offset,
48605796c8dcSSimon Schubert 			htab->elf.sgotplt->contents);
48615796c8dcSSimon Schubert 	  /* Write GOT[1] and GOT[2], needed for the dynamic linker.  */
48625796c8dcSSimon Schubert 	  bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
48635796c8dcSSimon Schubert 	  bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE*2);
48645796c8dcSSimon Schubert 	}
48655796c8dcSSimon Schubert 
48665796c8dcSSimon Schubert       elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize =
48675796c8dcSSimon Schubert 	GOT_ENTRY_SIZE;
48685796c8dcSSimon Schubert     }
48695796c8dcSSimon Schubert 
4870a45ae5f8SJohn Marino   /* Adjust .eh_frame for .plt section.  */
4871*ef5ccd6cSJohn Marino   if (htab->plt_eh_frame != NULL
4872*ef5ccd6cSJohn Marino       && htab->plt_eh_frame->contents != NULL)
4873a45ae5f8SJohn Marino     {
4874a45ae5f8SJohn Marino       if (htab->elf.splt != NULL
4875a45ae5f8SJohn Marino 	  && htab->elf.splt->size != 0
4876a45ae5f8SJohn Marino 	  && (htab->elf.splt->flags & SEC_EXCLUDE) == 0
4877a45ae5f8SJohn Marino 	  && htab->elf.splt->output_section != NULL
4878a45ae5f8SJohn Marino 	  && htab->plt_eh_frame->output_section != NULL)
4879a45ae5f8SJohn Marino 	{
4880a45ae5f8SJohn Marino 	  bfd_vma plt_start = htab->elf.splt->output_section->vma;
4881a45ae5f8SJohn Marino 	  bfd_vma eh_frame_start = htab->plt_eh_frame->output_section->vma
4882a45ae5f8SJohn Marino 				   + htab->plt_eh_frame->output_offset
4883a45ae5f8SJohn Marino 				   + PLT_FDE_START_OFFSET;
4884a45ae5f8SJohn Marino 	  bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
4885a45ae5f8SJohn Marino 			     htab->plt_eh_frame->contents
4886a45ae5f8SJohn Marino 			     + PLT_FDE_START_OFFSET);
4887a45ae5f8SJohn Marino 	}
4888*ef5ccd6cSJohn Marino       if (htab->plt_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
4889a45ae5f8SJohn Marino 	{
4890a45ae5f8SJohn Marino 	  if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
4891a45ae5f8SJohn Marino 						 htab->plt_eh_frame,
4892a45ae5f8SJohn Marino 						 htab->plt_eh_frame->contents))
4893a45ae5f8SJohn Marino 	    return FALSE;
4894a45ae5f8SJohn Marino 	}
4895a45ae5f8SJohn Marino     }
4896a45ae5f8SJohn Marino 
48975796c8dcSSimon Schubert   if (htab->elf.sgot && htab->elf.sgot->size > 0)
48985796c8dcSSimon Schubert     elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
48995796c8dcSSimon Schubert       = GOT_ENTRY_SIZE;
49005796c8dcSSimon Schubert 
49015796c8dcSSimon Schubert   /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
49025796c8dcSSimon Schubert   htab_traverse (htab->loc_hash_table,
4903c50c785cSJohn Marino 		 elf_x86_64_finish_local_dynamic_symbol,
49045796c8dcSSimon Schubert 		 info);
49055796c8dcSSimon Schubert 
49065796c8dcSSimon Schubert   return TRUE;
49075796c8dcSSimon Schubert }
49085796c8dcSSimon Schubert 
49095796c8dcSSimon Schubert /* Return address for Ith PLT stub in section PLT, for relocation REL
49105796c8dcSSimon Schubert    or (bfd_vma) -1 if it should not be included.  */
49115796c8dcSSimon Schubert 
49125796c8dcSSimon Schubert static bfd_vma
elf_x86_64_plt_sym_val(bfd_vma i,const asection * plt,const arelent * rel ATTRIBUTE_UNUSED)4913c50c785cSJohn Marino elf_x86_64_plt_sym_val (bfd_vma i, const asection *plt,
49145796c8dcSSimon Schubert 			const arelent *rel ATTRIBUTE_UNUSED)
49155796c8dcSSimon Schubert {
4916*ef5ccd6cSJohn Marino   return plt->vma + (i + 1) * GET_PLT_ENTRY_SIZE (plt->owner);
49175796c8dcSSimon Schubert }
49185796c8dcSSimon Schubert 
49195796c8dcSSimon Schubert /* Handle an x86-64 specific section when reading an object file.  This
49205796c8dcSSimon Schubert    is called when elfcode.h finds a section with an unknown type.  */
49215796c8dcSSimon Schubert 
49225796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_section_from_shdr(bfd * abfd,Elf_Internal_Shdr * hdr,const char * name,int shindex)4923c50c785cSJohn Marino elf_x86_64_section_from_shdr (bfd *abfd,
49245796c8dcSSimon Schubert 				Elf_Internal_Shdr *hdr,
49255796c8dcSSimon Schubert 				const char *name,
49265796c8dcSSimon Schubert 				int shindex)
49275796c8dcSSimon Schubert {
49285796c8dcSSimon Schubert   if (hdr->sh_type != SHT_X86_64_UNWIND)
49295796c8dcSSimon Schubert     return FALSE;
49305796c8dcSSimon Schubert 
49315796c8dcSSimon Schubert   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
49325796c8dcSSimon Schubert     return FALSE;
49335796c8dcSSimon Schubert 
49345796c8dcSSimon Schubert   return TRUE;
49355796c8dcSSimon Schubert }
49365796c8dcSSimon Schubert 
49375796c8dcSSimon Schubert /* Hook called by the linker routine which adds symbols from an object
49385796c8dcSSimon Schubert    file.  We use it to put SHN_X86_64_LCOMMON items in .lbss, instead
49395796c8dcSSimon Schubert    of .bss.  */
49405796c8dcSSimon Schubert 
49415796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_add_symbol_hook(bfd * abfd,struct bfd_link_info * info,Elf_Internal_Sym * sym,const char ** namep ATTRIBUTE_UNUSED,flagword * flagsp ATTRIBUTE_UNUSED,asection ** secp,bfd_vma * valp)4942c50c785cSJohn Marino elf_x86_64_add_symbol_hook (bfd *abfd,
49435796c8dcSSimon Schubert 			    struct bfd_link_info *info,
49445796c8dcSSimon Schubert 			    Elf_Internal_Sym *sym,
49455796c8dcSSimon Schubert 			    const char **namep ATTRIBUTE_UNUSED,
49465796c8dcSSimon Schubert 			    flagword *flagsp ATTRIBUTE_UNUSED,
49475796c8dcSSimon Schubert 			    asection **secp,
49485796c8dcSSimon Schubert 			    bfd_vma *valp)
49495796c8dcSSimon Schubert {
49505796c8dcSSimon Schubert   asection *lcomm;
49515796c8dcSSimon Schubert 
49525796c8dcSSimon Schubert   switch (sym->st_shndx)
49535796c8dcSSimon Schubert     {
49545796c8dcSSimon Schubert     case SHN_X86_64_LCOMMON:
49555796c8dcSSimon Schubert       lcomm = bfd_get_section_by_name (abfd, "LARGE_COMMON");
49565796c8dcSSimon Schubert       if (lcomm == NULL)
49575796c8dcSSimon Schubert 	{
49585796c8dcSSimon Schubert 	  lcomm = bfd_make_section_with_flags (abfd,
49595796c8dcSSimon Schubert 					       "LARGE_COMMON",
49605796c8dcSSimon Schubert 					       (SEC_ALLOC
49615796c8dcSSimon Schubert 						| SEC_IS_COMMON
49625796c8dcSSimon Schubert 						| SEC_LINKER_CREATED));
49635796c8dcSSimon Schubert 	  if (lcomm == NULL)
49645796c8dcSSimon Schubert 	    return FALSE;
49655796c8dcSSimon Schubert 	  elf_section_flags (lcomm) |= SHF_X86_64_LARGE;
49665796c8dcSSimon Schubert 	}
49675796c8dcSSimon Schubert       *secp = lcomm;
49685796c8dcSSimon Schubert       *valp = sym->st_size;
4969cf7f2e2dSJohn Marino       return TRUE;
49705796c8dcSSimon Schubert     }
49715796c8dcSSimon Schubert 
4972cf7f2e2dSJohn Marino   if ((abfd->flags & DYNAMIC) == 0
4973a45ae5f8SJohn Marino       && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
4974a45ae5f8SJohn Marino 	  || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
4975a45ae5f8SJohn Marino     elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
49765796c8dcSSimon Schubert 
49775796c8dcSSimon Schubert   return TRUE;
49785796c8dcSSimon Schubert }
49795796c8dcSSimon Schubert 
49805796c8dcSSimon Schubert 
49815796c8dcSSimon Schubert /* Given a BFD section, try to locate the corresponding ELF section
49825796c8dcSSimon Schubert    index.  */
49835796c8dcSSimon Schubert 
49845796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_elf_section_from_bfd_section(bfd * abfd ATTRIBUTE_UNUSED,asection * sec,int * index_return)4985c50c785cSJohn Marino elf_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
4986cf7f2e2dSJohn Marino 					 asection *sec, int *index_return)
49875796c8dcSSimon Schubert {
49885796c8dcSSimon Schubert   if (sec == &_bfd_elf_large_com_section)
49895796c8dcSSimon Schubert     {
4990cf7f2e2dSJohn Marino       *index_return = SHN_X86_64_LCOMMON;
49915796c8dcSSimon Schubert       return TRUE;
49925796c8dcSSimon Schubert     }
49935796c8dcSSimon Schubert   return FALSE;
49945796c8dcSSimon Schubert }
49955796c8dcSSimon Schubert 
49965796c8dcSSimon Schubert /* Process a symbol.  */
49975796c8dcSSimon Schubert 
49985796c8dcSSimon Schubert static void
elf_x86_64_symbol_processing(bfd * abfd ATTRIBUTE_UNUSED,asymbol * asym)4999c50c785cSJohn Marino elf_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
50005796c8dcSSimon Schubert 			      asymbol *asym)
50015796c8dcSSimon Schubert {
50025796c8dcSSimon Schubert   elf_symbol_type *elfsym = (elf_symbol_type *) asym;
50035796c8dcSSimon Schubert 
50045796c8dcSSimon Schubert   switch (elfsym->internal_elf_sym.st_shndx)
50055796c8dcSSimon Schubert     {
50065796c8dcSSimon Schubert     case SHN_X86_64_LCOMMON:
50075796c8dcSSimon Schubert       asym->section = &_bfd_elf_large_com_section;
50085796c8dcSSimon Schubert       asym->value = elfsym->internal_elf_sym.st_size;
50095796c8dcSSimon Schubert       /* Common symbol doesn't set BSF_GLOBAL.  */
50105796c8dcSSimon Schubert       asym->flags &= ~BSF_GLOBAL;
50115796c8dcSSimon Schubert       break;
50125796c8dcSSimon Schubert     }
50135796c8dcSSimon Schubert }
50145796c8dcSSimon Schubert 
50155796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_common_definition(Elf_Internal_Sym * sym)5016c50c785cSJohn Marino elf_x86_64_common_definition (Elf_Internal_Sym *sym)
50175796c8dcSSimon Schubert {
50185796c8dcSSimon Schubert   return (sym->st_shndx == SHN_COMMON
50195796c8dcSSimon Schubert 	  || sym->st_shndx == SHN_X86_64_LCOMMON);
50205796c8dcSSimon Schubert }
50215796c8dcSSimon Schubert 
50225796c8dcSSimon Schubert static unsigned int
elf_x86_64_common_section_index(asection * sec)5023c50c785cSJohn Marino elf_x86_64_common_section_index (asection *sec)
50245796c8dcSSimon Schubert {
50255796c8dcSSimon Schubert   if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
50265796c8dcSSimon Schubert     return SHN_COMMON;
50275796c8dcSSimon Schubert   else
50285796c8dcSSimon Schubert     return SHN_X86_64_LCOMMON;
50295796c8dcSSimon Schubert }
50305796c8dcSSimon Schubert 
50315796c8dcSSimon Schubert static asection *
elf_x86_64_common_section(asection * sec)5032c50c785cSJohn Marino elf_x86_64_common_section (asection *sec)
50335796c8dcSSimon Schubert {
50345796c8dcSSimon Schubert   if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
50355796c8dcSSimon Schubert     return bfd_com_section_ptr;
50365796c8dcSSimon Schubert   else
50375796c8dcSSimon Schubert     return &_bfd_elf_large_com_section;
50385796c8dcSSimon Schubert }
50395796c8dcSSimon Schubert 
50405796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_merge_symbol(struct bfd_link_info * info ATTRIBUTE_UNUSED,struct elf_link_hash_entry ** sym_hash ATTRIBUTE_UNUSED,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym,asection ** psec,bfd_vma * pvalue ATTRIBUTE_UNUSED,unsigned int * pold_alignment ATTRIBUTE_UNUSED,bfd_boolean * skip ATTRIBUTE_UNUSED,bfd_boolean * override ATTRIBUTE_UNUSED,bfd_boolean * type_change_ok ATTRIBUTE_UNUSED,bfd_boolean * size_change_ok ATTRIBUTE_UNUSED,bfd_boolean * newdyn ATTRIBUTE_UNUSED,bfd_boolean * newdef,bfd_boolean * newdyncommon ATTRIBUTE_UNUSED,bfd_boolean * newweak ATTRIBUTE_UNUSED,bfd * abfd ATTRIBUTE_UNUSED,asection ** sec,bfd_boolean * olddyn ATTRIBUTE_UNUSED,bfd_boolean * olddef,bfd_boolean * olddyncommon ATTRIBUTE_UNUSED,bfd_boolean * oldweak ATTRIBUTE_UNUSED,bfd * oldbfd,asection ** oldsec)5041c50c785cSJohn Marino elf_x86_64_merge_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
50425796c8dcSSimon Schubert 			 struct elf_link_hash_entry **sym_hash ATTRIBUTE_UNUSED,
50435796c8dcSSimon Schubert 			 struct elf_link_hash_entry *h,
50445796c8dcSSimon Schubert 			 Elf_Internal_Sym *sym,
50455796c8dcSSimon Schubert 			 asection **psec,
50465796c8dcSSimon Schubert 			 bfd_vma *pvalue ATTRIBUTE_UNUSED,
50475796c8dcSSimon Schubert 			 unsigned int *pold_alignment ATTRIBUTE_UNUSED,
50485796c8dcSSimon Schubert 			 bfd_boolean *skip ATTRIBUTE_UNUSED,
50495796c8dcSSimon Schubert 			 bfd_boolean *override ATTRIBUTE_UNUSED,
50505796c8dcSSimon Schubert 			 bfd_boolean *type_change_ok ATTRIBUTE_UNUSED,
50515796c8dcSSimon Schubert 			 bfd_boolean *size_change_ok ATTRIBUTE_UNUSED,
5052a45ae5f8SJohn Marino 			 bfd_boolean *newdyn ATTRIBUTE_UNUSED,
5053a45ae5f8SJohn Marino 			 bfd_boolean *newdef,
50545796c8dcSSimon Schubert 			 bfd_boolean *newdyncommon ATTRIBUTE_UNUSED,
50555796c8dcSSimon Schubert 			 bfd_boolean *newweak ATTRIBUTE_UNUSED,
50565796c8dcSSimon Schubert 			 bfd *abfd ATTRIBUTE_UNUSED,
50575796c8dcSSimon Schubert 			 asection **sec,
5058a45ae5f8SJohn Marino 			 bfd_boolean *olddyn ATTRIBUTE_UNUSED,
5059a45ae5f8SJohn Marino 			 bfd_boolean *olddef,
50605796c8dcSSimon Schubert 			 bfd_boolean *olddyncommon ATTRIBUTE_UNUSED,
50615796c8dcSSimon Schubert 			 bfd_boolean *oldweak ATTRIBUTE_UNUSED,
50625796c8dcSSimon Schubert 			 bfd *oldbfd,
50635796c8dcSSimon Schubert 			 asection **oldsec)
50645796c8dcSSimon Schubert {
50655796c8dcSSimon Schubert   /* A normal common symbol and a large common symbol result in a
50665796c8dcSSimon Schubert      normal common symbol.  We turn the large common symbol into a
50675796c8dcSSimon Schubert      normal one.  */
5068a45ae5f8SJohn Marino   if (!*olddef
50695796c8dcSSimon Schubert       && h->root.type == bfd_link_hash_common
5070a45ae5f8SJohn Marino       && !*newdef
50715796c8dcSSimon Schubert       && bfd_is_com_section (*sec)
50725796c8dcSSimon Schubert       && *oldsec != *sec)
50735796c8dcSSimon Schubert     {
50745796c8dcSSimon Schubert       if (sym->st_shndx == SHN_COMMON
50755796c8dcSSimon Schubert 	  && (elf_section_flags (*oldsec) & SHF_X86_64_LARGE) != 0)
50765796c8dcSSimon Schubert 	{
50775796c8dcSSimon Schubert 	  h->root.u.c.p->section
50785796c8dcSSimon Schubert 	    = bfd_make_section_old_way (oldbfd, "COMMON");
50795796c8dcSSimon Schubert 	  h->root.u.c.p->section->flags = SEC_ALLOC;
50805796c8dcSSimon Schubert 	}
50815796c8dcSSimon Schubert       else if (sym->st_shndx == SHN_X86_64_LCOMMON
50825796c8dcSSimon Schubert 	       && (elf_section_flags (*oldsec) & SHF_X86_64_LARGE) == 0)
50835796c8dcSSimon Schubert 	*psec = *sec = bfd_com_section_ptr;
50845796c8dcSSimon Schubert     }
50855796c8dcSSimon Schubert 
50865796c8dcSSimon Schubert   return TRUE;
50875796c8dcSSimon Schubert }
50885796c8dcSSimon Schubert 
50895796c8dcSSimon Schubert static int
elf_x86_64_additional_program_headers(bfd * abfd,struct bfd_link_info * info ATTRIBUTE_UNUSED)5090c50c785cSJohn Marino elf_x86_64_additional_program_headers (bfd *abfd,
50915796c8dcSSimon Schubert 				       struct bfd_link_info *info ATTRIBUTE_UNUSED)
50925796c8dcSSimon Schubert {
50935796c8dcSSimon Schubert   asection *s;
50945796c8dcSSimon Schubert   int count = 0;
50955796c8dcSSimon Schubert 
50965796c8dcSSimon Schubert   /* Check to see if we need a large readonly segment.  */
50975796c8dcSSimon Schubert   s = bfd_get_section_by_name (abfd, ".lrodata");
50985796c8dcSSimon Schubert   if (s && (s->flags & SEC_LOAD))
50995796c8dcSSimon Schubert     count++;
51005796c8dcSSimon Schubert 
51015796c8dcSSimon Schubert   /* Check to see if we need a large data segment.  Since .lbss sections
51025796c8dcSSimon Schubert      is placed right after the .bss section, there should be no need for
51035796c8dcSSimon Schubert      a large data segment just because of .lbss.  */
51045796c8dcSSimon Schubert   s = bfd_get_section_by_name (abfd, ".ldata");
51055796c8dcSSimon Schubert   if (s && (s->flags & SEC_LOAD))
51065796c8dcSSimon Schubert     count++;
51075796c8dcSSimon Schubert 
51085796c8dcSSimon Schubert   return count;
51095796c8dcSSimon Schubert }
51105796c8dcSSimon Schubert 
51115796c8dcSSimon Schubert /* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
51125796c8dcSSimon Schubert 
51135796c8dcSSimon Schubert static bfd_boolean
elf_x86_64_hash_symbol(struct elf_link_hash_entry * h)5114c50c785cSJohn Marino elf_x86_64_hash_symbol (struct elf_link_hash_entry *h)
51155796c8dcSSimon Schubert {
51165796c8dcSSimon Schubert   if (h->plt.offset != (bfd_vma) -1
51175796c8dcSSimon Schubert       && !h->def_regular
51185796c8dcSSimon Schubert       && !h->pointer_equality_needed)
51195796c8dcSSimon Schubert     return FALSE;
51205796c8dcSSimon Schubert 
51215796c8dcSSimon Schubert   return _bfd_elf_hash_symbol (h);
51225796c8dcSSimon Schubert }
51235796c8dcSSimon Schubert 
5124c50c785cSJohn Marino /* Return TRUE iff relocations for INPUT are compatible with OUTPUT. */
5125c50c785cSJohn Marino 
5126c50c785cSJohn Marino static bfd_boolean
elf_x86_64_relocs_compatible(const bfd_target * input,const bfd_target * output)5127c50c785cSJohn Marino elf_x86_64_relocs_compatible (const bfd_target *input,
5128c50c785cSJohn Marino 			      const bfd_target *output)
5129c50c785cSJohn Marino {
5130c50c785cSJohn Marino   return ((xvec_get_elf_backend_data (input)->s->elfclass
5131c50c785cSJohn Marino 	   == xvec_get_elf_backend_data (output)->s->elfclass)
5132c50c785cSJohn Marino 	  && _bfd_elf_relocs_compatible (input, output));
5133c50c785cSJohn Marino }
5134c50c785cSJohn Marino 
51355796c8dcSSimon Schubert static const struct bfd_elf_special_section
5136c50c785cSJohn Marino   elf_x86_64_special_sections[]=
51375796c8dcSSimon Schubert {
51385796c8dcSSimon Schubert   { STRING_COMMA_LEN (".gnu.linkonce.lb"), -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
51395796c8dcSSimon Schubert   { STRING_COMMA_LEN (".gnu.linkonce.lr"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
51405796c8dcSSimon Schubert   { STRING_COMMA_LEN (".gnu.linkonce.lt"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR + SHF_X86_64_LARGE},
51415796c8dcSSimon Schubert   { STRING_COMMA_LEN (".lbss"),	           -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
51425796c8dcSSimon Schubert   { STRING_COMMA_LEN (".ldata"),	   -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
51435796c8dcSSimon Schubert   { STRING_COMMA_LEN (".lrodata"),	   -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
51445796c8dcSSimon Schubert   { NULL,	                0,          0, 0,            0 }
51455796c8dcSSimon Schubert };
51465796c8dcSSimon Schubert 
51475796c8dcSSimon Schubert #define TARGET_LITTLE_SYM		    bfd_elf64_x86_64_vec
51485796c8dcSSimon Schubert #define TARGET_LITTLE_NAME		    "elf64-x86-64"
51495796c8dcSSimon Schubert #define ELF_ARCH			    bfd_arch_i386
5150c50c785cSJohn Marino #define ELF_TARGET_ID			    X86_64_ELF_DATA
51515796c8dcSSimon Schubert #define ELF_MACHINE_CODE		    EM_X86_64
51525796c8dcSSimon Schubert #define ELF_MAXPAGESIZE			    0x200000
51535796c8dcSSimon Schubert #define ELF_MINPAGESIZE			    0x1000
51545796c8dcSSimon Schubert #define ELF_COMMONPAGESIZE		    0x1000
51555796c8dcSSimon Schubert 
51565796c8dcSSimon Schubert #define elf_backend_can_gc_sections	    1
51575796c8dcSSimon Schubert #define elf_backend_can_refcount	    1
51585796c8dcSSimon Schubert #define elf_backend_want_got_plt	    1
51595796c8dcSSimon Schubert #define elf_backend_plt_readonly	    1
51605796c8dcSSimon Schubert #define elf_backend_want_plt_sym	    0
51615796c8dcSSimon Schubert #define elf_backend_got_header_size	    (GOT_ENTRY_SIZE*3)
51625796c8dcSSimon Schubert #define elf_backend_rela_normal		    1
5163a45ae5f8SJohn Marino #define elf_backend_plt_alignment           4
51645796c8dcSSimon Schubert 
5165c50c785cSJohn Marino #define elf_info_to_howto		    elf_x86_64_info_to_howto
51665796c8dcSSimon Schubert 
51675796c8dcSSimon Schubert #define bfd_elf64_bfd_link_hash_table_create \
5168c50c785cSJohn Marino   elf_x86_64_link_hash_table_create
51695796c8dcSSimon Schubert #define bfd_elf64_bfd_link_hash_table_free \
5170c50c785cSJohn Marino   elf_x86_64_link_hash_table_free
5171c50c785cSJohn Marino #define bfd_elf64_bfd_reloc_type_lookup	    elf_x86_64_reloc_type_lookup
51725796c8dcSSimon Schubert #define bfd_elf64_bfd_reloc_name_lookup \
5173c50c785cSJohn Marino   elf_x86_64_reloc_name_lookup
51745796c8dcSSimon Schubert 
5175c50c785cSJohn Marino #define elf_backend_adjust_dynamic_symbol   elf_x86_64_adjust_dynamic_symbol
5176c50c785cSJohn Marino #define elf_backend_relocs_compatible	    elf_x86_64_relocs_compatible
5177c50c785cSJohn Marino #define elf_backend_check_relocs	    elf_x86_64_check_relocs
5178c50c785cSJohn Marino #define elf_backend_copy_indirect_symbol    elf_x86_64_copy_indirect_symbol
5179c50c785cSJohn Marino #define elf_backend_create_dynamic_sections elf_x86_64_create_dynamic_sections
5180c50c785cSJohn Marino #define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections
5181c50c785cSJohn Marino #define elf_backend_finish_dynamic_symbol   elf_x86_64_finish_dynamic_symbol
5182c50c785cSJohn Marino #define elf_backend_gc_mark_hook	    elf_x86_64_gc_mark_hook
5183c50c785cSJohn Marino #define elf_backend_gc_sweep_hook	    elf_x86_64_gc_sweep_hook
5184c50c785cSJohn Marino #define elf_backend_grok_prstatus	    elf_x86_64_grok_prstatus
5185c50c785cSJohn Marino #define elf_backend_grok_psinfo		    elf_x86_64_grok_psinfo
5186a45ae5f8SJohn Marino #ifdef CORE_HEADER
5187a45ae5f8SJohn Marino #define elf_backend_write_core_note	    elf_x86_64_write_core_note
5188a45ae5f8SJohn Marino #endif
5189c50c785cSJohn Marino #define elf_backend_reloc_type_class	    elf_x86_64_reloc_type_class
5190c50c785cSJohn Marino #define elf_backend_relocate_section	    elf_x86_64_relocate_section
5191c50c785cSJohn Marino #define elf_backend_size_dynamic_sections   elf_x86_64_size_dynamic_sections
5192c50c785cSJohn Marino #define elf_backend_always_size_sections    elf_x86_64_always_size_sections
51935796c8dcSSimon Schubert #define elf_backend_init_index_section	    _bfd_elf_init_1_index_section
5194c50c785cSJohn Marino #define elf_backend_plt_sym_val		    elf_x86_64_plt_sym_val
51955796c8dcSSimon Schubert #define elf_backend_object_p		    elf64_x86_64_elf_object_p
5196c50c785cSJohn Marino #define bfd_elf64_mkobject		    elf_x86_64_mkobject
51975796c8dcSSimon Schubert 
51985796c8dcSSimon Schubert #define elf_backend_section_from_shdr \
5199c50c785cSJohn Marino 	elf_x86_64_section_from_shdr
52005796c8dcSSimon Schubert 
52015796c8dcSSimon Schubert #define elf_backend_section_from_bfd_section \
5202c50c785cSJohn Marino   elf_x86_64_elf_section_from_bfd_section
52035796c8dcSSimon Schubert #define elf_backend_add_symbol_hook \
5204c50c785cSJohn Marino   elf_x86_64_add_symbol_hook
52055796c8dcSSimon Schubert #define elf_backend_symbol_processing \
5206c50c785cSJohn Marino   elf_x86_64_symbol_processing
52075796c8dcSSimon Schubert #define elf_backend_common_section_index \
5208c50c785cSJohn Marino   elf_x86_64_common_section_index
52095796c8dcSSimon Schubert #define elf_backend_common_section \
5210c50c785cSJohn Marino   elf_x86_64_common_section
52115796c8dcSSimon Schubert #define elf_backend_common_definition \
5212c50c785cSJohn Marino   elf_x86_64_common_definition
52135796c8dcSSimon Schubert #define elf_backend_merge_symbol \
5214c50c785cSJohn Marino   elf_x86_64_merge_symbol
52155796c8dcSSimon Schubert #define elf_backend_special_sections \
5216c50c785cSJohn Marino   elf_x86_64_special_sections
52175796c8dcSSimon Schubert #define elf_backend_additional_program_headers \
5218c50c785cSJohn Marino   elf_x86_64_additional_program_headers
52195796c8dcSSimon Schubert #define elf_backend_hash_symbol \
5220c50c785cSJohn Marino   elf_x86_64_hash_symbol
52215796c8dcSSimon Schubert 
52225796c8dcSSimon Schubert #define elf_backend_post_process_headers  _bfd_elf_set_osabi
52235796c8dcSSimon Schubert 
52245796c8dcSSimon Schubert #include "elf64-target.h"
52255796c8dcSSimon Schubert 
52265796c8dcSSimon Schubert /* FreeBSD support.  */
52275796c8dcSSimon Schubert 
52285796c8dcSSimon Schubert #undef  TARGET_LITTLE_SYM
52295796c8dcSSimon Schubert #define TARGET_LITTLE_SYM		    bfd_elf64_x86_64_freebsd_vec
52305796c8dcSSimon Schubert #undef  TARGET_LITTLE_NAME
52315796c8dcSSimon Schubert #define TARGET_LITTLE_NAME		    "elf64-x86-64-freebsd"
52325796c8dcSSimon Schubert 
52335796c8dcSSimon Schubert #undef	ELF_OSABI
52345796c8dcSSimon Schubert #define	ELF_OSABI			    ELFOSABI_FREEBSD
52355796c8dcSSimon Schubert 
52365796c8dcSSimon Schubert #undef  elf64_bed
52375796c8dcSSimon Schubert #define elf64_bed elf64_x86_64_fbsd_bed
52385796c8dcSSimon Schubert 
52395796c8dcSSimon Schubert #include "elf64-target.h"
52405796c8dcSSimon Schubert 
5241cf7f2e2dSJohn Marino /* Solaris 2 support.  */
5242cf7f2e2dSJohn Marino 
5243cf7f2e2dSJohn Marino #undef  TARGET_LITTLE_SYM
5244cf7f2e2dSJohn Marino #define TARGET_LITTLE_SYM		    bfd_elf64_x86_64_sol2_vec
5245cf7f2e2dSJohn Marino #undef  TARGET_LITTLE_NAME
5246cf7f2e2dSJohn Marino #define TARGET_LITTLE_NAME		    "elf64-x86-64-sol2"
5247cf7f2e2dSJohn Marino 
5248cf7f2e2dSJohn Marino /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
5249cf7f2e2dSJohn Marino    objects won't be recognized.  */
5250cf7f2e2dSJohn Marino #undef ELF_OSABI
5251cf7f2e2dSJohn Marino 
5252cf7f2e2dSJohn Marino #undef  elf64_bed
5253cf7f2e2dSJohn Marino #define elf64_bed			    elf64_x86_64_sol2_bed
5254cf7f2e2dSJohn Marino 
5255c50c785cSJohn Marino /* The 64-bit static TLS arena size is rounded to the nearest 16-byte
5256c50c785cSJohn Marino    boundary.  */
5257c50c785cSJohn Marino #undef elf_backend_static_tls_alignment
5258c50c785cSJohn Marino #define elf_backend_static_tls_alignment    16
5259c50c785cSJohn Marino 
5260cf7f2e2dSJohn Marino /* The Solaris 2 ABI requires a plt symbol on all platforms.
5261cf7f2e2dSJohn Marino 
5262cf7f2e2dSJohn Marino    Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
5263cf7f2e2dSJohn Marino    File, p.63.  */
5264cf7f2e2dSJohn Marino #undef elf_backend_want_plt_sym
5265cf7f2e2dSJohn Marino #define elf_backend_want_plt_sym	    1
5266cf7f2e2dSJohn Marino 
5267cf7f2e2dSJohn Marino #include "elf64-target.h"
5268cf7f2e2dSJohn Marino 
5269*ef5ccd6cSJohn Marino /* Native Client support.  */
5270*ef5ccd6cSJohn Marino 
5271*ef5ccd6cSJohn Marino #undef	TARGET_LITTLE_SYM
5272*ef5ccd6cSJohn Marino #define	TARGET_LITTLE_SYM		bfd_elf64_x86_64_nacl_vec
5273*ef5ccd6cSJohn Marino #undef	TARGET_LITTLE_NAME
5274*ef5ccd6cSJohn Marino #define	TARGET_LITTLE_NAME		"elf64-x86-64-nacl"
5275*ef5ccd6cSJohn Marino #undef	elf64_bed
5276*ef5ccd6cSJohn Marino #define	elf64_bed			elf64_x86_64_nacl_bed
5277*ef5ccd6cSJohn Marino 
5278*ef5ccd6cSJohn Marino #undef	ELF_MAXPAGESIZE
5279*ef5ccd6cSJohn Marino #undef	ELF_MINPAGESIZE
5280*ef5ccd6cSJohn Marino #undef	ELF_COMMONPAGESIZE
5281*ef5ccd6cSJohn Marino #define ELF_MAXPAGESIZE			0x10000
5282*ef5ccd6cSJohn Marino #define ELF_MINPAGESIZE			0x10000
5283*ef5ccd6cSJohn Marino #define ELF_COMMONPAGESIZE		0x10000
5284*ef5ccd6cSJohn Marino 
5285*ef5ccd6cSJohn Marino /* Restore defaults.  */
5286*ef5ccd6cSJohn Marino #undef	ELF_OSABI
5287*ef5ccd6cSJohn Marino #undef	elf_backend_static_tls_alignment
5288*ef5ccd6cSJohn Marino #undef	elf_backend_want_plt_sym
5289*ef5ccd6cSJohn Marino #define elf_backend_want_plt_sym	0
5290*ef5ccd6cSJohn Marino 
5291*ef5ccd6cSJohn Marino /* NaCl uses substantially different PLT entries for the same effects.  */
5292*ef5ccd6cSJohn Marino 
5293*ef5ccd6cSJohn Marino #undef	elf_backend_plt_alignment
5294*ef5ccd6cSJohn Marino #define elf_backend_plt_alignment	5
5295*ef5ccd6cSJohn Marino #define NACL_PLT_ENTRY_SIZE		64
5296*ef5ccd6cSJohn Marino #define	NACLMASK			0xe0 /* 32-byte alignment mask.  */
5297*ef5ccd6cSJohn Marino 
5298*ef5ccd6cSJohn Marino static const bfd_byte elf_x86_64_nacl_plt0_entry[NACL_PLT_ENTRY_SIZE] =
5299*ef5ccd6cSJohn Marino   {
5300*ef5ccd6cSJohn Marino     0xff, 0x35, 8, 0, 0, 0,             /* pushq GOT+8(%rip) 		*/
5301*ef5ccd6cSJohn Marino     0x4c, 0x8b, 0x1d, 16, 0, 0, 0,	/* mov GOT+16(%rip), %r11	*/
5302*ef5ccd6cSJohn Marino     0x41, 0x83, 0xe3, NACLMASK,         /* and $-32, %r11d		*/
5303*ef5ccd6cSJohn Marino     0x4d, 0x01, 0xfb,             	/* add %r15, %r11		*/
5304*ef5ccd6cSJohn Marino     0x41, 0xff, 0xe3,             	/* jmpq *%r11			*/
5305*ef5ccd6cSJohn Marino 
5306*ef5ccd6cSJohn Marino     /* 9-byte nop sequence to pad out to the next 32-byte boundary.  */
5307*ef5ccd6cSJohn Marino     0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopl %cs:0x0(%rax,%rax,1)	*/
5308*ef5ccd6cSJohn Marino 
5309*ef5ccd6cSJohn Marino     /* 32 bytes of nop to pad out to the standard size.  */
5310*ef5ccd6cSJohn Marino     0x66, 0x66, 0x66, 0x66, 0x66, 0x66,    /* excess data32 prefixes	*/
5311*ef5ccd6cSJohn Marino     0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1)	*/
5312*ef5ccd6cSJohn Marino     0x66, 0x66, 0x66, 0x66, 0x66, 0x66,    /* excess data32 prefixes	*/
5313*ef5ccd6cSJohn Marino     0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1)	*/
5314*ef5ccd6cSJohn Marino     0x66,                                  /* excess data32 prefix	*/
5315*ef5ccd6cSJohn Marino     0x90                                   /* nop */
5316*ef5ccd6cSJohn Marino   };
5317*ef5ccd6cSJohn Marino 
5318*ef5ccd6cSJohn Marino static const bfd_byte elf_x86_64_nacl_plt_entry[NACL_PLT_ENTRY_SIZE] =
5319*ef5ccd6cSJohn Marino   {
5320*ef5ccd6cSJohn Marino     0x4c, 0x8b, 0x1d, 0, 0, 0, 0,	/* mov name@GOTPCREL(%rip),%r11	*/
5321*ef5ccd6cSJohn Marino     0x41, 0x83, 0xe3, NACLMASK,         /* and $-32, %r11d		*/
5322*ef5ccd6cSJohn Marino     0x4d, 0x01, 0xfb,             	/* add %r15, %r11		*/
5323*ef5ccd6cSJohn Marino     0x41, 0xff, 0xe3,             	/* jmpq *%r11			*/
5324*ef5ccd6cSJohn Marino 
5325*ef5ccd6cSJohn Marino     /* 15-byte nop sequence to pad out to the next 32-byte boundary.  */
5326*ef5ccd6cSJohn Marino     0x66, 0x66, 0x66, 0x66, 0x66, 0x66,    /* excess data32 prefixes	*/
5327*ef5ccd6cSJohn Marino     0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1)	*/
5328*ef5ccd6cSJohn Marino 
5329*ef5ccd6cSJohn Marino     /* Lazy GOT entries point here (32-byte aligned).  */
5330*ef5ccd6cSJohn Marino     0x68,                 /* pushq immediate */
5331*ef5ccd6cSJohn Marino     0, 0, 0, 0,           /* replaced with index into relocation table.  */
5332*ef5ccd6cSJohn Marino     0xe9,                 /* jmp relative */
5333*ef5ccd6cSJohn Marino     0, 0, 0, 0,           /* replaced with offset to start of .plt0.  */
5334*ef5ccd6cSJohn Marino 
5335*ef5ccd6cSJohn Marino     /* 22 bytes of nop to pad out to the standard size.  */
5336*ef5ccd6cSJohn Marino     0x66, 0x66, 0x66, 0x66, 0x66, 0x66,    /* excess data32 prefixes	*/
5337*ef5ccd6cSJohn Marino     0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1)	*/
5338*ef5ccd6cSJohn Marino     0x0f, 0x1f, 0x80, 0, 0, 0, 0,          /* nopl 0x0(%rax)		*/
5339*ef5ccd6cSJohn Marino   };
5340*ef5ccd6cSJohn Marino 
5341*ef5ccd6cSJohn Marino /* .eh_frame covering the .plt section.  */
5342*ef5ccd6cSJohn Marino 
5343*ef5ccd6cSJohn Marino static const bfd_byte elf_x86_64_nacl_eh_frame_plt[] =
5344*ef5ccd6cSJohn Marino   {
5345*ef5ccd6cSJohn Marino #if (PLT_CIE_LENGTH != 20                               \
5346*ef5ccd6cSJohn Marino      || PLT_FDE_LENGTH != 36                            \
5347*ef5ccd6cSJohn Marino      || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8  \
5348*ef5ccd6cSJohn Marino      || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12)
5349*ef5ccd6cSJohn Marino # error "Need elf_x86_64_backend_data parameters for eh_frame_plt offsets!"
5350*ef5ccd6cSJohn Marino #endif
5351*ef5ccd6cSJohn Marino     PLT_CIE_LENGTH, 0, 0, 0,	/* CIE length */
5352*ef5ccd6cSJohn Marino     0, 0, 0, 0,			/* CIE ID */
5353*ef5ccd6cSJohn Marino     1,				/* CIE version */
5354*ef5ccd6cSJohn Marino     'z', 'R', 0,                /* Augmentation string */
5355*ef5ccd6cSJohn Marino     1,				/* Code alignment factor */
5356*ef5ccd6cSJohn Marino     0x78,                       /* Data alignment factor */
5357*ef5ccd6cSJohn Marino     16,				/* Return address column */
5358*ef5ccd6cSJohn Marino     1,				/* Augmentation size */
5359*ef5ccd6cSJohn Marino     DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
5360*ef5ccd6cSJohn Marino     DW_CFA_def_cfa, 7, 8,	/* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
5361*ef5ccd6cSJohn Marino     DW_CFA_offset + 16, 1,	/* DW_CFA_offset: r16 (rip) at cfa-8 */
5362*ef5ccd6cSJohn Marino     DW_CFA_nop, DW_CFA_nop,
5363*ef5ccd6cSJohn Marino 
5364*ef5ccd6cSJohn Marino     PLT_FDE_LENGTH, 0, 0, 0,	/* FDE length */
5365*ef5ccd6cSJohn Marino     PLT_CIE_LENGTH + 8, 0, 0, 0,/* CIE pointer */
5366*ef5ccd6cSJohn Marino     0, 0, 0, 0,			/* R_X86_64_PC32 .plt goes here */
5367*ef5ccd6cSJohn Marino     0, 0, 0, 0,			/* .plt size goes here */
5368*ef5ccd6cSJohn Marino     0,				/* Augmentation size */
5369*ef5ccd6cSJohn Marino     DW_CFA_def_cfa_offset, 16,	/* DW_CFA_def_cfa_offset: 16 */
5370*ef5ccd6cSJohn Marino     DW_CFA_advance_loc + 6,	/* DW_CFA_advance_loc: 6 to __PLT__+6 */
5371*ef5ccd6cSJohn Marino     DW_CFA_def_cfa_offset, 24,	/* DW_CFA_def_cfa_offset: 24 */
5372*ef5ccd6cSJohn Marino     DW_CFA_advance_loc + 58,	/* DW_CFA_advance_loc: 58 to __PLT__+64 */
5373*ef5ccd6cSJohn Marino     DW_CFA_def_cfa_expression,	/* DW_CFA_def_cfa_expression */
5374*ef5ccd6cSJohn Marino     13,				/* Block length */
5375*ef5ccd6cSJohn Marino     DW_OP_breg7, 8,		/* DW_OP_breg7 (rsp): 8 */
5376*ef5ccd6cSJohn Marino     DW_OP_breg16, 0,		/* DW_OP_breg16 (rip): 0 */
5377*ef5ccd6cSJohn Marino     DW_OP_const1u, 63, DW_OP_and, DW_OP_const1u, 37, DW_OP_ge,
5378*ef5ccd6cSJohn Marino     DW_OP_lit3, DW_OP_shl, DW_OP_plus,
5379*ef5ccd6cSJohn Marino     DW_CFA_nop, DW_CFA_nop
5380*ef5ccd6cSJohn Marino   };
5381*ef5ccd6cSJohn Marino 
5382*ef5ccd6cSJohn Marino static const struct elf_x86_64_backend_data elf_x86_64_nacl_arch_bed =
5383*ef5ccd6cSJohn Marino   {
5384*ef5ccd6cSJohn Marino     elf_x86_64_nacl_plt0_entry,              /* plt0_entry */
5385*ef5ccd6cSJohn Marino     elf_x86_64_nacl_plt_entry,               /* plt_entry */
5386*ef5ccd6cSJohn Marino     NACL_PLT_ENTRY_SIZE,                     /* plt_entry_size */
5387*ef5ccd6cSJohn Marino     2,                                       /* plt0_got1_offset */
5388*ef5ccd6cSJohn Marino     9,                                       /* plt0_got2_offset */
5389*ef5ccd6cSJohn Marino     13,                                      /* plt0_got2_insn_end */
5390*ef5ccd6cSJohn Marino     3,                                       /* plt_got_offset */
5391*ef5ccd6cSJohn Marino     33,                                      /* plt_reloc_offset */
5392*ef5ccd6cSJohn Marino     38,                                      /* plt_plt_offset */
5393*ef5ccd6cSJohn Marino     7,                                       /* plt_got_insn_size */
5394*ef5ccd6cSJohn Marino     42,                                      /* plt_plt_insn_end */
5395*ef5ccd6cSJohn Marino     32,                                      /* plt_lazy_offset */
5396*ef5ccd6cSJohn Marino     elf_x86_64_nacl_eh_frame_plt,            /* eh_frame_plt */
5397*ef5ccd6cSJohn Marino     sizeof (elf_x86_64_nacl_eh_frame_plt),   /* eh_frame_plt_size */
5398*ef5ccd6cSJohn Marino   };
5399*ef5ccd6cSJohn Marino 
5400*ef5ccd6cSJohn Marino #undef	elf_backend_arch_data
5401*ef5ccd6cSJohn Marino #define	elf_backend_arch_data	&elf_x86_64_nacl_arch_bed
5402*ef5ccd6cSJohn Marino 
5403*ef5ccd6cSJohn Marino #undef	elf_backend_modify_segment_map
5404*ef5ccd6cSJohn Marino #define	elf_backend_modify_segment_map		nacl_modify_segment_map
5405*ef5ccd6cSJohn Marino #undef	elf_backend_modify_program_headers
5406*ef5ccd6cSJohn Marino #define	elf_backend_modify_program_headers	nacl_modify_program_headers
5407*ef5ccd6cSJohn Marino 
5408*ef5ccd6cSJohn Marino #include "elf64-target.h"
5409*ef5ccd6cSJohn Marino 
5410*ef5ccd6cSJohn Marino /* Native Client x32 support.  */
5411*ef5ccd6cSJohn Marino 
5412*ef5ccd6cSJohn Marino #undef  TARGET_LITTLE_SYM
5413*ef5ccd6cSJohn Marino #define TARGET_LITTLE_SYM		bfd_elf32_x86_64_nacl_vec
5414*ef5ccd6cSJohn Marino #undef  TARGET_LITTLE_NAME
5415*ef5ccd6cSJohn Marino #define TARGET_LITTLE_NAME		"elf32-x86-64-nacl"
5416*ef5ccd6cSJohn Marino #undef	elf32_bed
5417*ef5ccd6cSJohn Marino #define	elf32_bed			elf32_x86_64_nacl_bed
5418*ef5ccd6cSJohn Marino 
5419*ef5ccd6cSJohn Marino #define bfd_elf32_bfd_link_hash_table_create \
5420*ef5ccd6cSJohn Marino   elf_x86_64_link_hash_table_create
5421*ef5ccd6cSJohn Marino #define bfd_elf32_bfd_link_hash_table_free \
5422*ef5ccd6cSJohn Marino   elf_x86_64_link_hash_table_free
5423*ef5ccd6cSJohn Marino #define bfd_elf32_bfd_reloc_type_lookup	\
5424*ef5ccd6cSJohn Marino   elf_x86_64_reloc_type_lookup
5425*ef5ccd6cSJohn Marino #define bfd_elf32_bfd_reloc_name_lookup \
5426*ef5ccd6cSJohn Marino   elf_x86_64_reloc_name_lookup
5427*ef5ccd6cSJohn Marino #define bfd_elf32_mkobject \
5428*ef5ccd6cSJohn Marino   elf_x86_64_mkobject
5429*ef5ccd6cSJohn Marino 
5430*ef5ccd6cSJohn Marino #undef elf_backend_object_p
5431*ef5ccd6cSJohn Marino #define elf_backend_object_p \
5432*ef5ccd6cSJohn Marino   elf32_x86_64_elf_object_p
5433*ef5ccd6cSJohn Marino 
5434*ef5ccd6cSJohn Marino #undef elf_backend_bfd_from_remote_memory
5435*ef5ccd6cSJohn Marino #define elf_backend_bfd_from_remote_memory \
5436*ef5ccd6cSJohn Marino   _bfd_elf32_bfd_from_remote_memory
5437*ef5ccd6cSJohn Marino 
5438*ef5ccd6cSJohn Marino #undef elf_backend_size_info
5439*ef5ccd6cSJohn Marino #define elf_backend_size_info \
5440*ef5ccd6cSJohn Marino   _bfd_elf32_size_info
5441*ef5ccd6cSJohn Marino 
5442*ef5ccd6cSJohn Marino #include "elf32-target.h"
5443*ef5ccd6cSJohn Marino 
5444*ef5ccd6cSJohn Marino /* Restore defaults.  */
5445*ef5ccd6cSJohn Marino #undef	elf_backend_object_p
5446*ef5ccd6cSJohn Marino #define elf_backend_object_p		    elf64_x86_64_elf_object_p
5447*ef5ccd6cSJohn Marino #undef	elf_backend_bfd_from_remote_memory
5448*ef5ccd6cSJohn Marino #undef	elf_backend_size_info
5449*ef5ccd6cSJohn Marino #undef	elf_backend_modify_segment_map
5450*ef5ccd6cSJohn Marino #undef	elf_backend_modify_program_headers
5451*ef5ccd6cSJohn Marino 
54525796c8dcSSimon Schubert /* Intel L1OM support.  */
54535796c8dcSSimon Schubert 
54545796c8dcSSimon Schubert static bfd_boolean
elf64_l1om_elf_object_p(bfd * abfd)54555796c8dcSSimon Schubert elf64_l1om_elf_object_p (bfd *abfd)
54565796c8dcSSimon Schubert {
54575796c8dcSSimon Schubert   /* Set the right machine number for an L1OM elf64 file.  */
54585796c8dcSSimon Schubert   bfd_default_set_arch_mach (abfd, bfd_arch_l1om, bfd_mach_l1om);
54595796c8dcSSimon Schubert   return TRUE;
54605796c8dcSSimon Schubert }
54615796c8dcSSimon Schubert 
54625796c8dcSSimon Schubert #undef  TARGET_LITTLE_SYM
54635796c8dcSSimon Schubert #define TARGET_LITTLE_SYM		    bfd_elf64_l1om_vec
54645796c8dcSSimon Schubert #undef  TARGET_LITTLE_NAME
54655796c8dcSSimon Schubert #define TARGET_LITTLE_NAME		    "elf64-l1om"
54665796c8dcSSimon Schubert #undef ELF_ARCH
54675796c8dcSSimon Schubert #define ELF_ARCH			    bfd_arch_l1om
54685796c8dcSSimon Schubert 
54695796c8dcSSimon Schubert #undef	ELF_MACHINE_CODE
54705796c8dcSSimon Schubert #define ELF_MACHINE_CODE		    EM_L1OM
54715796c8dcSSimon Schubert 
54725796c8dcSSimon Schubert #undef	ELF_OSABI
54735796c8dcSSimon Schubert 
54745796c8dcSSimon Schubert #undef  elf64_bed
54755796c8dcSSimon Schubert #define elf64_bed elf64_l1om_bed
54765796c8dcSSimon Schubert 
54775796c8dcSSimon Schubert #undef elf_backend_object_p
54785796c8dcSSimon Schubert #define elf_backend_object_p		    elf64_l1om_elf_object_p
54795796c8dcSSimon Schubert 
5480*ef5ccd6cSJohn Marino /* Restore defaults.  */
5481*ef5ccd6cSJohn Marino #undef	ELF_MAXPAGESIZE
5482*ef5ccd6cSJohn Marino #undef	ELF_MINPAGESIZE
5483*ef5ccd6cSJohn Marino #undef	ELF_COMMONPAGESIZE
5484*ef5ccd6cSJohn Marino #define ELF_MAXPAGESIZE			0x200000
5485*ef5ccd6cSJohn Marino #define ELF_MINPAGESIZE			0x1000
5486*ef5ccd6cSJohn Marino #define ELF_COMMONPAGESIZE		0x1000
5487*ef5ccd6cSJohn Marino #undef	elf_backend_plt_alignment
5488*ef5ccd6cSJohn Marino #define elf_backend_plt_alignment	4
5489*ef5ccd6cSJohn Marino #undef	elf_backend_arch_data
5490*ef5ccd6cSJohn Marino #define	elf_backend_arch_data	&elf_x86_64_arch_bed
54915796c8dcSSimon Schubert 
54925796c8dcSSimon Schubert #include "elf64-target.h"
54935796c8dcSSimon Schubert 
54945796c8dcSSimon Schubert /* FreeBSD L1OM support.  */
54955796c8dcSSimon Schubert 
54965796c8dcSSimon Schubert #undef  TARGET_LITTLE_SYM
54975796c8dcSSimon Schubert #define TARGET_LITTLE_SYM		    bfd_elf64_l1om_freebsd_vec
54985796c8dcSSimon Schubert #undef  TARGET_LITTLE_NAME
54995796c8dcSSimon Schubert #define TARGET_LITTLE_NAME		    "elf64-l1om-freebsd"
55005796c8dcSSimon Schubert 
55015796c8dcSSimon Schubert #undef	ELF_OSABI
55025796c8dcSSimon Schubert #define	ELF_OSABI			    ELFOSABI_FREEBSD
55035796c8dcSSimon Schubert 
55045796c8dcSSimon Schubert #undef  elf64_bed
55055796c8dcSSimon Schubert #define elf64_bed elf64_l1om_fbsd_bed
55065796c8dcSSimon Schubert 
5507a45ae5f8SJohn Marino #include "elf64-target.h"
5508a45ae5f8SJohn Marino 
5509a45ae5f8SJohn Marino /* Intel K1OM support.  */
5510a45ae5f8SJohn Marino 
5511a45ae5f8SJohn Marino static bfd_boolean
elf64_k1om_elf_object_p(bfd * abfd)5512a45ae5f8SJohn Marino elf64_k1om_elf_object_p (bfd *abfd)
5513a45ae5f8SJohn Marino {
5514a45ae5f8SJohn Marino   /* Set the right machine number for an K1OM elf64 file.  */
5515a45ae5f8SJohn Marino   bfd_default_set_arch_mach (abfd, bfd_arch_k1om, bfd_mach_k1om);
5516a45ae5f8SJohn Marino   return TRUE;
5517a45ae5f8SJohn Marino }
5518a45ae5f8SJohn Marino 
5519a45ae5f8SJohn Marino #undef  TARGET_LITTLE_SYM
5520a45ae5f8SJohn Marino #define TARGET_LITTLE_SYM		    bfd_elf64_k1om_vec
5521a45ae5f8SJohn Marino #undef  TARGET_LITTLE_NAME
5522a45ae5f8SJohn Marino #define TARGET_LITTLE_NAME		    "elf64-k1om"
5523a45ae5f8SJohn Marino #undef ELF_ARCH
5524a45ae5f8SJohn Marino #define ELF_ARCH			    bfd_arch_k1om
5525a45ae5f8SJohn Marino 
5526a45ae5f8SJohn Marino #undef	ELF_MACHINE_CODE
5527a45ae5f8SJohn Marino #define ELF_MACHINE_CODE		    EM_K1OM
5528a45ae5f8SJohn Marino 
5529a45ae5f8SJohn Marino #undef	ELF_OSABI
5530a45ae5f8SJohn Marino 
5531a45ae5f8SJohn Marino #undef  elf64_bed
5532a45ae5f8SJohn Marino #define elf64_bed elf64_k1om_bed
5533a45ae5f8SJohn Marino 
5534a45ae5f8SJohn Marino #undef elf_backend_object_p
5535a45ae5f8SJohn Marino #define elf_backend_object_p		    elf64_k1om_elf_object_p
5536a45ae5f8SJohn Marino 
5537a45ae5f8SJohn Marino #undef  elf_backend_static_tls_alignment
5538a45ae5f8SJohn Marino 
5539a45ae5f8SJohn Marino #undef elf_backend_want_plt_sym
5540a45ae5f8SJohn Marino #define elf_backend_want_plt_sym	    0
5541a45ae5f8SJohn Marino 
5542a45ae5f8SJohn Marino #include "elf64-target.h"
5543a45ae5f8SJohn Marino 
5544a45ae5f8SJohn Marino /* FreeBSD K1OM support.  */
5545a45ae5f8SJohn Marino 
5546a45ae5f8SJohn Marino #undef  TARGET_LITTLE_SYM
5547a45ae5f8SJohn Marino #define TARGET_LITTLE_SYM		    bfd_elf64_k1om_freebsd_vec
5548a45ae5f8SJohn Marino #undef  TARGET_LITTLE_NAME
5549a45ae5f8SJohn Marino #define TARGET_LITTLE_NAME		    "elf64-k1om-freebsd"
5550a45ae5f8SJohn Marino 
5551a45ae5f8SJohn Marino #undef	ELF_OSABI
5552a45ae5f8SJohn Marino #define	ELF_OSABI			    ELFOSABI_FREEBSD
5553a45ae5f8SJohn Marino 
5554a45ae5f8SJohn Marino #undef  elf64_bed
5555a45ae5f8SJohn Marino #define elf64_bed elf64_k1om_fbsd_bed
55565796c8dcSSimon Schubert 
55575796c8dcSSimon Schubert #include "elf64-target.h"
5558c50c785cSJohn Marino 
5559c50c785cSJohn Marino /* 32bit x86-64 support.  */
5560c50c785cSJohn Marino 
5561c50c785cSJohn Marino #undef  TARGET_LITTLE_SYM
5562c50c785cSJohn Marino #define TARGET_LITTLE_SYM		    bfd_elf32_x86_64_vec
5563c50c785cSJohn Marino #undef  TARGET_LITTLE_NAME
5564c50c785cSJohn Marino #define TARGET_LITTLE_NAME		    "elf32-x86-64"
5565*ef5ccd6cSJohn Marino #undef	elf32_bed
5566c50c785cSJohn Marino 
5567c50c785cSJohn Marino #undef ELF_ARCH
5568c50c785cSJohn Marino #define ELF_ARCH			    bfd_arch_i386
5569c50c785cSJohn Marino 
5570c50c785cSJohn Marino #undef	ELF_MACHINE_CODE
5571c50c785cSJohn Marino #define ELF_MACHINE_CODE		    EM_X86_64
5572c50c785cSJohn Marino 
5573c50c785cSJohn Marino #undef	ELF_OSABI
5574c50c785cSJohn Marino 
5575c50c785cSJohn Marino #undef elf_backend_object_p
5576c50c785cSJohn Marino #define elf_backend_object_p \
5577c50c785cSJohn Marino   elf32_x86_64_elf_object_p
5578c50c785cSJohn Marino 
5579c50c785cSJohn Marino #undef elf_backend_bfd_from_remote_memory
5580c50c785cSJohn Marino #define elf_backend_bfd_from_remote_memory \
5581c50c785cSJohn Marino   _bfd_elf32_bfd_from_remote_memory
5582c50c785cSJohn Marino 
5583c50c785cSJohn Marino #undef elf_backend_size_info
5584c50c785cSJohn Marino #define elf_backend_size_info \
5585c50c785cSJohn Marino   _bfd_elf32_size_info
5586c50c785cSJohn Marino 
5587c50c785cSJohn Marino #include "elf32-target.h"
5588