xref: /dflybsd-src/contrib/gdb-7/bfd/elf32-i386.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Intel 80386/80486-specific support for 32-bit ELF
25796c8dcSSimon Schubert    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3*ef5ccd6cSJohn Marino    2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4a45ae5f8SJohn Marino    Free Software Foundation, Inc.
55796c8dcSSimon Schubert 
65796c8dcSSimon Schubert    This file is part of BFD, the Binary File Descriptor library.
75796c8dcSSimon Schubert 
85796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
95796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
105796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
115796c8dcSSimon Schubert    (at your option) any later version.
125796c8dcSSimon Schubert 
135796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
145796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
155796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
165796c8dcSSimon Schubert    GNU General Public License for more details.
175796c8dcSSimon Schubert 
185796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
195796c8dcSSimon Schubert    along with this program; if not, write to the Free Software
205796c8dcSSimon Schubert    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
215796c8dcSSimon Schubert    MA 02110-1301, USA.  */
225796c8dcSSimon Schubert 
235796c8dcSSimon Schubert #include "sysdep.h"
245796c8dcSSimon Schubert #include "bfd.h"
255796c8dcSSimon Schubert #include "bfdlink.h"
265796c8dcSSimon Schubert #include "libbfd.h"
275796c8dcSSimon Schubert #include "elf-bfd.h"
28*ef5ccd6cSJohn Marino #include "elf-nacl.h"
295796c8dcSSimon Schubert #include "elf-vxworks.h"
305796c8dcSSimon Schubert #include "bfd_stdint.h"
315796c8dcSSimon Schubert #include "objalloc.h"
325796c8dcSSimon Schubert #include "hashtab.h"
33a45ae5f8SJohn Marino #include "dwarf2.h"
345796c8dcSSimon Schubert 
355796c8dcSSimon Schubert /* 386 uses REL relocations instead of RELA.  */
365796c8dcSSimon Schubert #define USE_REL	1
375796c8dcSSimon Schubert 
385796c8dcSSimon Schubert #include "elf/i386.h"
395796c8dcSSimon Schubert 
405796c8dcSSimon Schubert static reloc_howto_type elf_howto_table[]=
415796c8dcSSimon Schubert {
425796c8dcSSimon Schubert   HOWTO(R_386_NONE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
435796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_NONE",
445796c8dcSSimon Schubert 	TRUE, 0x00000000, 0x00000000, FALSE),
455796c8dcSSimon Schubert   HOWTO(R_386_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
465796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_32",
475796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
485796c8dcSSimon Schubert   HOWTO(R_386_PC32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
495796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_PC32",
505796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, TRUE),
515796c8dcSSimon Schubert   HOWTO(R_386_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
525796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_GOT32",
535796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
545796c8dcSSimon Schubert   HOWTO(R_386_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
555796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_PLT32",
565796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, TRUE),
575796c8dcSSimon Schubert   HOWTO(R_386_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
585796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_COPY",
595796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
605796c8dcSSimon Schubert   HOWTO(R_386_GLOB_DAT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
615796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_GLOB_DAT",
625796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
635796c8dcSSimon Schubert   HOWTO(R_386_JUMP_SLOT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
645796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_JUMP_SLOT",
655796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
665796c8dcSSimon Schubert   HOWTO(R_386_RELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
675796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_RELATIVE",
685796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
695796c8dcSSimon Schubert   HOWTO(R_386_GOTOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
705796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_GOTOFF",
715796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
725796c8dcSSimon Schubert   HOWTO(R_386_GOTPC, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
735796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_GOTPC",
745796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, TRUE),
755796c8dcSSimon Schubert 
765796c8dcSSimon Schubert   /* We have a gap in the reloc numbers here.
775796c8dcSSimon Schubert      R_386_standard counts the number up to this point, and
785796c8dcSSimon Schubert      R_386_ext_offset is the value to subtract from a reloc type of
795796c8dcSSimon Schubert      R_386_16 thru R_386_PC8 to form an index into this table.  */
805796c8dcSSimon Schubert #define R_386_standard (R_386_GOTPC + 1)
815796c8dcSSimon Schubert #define R_386_ext_offset (R_386_TLS_TPOFF - R_386_standard)
825796c8dcSSimon Schubert 
835796c8dcSSimon Schubert   /* These relocs are a GNU extension.  */
845796c8dcSSimon Schubert   HOWTO(R_386_TLS_TPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
855796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_TPOFF",
865796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
875796c8dcSSimon Schubert   HOWTO(R_386_TLS_IE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
885796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_IE",
895796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
905796c8dcSSimon Schubert   HOWTO(R_386_TLS_GOTIE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
915796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_GOTIE",
925796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
935796c8dcSSimon Schubert   HOWTO(R_386_TLS_LE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
945796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_LE",
955796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
965796c8dcSSimon Schubert   HOWTO(R_386_TLS_GD, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
975796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_GD",
985796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
995796c8dcSSimon Schubert   HOWTO(R_386_TLS_LDM, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
1005796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_LDM",
1015796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
1025796c8dcSSimon Schubert   HOWTO(R_386_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
1035796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_16",
1045796c8dcSSimon Schubert 	TRUE, 0xffff, 0xffff, FALSE),
1055796c8dcSSimon Schubert   HOWTO(R_386_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield,
1065796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_PC16",
1075796c8dcSSimon Schubert 	TRUE, 0xffff, 0xffff, TRUE),
1085796c8dcSSimon Schubert   HOWTO(R_386_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
1095796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_8",
1105796c8dcSSimon Schubert 	TRUE, 0xff, 0xff, FALSE),
1115796c8dcSSimon Schubert   HOWTO(R_386_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed,
1125796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_PC8",
1135796c8dcSSimon Schubert 	TRUE, 0xff, 0xff, TRUE),
1145796c8dcSSimon Schubert 
1155796c8dcSSimon Schubert #define R_386_ext (R_386_PC8 + 1 - R_386_ext_offset)
1165796c8dcSSimon Schubert #define R_386_tls_offset (R_386_TLS_LDO_32 - R_386_ext)
1175796c8dcSSimon Schubert   /* These are common with Solaris TLS implementation.  */
1185796c8dcSSimon Schubert   HOWTO(R_386_TLS_LDO_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
1195796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_LDO_32",
1205796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
1215796c8dcSSimon Schubert   HOWTO(R_386_TLS_IE_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
1225796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_IE_32",
1235796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
1245796c8dcSSimon Schubert   HOWTO(R_386_TLS_LE_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
1255796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_LE_32",
1265796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
1275796c8dcSSimon Schubert   HOWTO(R_386_TLS_DTPMOD32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
1285796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_DTPMOD32",
1295796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
1305796c8dcSSimon Schubert   HOWTO(R_386_TLS_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
1315796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_DTPOFF32",
1325796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
1335796c8dcSSimon Schubert   HOWTO(R_386_TLS_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
1345796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_TPOFF32",
1355796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
136*ef5ccd6cSJohn Marino   HOWTO(R_386_SIZE32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned,
137*ef5ccd6cSJohn Marino 	bfd_elf_generic_reloc, "R_386_SIZE32",
138*ef5ccd6cSJohn Marino 	TRUE, 0xffffffff, 0xffffffff, FALSE),
1395796c8dcSSimon Schubert   HOWTO(R_386_TLS_GOTDESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
1405796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_GOTDESC",
1415796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
1425796c8dcSSimon Schubert   HOWTO(R_386_TLS_DESC_CALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
1435796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_DESC_CALL",
1445796c8dcSSimon Schubert 	FALSE, 0, 0, FALSE),
1455796c8dcSSimon Schubert   HOWTO(R_386_TLS_DESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
1465796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_TLS_DESC",
1475796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
1485796c8dcSSimon Schubert   HOWTO(R_386_IRELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
1495796c8dcSSimon Schubert 	bfd_elf_generic_reloc, "R_386_IRELATIVE",
1505796c8dcSSimon Schubert 	TRUE, 0xffffffff, 0xffffffff, FALSE),
1515796c8dcSSimon Schubert 
1525796c8dcSSimon Schubert   /* Another gap.  */
1535796c8dcSSimon Schubert #define R_386_irelative (R_386_IRELATIVE + 1 - R_386_tls_offset)
1545796c8dcSSimon Schubert #define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_irelative)
1555796c8dcSSimon Schubert 
1565796c8dcSSimon Schubert /* GNU extension to record C++ vtable hierarchy.  */
1575796c8dcSSimon Schubert   HOWTO (R_386_GNU_VTINHERIT,	/* type */
1585796c8dcSSimon Schubert 	 0,			/* rightshift */
1595796c8dcSSimon Schubert 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1605796c8dcSSimon Schubert 	 0,			/* bitsize */
1615796c8dcSSimon Schubert 	 FALSE,			/* pc_relative */
1625796c8dcSSimon Schubert 	 0,			/* bitpos */
1635796c8dcSSimon Schubert 	 complain_overflow_dont, /* complain_on_overflow */
1645796c8dcSSimon Schubert 	 NULL,			/* special_function */
1655796c8dcSSimon Schubert 	 "R_386_GNU_VTINHERIT",	/* name */
1665796c8dcSSimon Schubert 	 FALSE,			/* partial_inplace */
1675796c8dcSSimon Schubert 	 0,			/* src_mask */
1685796c8dcSSimon Schubert 	 0,			/* dst_mask */
1695796c8dcSSimon Schubert 	 FALSE),		/* pcrel_offset */
1705796c8dcSSimon Schubert 
1715796c8dcSSimon Schubert /* GNU extension to record C++ vtable member usage.  */
1725796c8dcSSimon Schubert   HOWTO (R_386_GNU_VTENTRY,	/* type */
1735796c8dcSSimon Schubert 	 0,			/* rightshift */
1745796c8dcSSimon Schubert 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1755796c8dcSSimon Schubert 	 0,			/* bitsize */
1765796c8dcSSimon Schubert 	 FALSE,			/* pc_relative */
1775796c8dcSSimon Schubert 	 0,			/* bitpos */
1785796c8dcSSimon Schubert 	 complain_overflow_dont, /* complain_on_overflow */
1795796c8dcSSimon Schubert 	 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1805796c8dcSSimon Schubert 	 "R_386_GNU_VTENTRY",	/* name */
1815796c8dcSSimon Schubert 	 FALSE,			/* partial_inplace */
1825796c8dcSSimon Schubert 	 0,			/* src_mask */
1835796c8dcSSimon Schubert 	 0,			/* dst_mask */
1845796c8dcSSimon Schubert 	 FALSE)			/* pcrel_offset */
1855796c8dcSSimon Schubert 
1865796c8dcSSimon Schubert #define R_386_vt (R_386_GNU_VTENTRY + 1 - R_386_vt_offset)
1875796c8dcSSimon Schubert 
1885796c8dcSSimon Schubert };
1895796c8dcSSimon Schubert 
1905796c8dcSSimon Schubert #ifdef DEBUG_GEN_RELOC
1915796c8dcSSimon Schubert #define TRACE(str) \
1925796c8dcSSimon Schubert   fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str)
1935796c8dcSSimon Schubert #else
1945796c8dcSSimon Schubert #define TRACE(str)
1955796c8dcSSimon Schubert #endif
1965796c8dcSSimon Schubert 
1975796c8dcSSimon Schubert static reloc_howto_type *
elf_i386_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)1985796c8dcSSimon Schubert elf_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1995796c8dcSSimon Schubert 			    bfd_reloc_code_real_type code)
2005796c8dcSSimon Schubert {
2015796c8dcSSimon Schubert   switch (code)
2025796c8dcSSimon Schubert     {
2035796c8dcSSimon Schubert     case BFD_RELOC_NONE:
2045796c8dcSSimon Schubert       TRACE ("BFD_RELOC_NONE");
2055796c8dcSSimon Schubert       return &elf_howto_table[R_386_NONE];
2065796c8dcSSimon Schubert 
2075796c8dcSSimon Schubert     case BFD_RELOC_32:
2085796c8dcSSimon Schubert       TRACE ("BFD_RELOC_32");
2095796c8dcSSimon Schubert       return &elf_howto_table[R_386_32];
2105796c8dcSSimon Schubert 
2115796c8dcSSimon Schubert     case BFD_RELOC_CTOR:
2125796c8dcSSimon Schubert       TRACE ("BFD_RELOC_CTOR");
2135796c8dcSSimon Schubert       return &elf_howto_table[R_386_32];
2145796c8dcSSimon Schubert 
2155796c8dcSSimon Schubert     case BFD_RELOC_32_PCREL:
2165796c8dcSSimon Schubert       TRACE ("BFD_RELOC_PC32");
2175796c8dcSSimon Schubert       return &elf_howto_table[R_386_PC32];
2185796c8dcSSimon Schubert 
2195796c8dcSSimon Schubert     case BFD_RELOC_386_GOT32:
2205796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_GOT32");
2215796c8dcSSimon Schubert       return &elf_howto_table[R_386_GOT32];
2225796c8dcSSimon Schubert 
2235796c8dcSSimon Schubert     case BFD_RELOC_386_PLT32:
2245796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_PLT32");
2255796c8dcSSimon Schubert       return &elf_howto_table[R_386_PLT32];
2265796c8dcSSimon Schubert 
2275796c8dcSSimon Schubert     case BFD_RELOC_386_COPY:
2285796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_COPY");
2295796c8dcSSimon Schubert       return &elf_howto_table[R_386_COPY];
2305796c8dcSSimon Schubert 
2315796c8dcSSimon Schubert     case BFD_RELOC_386_GLOB_DAT:
2325796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_GLOB_DAT");
2335796c8dcSSimon Schubert       return &elf_howto_table[R_386_GLOB_DAT];
2345796c8dcSSimon Schubert 
2355796c8dcSSimon Schubert     case BFD_RELOC_386_JUMP_SLOT:
2365796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_JUMP_SLOT");
2375796c8dcSSimon Schubert       return &elf_howto_table[R_386_JUMP_SLOT];
2385796c8dcSSimon Schubert 
2395796c8dcSSimon Schubert     case BFD_RELOC_386_RELATIVE:
2405796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_RELATIVE");
2415796c8dcSSimon Schubert       return &elf_howto_table[R_386_RELATIVE];
2425796c8dcSSimon Schubert 
2435796c8dcSSimon Schubert     case BFD_RELOC_386_GOTOFF:
2445796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_GOTOFF");
2455796c8dcSSimon Schubert       return &elf_howto_table[R_386_GOTOFF];
2465796c8dcSSimon Schubert 
2475796c8dcSSimon Schubert     case BFD_RELOC_386_GOTPC:
2485796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_GOTPC");
2495796c8dcSSimon Schubert       return &elf_howto_table[R_386_GOTPC];
2505796c8dcSSimon Schubert 
2515796c8dcSSimon Schubert       /* These relocs are a GNU extension.  */
2525796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_TPOFF:
2535796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_TPOFF");
2545796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_TPOFF - R_386_ext_offset];
2555796c8dcSSimon Schubert 
2565796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_IE:
2575796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_IE");
2585796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_IE - R_386_ext_offset];
2595796c8dcSSimon Schubert 
2605796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_GOTIE:
2615796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_GOTIE");
2625796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_GOTIE - R_386_ext_offset];
2635796c8dcSSimon Schubert 
2645796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_LE:
2655796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_LE");
2665796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_LE - R_386_ext_offset];
2675796c8dcSSimon Schubert 
2685796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_GD:
2695796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_GD");
2705796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_GD - R_386_ext_offset];
2715796c8dcSSimon Schubert 
2725796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_LDM:
2735796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_LDM");
2745796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_LDM - R_386_ext_offset];
2755796c8dcSSimon Schubert 
2765796c8dcSSimon Schubert     case BFD_RELOC_16:
2775796c8dcSSimon Schubert       TRACE ("BFD_RELOC_16");
2785796c8dcSSimon Schubert       return &elf_howto_table[R_386_16 - R_386_ext_offset];
2795796c8dcSSimon Schubert 
2805796c8dcSSimon Schubert     case BFD_RELOC_16_PCREL:
2815796c8dcSSimon Schubert       TRACE ("BFD_RELOC_16_PCREL");
2825796c8dcSSimon Schubert       return &elf_howto_table[R_386_PC16 - R_386_ext_offset];
2835796c8dcSSimon Schubert 
2845796c8dcSSimon Schubert     case BFD_RELOC_8:
2855796c8dcSSimon Schubert       TRACE ("BFD_RELOC_8");
2865796c8dcSSimon Schubert       return &elf_howto_table[R_386_8 - R_386_ext_offset];
2875796c8dcSSimon Schubert 
2885796c8dcSSimon Schubert     case BFD_RELOC_8_PCREL:
2895796c8dcSSimon Schubert       TRACE ("BFD_RELOC_8_PCREL");
2905796c8dcSSimon Schubert       return &elf_howto_table[R_386_PC8 - R_386_ext_offset];
2915796c8dcSSimon Schubert 
2925796c8dcSSimon Schubert     /* Common with Sun TLS implementation.  */
2935796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_LDO_32:
2945796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_LDO_32");
2955796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_LDO_32 - R_386_tls_offset];
2965796c8dcSSimon Schubert 
2975796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_IE_32:
2985796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_IE_32");
2995796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_IE_32 - R_386_tls_offset];
3005796c8dcSSimon Schubert 
3015796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_LE_32:
3025796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_LE_32");
3035796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_LE_32 - R_386_tls_offset];
3045796c8dcSSimon Schubert 
3055796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_DTPMOD32:
3065796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_DTPMOD32");
3075796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_DTPMOD32 - R_386_tls_offset];
3085796c8dcSSimon Schubert 
3095796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_DTPOFF32:
3105796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_DTPOFF32");
3115796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_DTPOFF32 - R_386_tls_offset];
3125796c8dcSSimon Schubert 
3135796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_TPOFF32:
3145796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_TPOFF32");
3155796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_TPOFF32 - R_386_tls_offset];
3165796c8dcSSimon Schubert 
317*ef5ccd6cSJohn Marino     case BFD_RELOC_SIZE32:
318*ef5ccd6cSJohn Marino       TRACE ("BFD_RELOC_SIZE32");
319*ef5ccd6cSJohn Marino       return &elf_howto_table[R_386_SIZE32 - R_386_tls_offset];
320*ef5ccd6cSJohn Marino 
3215796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_GOTDESC:
3225796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_GOTDESC");
3235796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_GOTDESC - R_386_tls_offset];
3245796c8dcSSimon Schubert 
3255796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_DESC_CALL:
3265796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_DESC_CALL");
3275796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_DESC_CALL - R_386_tls_offset];
3285796c8dcSSimon Schubert 
3295796c8dcSSimon Schubert     case BFD_RELOC_386_TLS_DESC:
3305796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_TLS_DESC");
3315796c8dcSSimon Schubert       return &elf_howto_table[R_386_TLS_DESC - R_386_tls_offset];
3325796c8dcSSimon Schubert 
3335796c8dcSSimon Schubert     case BFD_RELOC_386_IRELATIVE:
3345796c8dcSSimon Schubert       TRACE ("BFD_RELOC_386_IRELATIVE");
335a45ae5f8SJohn Marino       return &elf_howto_table[R_386_IRELATIVE - R_386_tls_offset];
3365796c8dcSSimon Schubert 
3375796c8dcSSimon Schubert     case BFD_RELOC_VTABLE_INHERIT:
3385796c8dcSSimon Schubert       TRACE ("BFD_RELOC_VTABLE_INHERIT");
3395796c8dcSSimon Schubert       return &elf_howto_table[R_386_GNU_VTINHERIT - R_386_vt_offset];
3405796c8dcSSimon Schubert 
3415796c8dcSSimon Schubert     case BFD_RELOC_VTABLE_ENTRY:
3425796c8dcSSimon Schubert       TRACE ("BFD_RELOC_VTABLE_ENTRY");
3435796c8dcSSimon Schubert       return &elf_howto_table[R_386_GNU_VTENTRY - R_386_vt_offset];
3445796c8dcSSimon Schubert 
3455796c8dcSSimon Schubert     default:
3465796c8dcSSimon Schubert       break;
3475796c8dcSSimon Schubert     }
3485796c8dcSSimon Schubert 
3495796c8dcSSimon Schubert   TRACE ("Unknown");
3505796c8dcSSimon Schubert   return 0;
3515796c8dcSSimon Schubert }
3525796c8dcSSimon Schubert 
3535796c8dcSSimon Schubert static reloc_howto_type *
elf_i386_reloc_name_lookup(bfd * abfd ATTRIBUTE_UNUSED,const char * r_name)3545796c8dcSSimon Schubert elf_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3555796c8dcSSimon Schubert 			    const char *r_name)
3565796c8dcSSimon Schubert {
3575796c8dcSSimon Schubert   unsigned int i;
3585796c8dcSSimon Schubert 
3595796c8dcSSimon Schubert   for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
3605796c8dcSSimon Schubert     if (elf_howto_table[i].name != NULL
3615796c8dcSSimon Schubert 	&& strcasecmp (elf_howto_table[i].name, r_name) == 0)
3625796c8dcSSimon Schubert       return &elf_howto_table[i];
3635796c8dcSSimon Schubert 
3645796c8dcSSimon Schubert   return NULL;
3655796c8dcSSimon Schubert }
3665796c8dcSSimon Schubert 
3675796c8dcSSimon Schubert static reloc_howto_type *
elf_i386_rtype_to_howto(bfd * abfd,unsigned r_type)3685796c8dcSSimon Schubert elf_i386_rtype_to_howto (bfd *abfd, unsigned r_type)
3695796c8dcSSimon Schubert {
3705796c8dcSSimon Schubert   unsigned int indx;
3715796c8dcSSimon Schubert 
3725796c8dcSSimon Schubert   if ((indx = r_type) >= R_386_standard
3735796c8dcSSimon Schubert       && ((indx = r_type - R_386_ext_offset) - R_386_standard
3745796c8dcSSimon Schubert 	  >= R_386_ext - R_386_standard)
3755796c8dcSSimon Schubert       && ((indx = r_type - R_386_tls_offset) - R_386_ext
3765796c8dcSSimon Schubert 	  >= R_386_irelative - R_386_ext)
3775796c8dcSSimon Schubert       && ((indx = r_type - R_386_vt_offset) - R_386_irelative
3785796c8dcSSimon Schubert 	  >= R_386_vt - R_386_irelative))
3795796c8dcSSimon Schubert     {
3805796c8dcSSimon Schubert       (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
3815796c8dcSSimon Schubert 			     abfd, (int) r_type);
3825796c8dcSSimon Schubert       indx = R_386_NONE;
3835796c8dcSSimon Schubert     }
3845796c8dcSSimon Schubert   BFD_ASSERT (elf_howto_table [indx].type == r_type);
3855796c8dcSSimon Schubert   return &elf_howto_table[indx];
3865796c8dcSSimon Schubert }
3875796c8dcSSimon Schubert 
3885796c8dcSSimon Schubert static void
elf_i386_info_to_howto_rel(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr,Elf_Internal_Rela * dst)3895796c8dcSSimon Schubert elf_i386_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
3905796c8dcSSimon Schubert 			    arelent *cache_ptr,
3915796c8dcSSimon Schubert 			    Elf_Internal_Rela *dst)
3925796c8dcSSimon Schubert {
3935796c8dcSSimon Schubert   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
3945796c8dcSSimon Schubert   cache_ptr->howto = elf_i386_rtype_to_howto (abfd, r_type);
3955796c8dcSSimon Schubert }
3965796c8dcSSimon Schubert 
3975796c8dcSSimon Schubert /* Return whether a symbol name implies a local label.  The UnixWare
3985796c8dcSSimon Schubert    2.1 cc generates temporary symbols that start with .X, so we
3995796c8dcSSimon Schubert    recognize them here.  FIXME: do other SVR4 compilers also use .X?.
4005796c8dcSSimon Schubert    If so, we should move the .X recognition into
4015796c8dcSSimon Schubert    _bfd_elf_is_local_label_name.  */
4025796c8dcSSimon Schubert 
4035796c8dcSSimon Schubert static bfd_boolean
elf_i386_is_local_label_name(bfd * abfd,const char * name)4045796c8dcSSimon Schubert elf_i386_is_local_label_name (bfd *abfd, const char *name)
4055796c8dcSSimon Schubert {
4065796c8dcSSimon Schubert   if (name[0] == '.' && name[1] == 'X')
4075796c8dcSSimon Schubert     return TRUE;
4085796c8dcSSimon Schubert 
4095796c8dcSSimon Schubert   return _bfd_elf_is_local_label_name (abfd, name);
4105796c8dcSSimon Schubert }
4115796c8dcSSimon Schubert 
4125796c8dcSSimon Schubert /* Support for core dump NOTE sections.  */
4135796c8dcSSimon Schubert 
4145796c8dcSSimon Schubert static bfd_boolean
elf_i386_grok_prstatus(bfd * abfd,Elf_Internal_Note * note)4155796c8dcSSimon Schubert elf_i386_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
4165796c8dcSSimon Schubert {
4175796c8dcSSimon Schubert   int offset;
4185796c8dcSSimon Schubert   size_t size;
4195796c8dcSSimon Schubert 
4205796c8dcSSimon Schubert   if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0)
4215796c8dcSSimon Schubert     {
4225796c8dcSSimon Schubert       int pr_version = bfd_get_32 (abfd, note->descdata);
4235796c8dcSSimon Schubert 
4245796c8dcSSimon Schubert       if (pr_version != 1)
4255796c8dcSSimon Schubert  	return FALSE;
4265796c8dcSSimon Schubert 
4275796c8dcSSimon Schubert       /* pr_cursig */
428*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 20);
4295796c8dcSSimon Schubert 
4305796c8dcSSimon Schubert       /* pr_pid */
431*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
4325796c8dcSSimon Schubert 
4335796c8dcSSimon Schubert       /* pr_reg */
4345796c8dcSSimon Schubert       offset = 28;
4355796c8dcSSimon Schubert       size = bfd_get_32 (abfd, note->descdata + 8);
4365796c8dcSSimon Schubert     }
4375796c8dcSSimon Schubert   else
4385796c8dcSSimon Schubert     {
4395796c8dcSSimon Schubert       switch (note->descsz)
4405796c8dcSSimon Schubert 	{
4415796c8dcSSimon Schubert 	default:
4425796c8dcSSimon Schubert 	  return FALSE;
4435796c8dcSSimon Schubert 
4445796c8dcSSimon Schubert 	case 144:		/* Linux/i386 */
4455796c8dcSSimon Schubert 	  /* pr_cursig */
446*ef5ccd6cSJohn Marino 	  elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
4475796c8dcSSimon Schubert 
4485796c8dcSSimon Schubert 	  /* pr_pid */
449*ef5ccd6cSJohn Marino 	  elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
4505796c8dcSSimon Schubert 
4515796c8dcSSimon Schubert 	  /* pr_reg */
4525796c8dcSSimon Schubert 	  offset = 72;
4535796c8dcSSimon Schubert 	  size = 68;
4545796c8dcSSimon Schubert 
4555796c8dcSSimon Schubert 	  break;
4565796c8dcSSimon Schubert 	}
4575796c8dcSSimon Schubert     }
4585796c8dcSSimon Schubert 
4595796c8dcSSimon Schubert   /* Make a ".reg/999" section.  */
4605796c8dcSSimon Schubert   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
4615796c8dcSSimon Schubert 					  size, note->descpos + offset);
4625796c8dcSSimon Schubert }
4635796c8dcSSimon Schubert 
4645796c8dcSSimon Schubert static bfd_boolean
elf_i386_grok_psinfo(bfd * abfd,Elf_Internal_Note * note)4655796c8dcSSimon Schubert elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
4665796c8dcSSimon Schubert {
4675796c8dcSSimon Schubert   if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0)
4685796c8dcSSimon Schubert     {
4695796c8dcSSimon Schubert       int pr_version = bfd_get_32 (abfd, note->descdata);
4705796c8dcSSimon Schubert 
4715796c8dcSSimon Schubert       if (pr_version != 1)
4725796c8dcSSimon Schubert 	return FALSE;
4735796c8dcSSimon Schubert 
474*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->program
4755796c8dcSSimon Schubert 	= _bfd_elfcore_strndup (abfd, note->descdata + 8, 17);
476*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->command
4775796c8dcSSimon Schubert 	= _bfd_elfcore_strndup (abfd, note->descdata + 25, 81);
4785796c8dcSSimon Schubert     }
4795796c8dcSSimon Schubert   else
4805796c8dcSSimon Schubert     {
4815796c8dcSSimon Schubert       switch (note->descsz)
4825796c8dcSSimon Schubert 	{
4835796c8dcSSimon Schubert 	default:
4845796c8dcSSimon Schubert 	  return FALSE;
4855796c8dcSSimon Schubert 
4865796c8dcSSimon Schubert 	case 124:		/* Linux/i386 elf_prpsinfo.  */
487*ef5ccd6cSJohn Marino 	  elf_tdata (abfd)->core->pid
488c50c785cSJohn Marino 	    = bfd_get_32 (abfd, note->descdata + 12);
489*ef5ccd6cSJohn Marino 	  elf_tdata (abfd)->core->program
4905796c8dcSSimon Schubert 	    = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
491*ef5ccd6cSJohn Marino 	  elf_tdata (abfd)->core->command
4925796c8dcSSimon Schubert 	    = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
4935796c8dcSSimon Schubert 	}
4945796c8dcSSimon Schubert     }
4955796c8dcSSimon Schubert 
4965796c8dcSSimon Schubert   /* Note that for some reason, a spurious space is tacked
4975796c8dcSSimon Schubert      onto the end of the args in some (at least one anyway)
4985796c8dcSSimon Schubert      implementations, so strip it off if it exists.  */
4995796c8dcSSimon Schubert   {
500*ef5ccd6cSJohn Marino     char *command = elf_tdata (abfd)->core->command;
5015796c8dcSSimon Schubert     int n = strlen (command);
5025796c8dcSSimon Schubert 
5035796c8dcSSimon Schubert     if (0 < n && command[n - 1] == ' ')
5045796c8dcSSimon Schubert       command[n - 1] = '\0';
5055796c8dcSSimon Schubert   }
5065796c8dcSSimon Schubert 
5075796c8dcSSimon Schubert   return TRUE;
5085796c8dcSSimon Schubert }
5095796c8dcSSimon Schubert 
5105796c8dcSSimon Schubert /* Functions for the i386 ELF linker.
5115796c8dcSSimon Schubert 
5125796c8dcSSimon Schubert    In order to gain some understanding of code in this file without
5135796c8dcSSimon Schubert    knowing all the intricate details of the linker, note the
5145796c8dcSSimon Schubert    following:
5155796c8dcSSimon Schubert 
5165796c8dcSSimon Schubert    Functions named elf_i386_* are called by external routines, other
5175796c8dcSSimon Schubert    functions are only called locally.  elf_i386_* functions appear
5185796c8dcSSimon Schubert    in this file more or less in the order in which they are called
5195796c8dcSSimon Schubert    from external routines.  eg. elf_i386_check_relocs is called
5205796c8dcSSimon Schubert    early in the link process, elf_i386_finish_dynamic_sections is
5215796c8dcSSimon Schubert    one of the last functions.  */
5225796c8dcSSimon Schubert 
5235796c8dcSSimon Schubert 
5245796c8dcSSimon Schubert /* The name of the dynamic interpreter.  This is put in the .interp
5255796c8dcSSimon Schubert    section.  */
5265796c8dcSSimon Schubert 
5275796c8dcSSimon Schubert #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
5285796c8dcSSimon Schubert 
5295796c8dcSSimon Schubert /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
5305796c8dcSSimon Schubert    copying dynamic variables from a shared lib into an app's dynbss
5315796c8dcSSimon Schubert    section, and instead use a dynamic relocation to point into the
5325796c8dcSSimon Schubert    shared lib.  */
5335796c8dcSSimon Schubert #define ELIMINATE_COPY_RELOCS 1
5345796c8dcSSimon Schubert 
5355796c8dcSSimon Schubert /* The size in bytes of an entry in the procedure linkage table.  */
5365796c8dcSSimon Schubert 
5375796c8dcSSimon Schubert #define PLT_ENTRY_SIZE 16
5385796c8dcSSimon Schubert 
5395796c8dcSSimon Schubert /* The first entry in an absolute procedure linkage table looks like
5405796c8dcSSimon Schubert    this.  See the SVR4 ABI i386 supplement to see how this works.
5415796c8dcSSimon Schubert    Will be padded to PLT_ENTRY_SIZE with htab->plt0_pad_byte.  */
5425796c8dcSSimon Schubert 
5435796c8dcSSimon Schubert static const bfd_byte elf_i386_plt0_entry[12] =
5445796c8dcSSimon Schubert {
5455796c8dcSSimon Schubert   0xff, 0x35,	/* pushl contents of address */
5465796c8dcSSimon Schubert   0, 0, 0, 0,	/* replaced with address of .got + 4.  */
5475796c8dcSSimon Schubert   0xff, 0x25,	/* jmp indirect */
5485796c8dcSSimon Schubert   0, 0, 0, 0	/* replaced with address of .got + 8.  */
5495796c8dcSSimon Schubert };
5505796c8dcSSimon Schubert 
5515796c8dcSSimon Schubert /* Subsequent entries in an absolute procedure linkage table look like
5525796c8dcSSimon Schubert    this.  */
5535796c8dcSSimon Schubert 
5545796c8dcSSimon Schubert static const bfd_byte elf_i386_plt_entry[PLT_ENTRY_SIZE] =
5555796c8dcSSimon Schubert {
5565796c8dcSSimon Schubert   0xff, 0x25,	/* jmp indirect */
5575796c8dcSSimon Schubert   0, 0, 0, 0,	/* replaced with address of this symbol in .got.  */
5585796c8dcSSimon Schubert   0x68,		/* pushl immediate */
5595796c8dcSSimon Schubert   0, 0, 0, 0,	/* replaced with offset into relocation table.  */
5605796c8dcSSimon Schubert   0xe9,		/* jmp relative */
5615796c8dcSSimon Schubert   0, 0, 0, 0	/* replaced with offset to start of .plt.  */
5625796c8dcSSimon Schubert };
5635796c8dcSSimon Schubert 
5645796c8dcSSimon Schubert /* The first entry in a PIC procedure linkage table look like this.
5655796c8dcSSimon Schubert    Will be padded to PLT_ENTRY_SIZE with htab->plt0_pad_byte.  */
5665796c8dcSSimon Schubert 
5675796c8dcSSimon Schubert static const bfd_byte elf_i386_pic_plt0_entry[12] =
5685796c8dcSSimon Schubert {
5695796c8dcSSimon Schubert   0xff, 0xb3, 4, 0, 0, 0,	/* pushl 4(%ebx) */
5705796c8dcSSimon Schubert   0xff, 0xa3, 8, 0, 0, 0	/* jmp *8(%ebx) */
5715796c8dcSSimon Schubert };
5725796c8dcSSimon Schubert 
5735796c8dcSSimon Schubert /* Subsequent entries in a PIC procedure linkage table look like this.  */
5745796c8dcSSimon Schubert 
5755796c8dcSSimon Schubert static const bfd_byte elf_i386_pic_plt_entry[PLT_ENTRY_SIZE] =
5765796c8dcSSimon Schubert {
5775796c8dcSSimon Schubert   0xff, 0xa3,	/* jmp *offset(%ebx) */
5785796c8dcSSimon Schubert   0, 0, 0, 0,	/* replaced with offset of this symbol in .got.  */
5795796c8dcSSimon Schubert   0x68,		/* pushl immediate */
5805796c8dcSSimon Schubert   0, 0, 0, 0,	/* replaced with offset into relocation table.  */
5815796c8dcSSimon Schubert   0xe9,		/* jmp relative */
5825796c8dcSSimon Schubert   0, 0, 0, 0	/* replaced with offset to start of .plt.  */
5835796c8dcSSimon Schubert };
5845796c8dcSSimon Schubert 
585a45ae5f8SJohn Marino /* .eh_frame covering the .plt section.  */
586a45ae5f8SJohn Marino 
587a45ae5f8SJohn Marino static const bfd_byte elf_i386_eh_frame_plt[] =
588a45ae5f8SJohn Marino {
589a45ae5f8SJohn Marino #define PLT_CIE_LENGTH		20
590a45ae5f8SJohn Marino #define PLT_FDE_LENGTH		36
591a45ae5f8SJohn Marino #define PLT_FDE_START_OFFSET	4 + PLT_CIE_LENGTH + 8
592a45ae5f8SJohn Marino #define PLT_FDE_LEN_OFFSET	4 + PLT_CIE_LENGTH + 12
593a45ae5f8SJohn Marino   PLT_CIE_LENGTH, 0, 0, 0,	/* CIE length */
594a45ae5f8SJohn Marino   0, 0, 0, 0,			/* CIE ID */
595a45ae5f8SJohn Marino   1,				/* CIE version */
596a45ae5f8SJohn Marino   'z', 'R', 0,			/* Augmentation string */
597a45ae5f8SJohn Marino   1,				/* Code alignment factor */
598a45ae5f8SJohn Marino   0x7c,				/* Data alignment factor */
599a45ae5f8SJohn Marino   8,				/* Return address column */
600a45ae5f8SJohn Marino   1,				/* Augmentation size */
601a45ae5f8SJohn Marino   DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
602a45ae5f8SJohn Marino   DW_CFA_def_cfa, 4, 4,		/* DW_CFA_def_cfa: r4 (esp) ofs 4 */
603a45ae5f8SJohn Marino   DW_CFA_offset + 8, 1,		/* DW_CFA_offset: r8 (eip) at cfa-4 */
604a45ae5f8SJohn Marino   DW_CFA_nop, DW_CFA_nop,
605a45ae5f8SJohn Marino 
606a45ae5f8SJohn Marino   PLT_FDE_LENGTH, 0, 0, 0,	/* FDE length */
607a45ae5f8SJohn Marino   PLT_CIE_LENGTH + 8, 0, 0, 0,	/* CIE pointer */
608a45ae5f8SJohn Marino   0, 0, 0, 0,			/* R_386_PC32 .plt goes here */
609a45ae5f8SJohn Marino   0, 0, 0, 0,			/* .plt size goes here */
610a45ae5f8SJohn Marino   0,				/* Augmentation size */
611a45ae5f8SJohn Marino   DW_CFA_def_cfa_offset, 8,	/* DW_CFA_def_cfa_offset: 8 */
612a45ae5f8SJohn Marino   DW_CFA_advance_loc + 6,	/* DW_CFA_advance_loc: 6 to __PLT__+6 */
613a45ae5f8SJohn Marino   DW_CFA_def_cfa_offset, 12,	/* DW_CFA_def_cfa_offset: 12 */
614a45ae5f8SJohn Marino   DW_CFA_advance_loc + 10,	/* DW_CFA_advance_loc: 10 to __PLT__+16 */
615a45ae5f8SJohn Marino   DW_CFA_def_cfa_expression,	/* DW_CFA_def_cfa_expression */
616a45ae5f8SJohn Marino   11,				/* Block length */
617a45ae5f8SJohn Marino   DW_OP_breg4, 4,		/* DW_OP_breg4 (esp): 4 */
618a45ae5f8SJohn Marino   DW_OP_breg8, 0,		/* DW_OP_breg8 (eip): 0 */
619a45ae5f8SJohn Marino   DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge,
620a45ae5f8SJohn Marino   DW_OP_lit2, DW_OP_shl, DW_OP_plus,
621a45ae5f8SJohn Marino   DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
622a45ae5f8SJohn Marino };
623a45ae5f8SJohn Marino 
624a45ae5f8SJohn Marino struct elf_i386_plt_layout
625a45ae5f8SJohn Marino {
626a45ae5f8SJohn Marino   /* The first entry in an absolute procedure linkage table looks like this.  */
627a45ae5f8SJohn Marino   const bfd_byte *plt0_entry;
628a45ae5f8SJohn Marino   unsigned int plt0_entry_size;
629a45ae5f8SJohn Marino 
630a45ae5f8SJohn Marino   /* Offsets into plt0_entry that are to be replaced with GOT[1] and GOT[2].  */
631a45ae5f8SJohn Marino   unsigned int plt0_got1_offset;
632a45ae5f8SJohn Marino   unsigned int plt0_got2_offset;
633a45ae5f8SJohn Marino 
634a45ae5f8SJohn Marino   /* Later entries in an absolute procedure linkage table look like this.  */
635a45ae5f8SJohn Marino   const bfd_byte *plt_entry;
636a45ae5f8SJohn Marino   unsigned int plt_entry_size;
637a45ae5f8SJohn Marino 
638a45ae5f8SJohn Marino   /* Offsets into plt_entry that are to be replaced with...  */
639a45ae5f8SJohn Marino   unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
640a45ae5f8SJohn Marino   unsigned int plt_reloc_offset;  /* ... offset into relocation table. */
641a45ae5f8SJohn Marino   unsigned int plt_plt_offset;    /* ... offset to start of .plt. */
642a45ae5f8SJohn Marino 
643a45ae5f8SJohn Marino   /* Offset into plt_entry where the initial value of the GOT entry points.  */
644a45ae5f8SJohn Marino   unsigned int plt_lazy_offset;
645a45ae5f8SJohn Marino 
646a45ae5f8SJohn Marino   /* The first entry in a PIC procedure linkage table looks like this.  */
647a45ae5f8SJohn Marino   const bfd_byte *pic_plt0_entry;
648a45ae5f8SJohn Marino 
649a45ae5f8SJohn Marino   /* Subsequent entries in a PIC procedure linkage table look like this.  */
650a45ae5f8SJohn Marino   const bfd_byte *pic_plt_entry;
651a45ae5f8SJohn Marino 
652a45ae5f8SJohn Marino   /* .eh_frame covering the .plt section.  */
653a45ae5f8SJohn Marino   const bfd_byte *eh_frame_plt;
654a45ae5f8SJohn Marino   unsigned int eh_frame_plt_size;
655a45ae5f8SJohn Marino };
656a45ae5f8SJohn Marino 
657a45ae5f8SJohn Marino #define GET_PLT_ENTRY_SIZE(abfd) \
658a45ae5f8SJohn Marino   get_elf_i386_backend_data (abfd)->plt->plt_entry_size
659a45ae5f8SJohn Marino 
660a45ae5f8SJohn Marino /* These are the standard parameters.  */
661a45ae5f8SJohn Marino static const struct elf_i386_plt_layout elf_i386_plt =
662a45ae5f8SJohn Marino   {
663a45ae5f8SJohn Marino     elf_i386_plt0_entry,                /* plt0_entry */
664a45ae5f8SJohn Marino     sizeof (elf_i386_plt0_entry),       /* plt0_entry_size */
665a45ae5f8SJohn Marino     2,                                  /* plt0_got1_offset */
666a45ae5f8SJohn Marino     8,                                  /* plt0_got2_offset */
667a45ae5f8SJohn Marino     elf_i386_plt_entry,                 /* plt_entry */
668a45ae5f8SJohn Marino     PLT_ENTRY_SIZE,                     /* plt_entry_size */
669a45ae5f8SJohn Marino     2,                                  /* plt_got_offset */
670a45ae5f8SJohn Marino     7,                                  /* plt_reloc_offset */
671a45ae5f8SJohn Marino     12,                                 /* plt_plt_offset */
672a45ae5f8SJohn Marino     6,                                  /* plt_lazy_offset */
673a45ae5f8SJohn Marino     elf_i386_pic_plt0_entry,            /* pic_plt0_entry */
674a45ae5f8SJohn Marino     elf_i386_pic_plt_entry,             /* pic_plt_entry */
675a45ae5f8SJohn Marino     elf_i386_eh_frame_plt,              /* eh_frame_plt */
676a45ae5f8SJohn Marino     sizeof (elf_i386_eh_frame_plt),     /* eh_frame_plt_size */
677a45ae5f8SJohn Marino   };
678a45ae5f8SJohn Marino 
679a45ae5f8SJohn Marino 
6805796c8dcSSimon Schubert /* On VxWorks, the .rel.plt.unloaded section has absolute relocations
6815796c8dcSSimon Schubert    for the PLTResolve stub and then for each PLT entry.  */
6825796c8dcSSimon Schubert #define PLTRESOLVE_RELOCS_SHLIB 0
6835796c8dcSSimon Schubert #define PLTRESOLVE_RELOCS 2
6845796c8dcSSimon Schubert #define PLT_NON_JUMP_SLOT_RELOCS 2
6855796c8dcSSimon Schubert 
686a45ae5f8SJohn Marino /* Architecture-specific backend data for i386.  */
687a45ae5f8SJohn Marino 
688a45ae5f8SJohn Marino struct elf_i386_backend_data
689a45ae5f8SJohn Marino {
690a45ae5f8SJohn Marino   /* Parameters describing PLT generation.  */
691a45ae5f8SJohn Marino   const struct elf_i386_plt_layout *plt;
692a45ae5f8SJohn Marino 
693a45ae5f8SJohn Marino   /* Value used to fill the unused bytes of the first PLT entry.  */
694a45ae5f8SJohn Marino   bfd_byte plt0_pad_byte;
695a45ae5f8SJohn Marino 
696a45ae5f8SJohn Marino   /* True if the target system is VxWorks.  */
697a45ae5f8SJohn Marino   int is_vxworks;
698a45ae5f8SJohn Marino };
699a45ae5f8SJohn Marino 
700a45ae5f8SJohn Marino #define get_elf_i386_backend_data(abfd) \
701a45ae5f8SJohn Marino   ((const struct elf_i386_backend_data *) \
702a45ae5f8SJohn Marino    get_elf_backend_data (abfd)->arch_data)
703a45ae5f8SJohn Marino 
704a45ae5f8SJohn Marino /* These are the standard parameters.  */
705a45ae5f8SJohn Marino static const struct elf_i386_backend_data elf_i386_arch_bed =
706a45ae5f8SJohn Marino   {
707a45ae5f8SJohn Marino     &elf_i386_plt,                      /* plt */
708a45ae5f8SJohn Marino     0,                                  /* plt0_pad_byte */
709a45ae5f8SJohn Marino     0,                                  /* is_vxworks */
710a45ae5f8SJohn Marino   };
711a45ae5f8SJohn Marino 
712a45ae5f8SJohn Marino #define	elf_backend_arch_data	&elf_i386_arch_bed
713a45ae5f8SJohn Marino 
7145796c8dcSSimon Schubert /* i386 ELF linker hash entry.  */
7155796c8dcSSimon Schubert 
7165796c8dcSSimon Schubert struct elf_i386_link_hash_entry
7175796c8dcSSimon Schubert {
7185796c8dcSSimon Schubert   struct elf_link_hash_entry elf;
7195796c8dcSSimon Schubert 
7205796c8dcSSimon Schubert   /* Track dynamic relocs copied for this symbol.  */
7215796c8dcSSimon Schubert   struct elf_dyn_relocs *dyn_relocs;
7225796c8dcSSimon Schubert 
7235796c8dcSSimon Schubert #define GOT_UNKNOWN	0
7245796c8dcSSimon Schubert #define GOT_NORMAL	1
7255796c8dcSSimon Schubert #define GOT_TLS_GD	2
7265796c8dcSSimon Schubert #define GOT_TLS_IE	4
7275796c8dcSSimon Schubert #define GOT_TLS_IE_POS	5
7285796c8dcSSimon Schubert #define GOT_TLS_IE_NEG	6
7295796c8dcSSimon Schubert #define GOT_TLS_IE_BOTH 7
7305796c8dcSSimon Schubert #define GOT_TLS_GDESC	8
7315796c8dcSSimon Schubert #define GOT_TLS_GD_BOTH_P(type)						\
7325796c8dcSSimon Schubert   ((type) == (GOT_TLS_GD | GOT_TLS_GDESC))
7335796c8dcSSimon Schubert #define GOT_TLS_GD_P(type)						\
7345796c8dcSSimon Schubert   ((type) == GOT_TLS_GD || GOT_TLS_GD_BOTH_P (type))
7355796c8dcSSimon Schubert #define GOT_TLS_GDESC_P(type)						\
7365796c8dcSSimon Schubert   ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type))
7375796c8dcSSimon Schubert #define GOT_TLS_GD_ANY_P(type)						\
7385796c8dcSSimon Schubert   (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type))
7395796c8dcSSimon Schubert   unsigned char tls_type;
7405796c8dcSSimon Schubert 
7415796c8dcSSimon Schubert   /* Offset of the GOTPLT entry reserved for the TLS descriptor,
7425796c8dcSSimon Schubert      starting at the end of the jump table.  */
7435796c8dcSSimon Schubert   bfd_vma tlsdesc_got;
7445796c8dcSSimon Schubert };
7455796c8dcSSimon Schubert 
7465796c8dcSSimon Schubert #define elf_i386_hash_entry(ent) ((struct elf_i386_link_hash_entry *)(ent))
7475796c8dcSSimon Schubert 
7485796c8dcSSimon Schubert struct elf_i386_obj_tdata
7495796c8dcSSimon Schubert {
7505796c8dcSSimon Schubert   struct elf_obj_tdata root;
7515796c8dcSSimon Schubert 
7525796c8dcSSimon Schubert   /* tls_type for each local got entry.  */
7535796c8dcSSimon Schubert   char *local_got_tls_type;
7545796c8dcSSimon Schubert 
7555796c8dcSSimon Schubert   /* GOTPLT entries for TLS descriptors.  */
7565796c8dcSSimon Schubert   bfd_vma *local_tlsdesc_gotent;
7575796c8dcSSimon Schubert };
7585796c8dcSSimon Schubert 
7595796c8dcSSimon Schubert #define elf_i386_tdata(abfd) \
7605796c8dcSSimon Schubert   ((struct elf_i386_obj_tdata *) (abfd)->tdata.any)
7615796c8dcSSimon Schubert 
7625796c8dcSSimon Schubert #define elf_i386_local_got_tls_type(abfd) \
7635796c8dcSSimon Schubert   (elf_i386_tdata (abfd)->local_got_tls_type)
7645796c8dcSSimon Schubert 
7655796c8dcSSimon Schubert #define elf_i386_local_tlsdesc_gotent(abfd) \
7665796c8dcSSimon Schubert   (elf_i386_tdata (abfd)->local_tlsdesc_gotent)
7675796c8dcSSimon Schubert 
7685796c8dcSSimon Schubert #define is_i386_elf(bfd)				\
7695796c8dcSSimon Schubert   (bfd_get_flavour (bfd) == bfd_target_elf_flavour	\
7705796c8dcSSimon Schubert    && elf_tdata (bfd) != NULL				\
771cf7f2e2dSJohn Marino    && elf_object_id (bfd) == I386_ELF_DATA)
7725796c8dcSSimon Schubert 
7735796c8dcSSimon Schubert static bfd_boolean
elf_i386_mkobject(bfd * abfd)7745796c8dcSSimon Schubert elf_i386_mkobject (bfd *abfd)
7755796c8dcSSimon Schubert {
7765796c8dcSSimon Schubert   return bfd_elf_allocate_object (abfd, sizeof (struct elf_i386_obj_tdata),
777cf7f2e2dSJohn Marino 				  I386_ELF_DATA);
7785796c8dcSSimon Schubert }
7795796c8dcSSimon Schubert 
7805796c8dcSSimon Schubert /* i386 ELF linker hash table.  */
7815796c8dcSSimon Schubert 
7825796c8dcSSimon Schubert struct elf_i386_link_hash_table
7835796c8dcSSimon Schubert {
7845796c8dcSSimon Schubert   struct elf_link_hash_table elf;
7855796c8dcSSimon Schubert 
7865796c8dcSSimon Schubert   /* Short-cuts to get to dynamic linker sections.  */
7875796c8dcSSimon Schubert   asection *sdynbss;
7885796c8dcSSimon Schubert   asection *srelbss;
789a45ae5f8SJohn Marino   asection *plt_eh_frame;
7905796c8dcSSimon Schubert 
791cf7f2e2dSJohn Marino   union
792cf7f2e2dSJohn Marino   {
7935796c8dcSSimon Schubert     bfd_signed_vma refcount;
7945796c8dcSSimon Schubert     bfd_vma offset;
7955796c8dcSSimon Schubert   } tls_ldm_got;
7965796c8dcSSimon Schubert 
7975796c8dcSSimon Schubert   /* The amount of space used by the reserved portion of the sgotplt
7985796c8dcSSimon Schubert      section, plus whatever space is used by the jump slots.  */
7995796c8dcSSimon Schubert   bfd_vma sgotplt_jump_table_size;
8005796c8dcSSimon Schubert 
8015796c8dcSSimon Schubert   /* Small local sym cache.  */
8025796c8dcSSimon Schubert   struct sym_cache sym_cache;
8035796c8dcSSimon Schubert 
8045796c8dcSSimon Schubert   /* _TLS_MODULE_BASE_ symbol.  */
8055796c8dcSSimon Schubert   struct bfd_link_hash_entry *tls_module_base;
8065796c8dcSSimon Schubert 
8075796c8dcSSimon Schubert   /* Used by local STT_GNU_IFUNC symbols.  */
8085796c8dcSSimon Schubert   htab_t loc_hash_table;
8095796c8dcSSimon Schubert   void * loc_hash_memory;
810cf7f2e2dSJohn Marino 
811cf7f2e2dSJohn Marino   /* The (unloaded but important) .rel.plt.unloaded section on VxWorks.  */
812cf7f2e2dSJohn Marino   asection *srelplt2;
813cf7f2e2dSJohn Marino 
814cf7f2e2dSJohn Marino   /* The index of the next unused R_386_TLS_DESC slot in .rel.plt.  */
815cf7f2e2dSJohn Marino   bfd_vma next_tls_desc_index;
816cf7f2e2dSJohn Marino 
817a45ae5f8SJohn Marino   /* The index of the next unused R_386_JUMP_SLOT slot in .rel.plt.  */
818a45ae5f8SJohn Marino   bfd_vma next_jump_slot_index;
819a45ae5f8SJohn Marino 
820a45ae5f8SJohn Marino   /* The index of the next unused R_386_IRELATIVE slot in .rel.plt.  */
821a45ae5f8SJohn Marino   bfd_vma next_irelative_index;
8225796c8dcSSimon Schubert };
8235796c8dcSSimon Schubert 
8245796c8dcSSimon Schubert /* Get the i386 ELF linker hash table from a link_info structure.  */
8255796c8dcSSimon Schubert 
8265796c8dcSSimon Schubert #define elf_i386_hash_table(p) \
827cf7f2e2dSJohn Marino   (elf_hash_table_id  ((struct elf_link_hash_table *) ((p)->hash)) \
828cf7f2e2dSJohn Marino   == I386_ELF_DATA ? ((struct elf_i386_link_hash_table *) ((p)->hash)) : NULL)
8295796c8dcSSimon Schubert 
8305796c8dcSSimon Schubert #define elf_i386_compute_jump_table_size(htab) \
8315796c8dcSSimon Schubert   ((htab)->next_tls_desc_index * 4)
8325796c8dcSSimon Schubert 
8335796c8dcSSimon Schubert /* Create an entry in an i386 ELF linker hash table.  */
8345796c8dcSSimon Schubert 
8355796c8dcSSimon Schubert static struct bfd_hash_entry *
elf_i386_link_hash_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)8365796c8dcSSimon Schubert elf_i386_link_hash_newfunc (struct bfd_hash_entry *entry,
8375796c8dcSSimon Schubert 			    struct bfd_hash_table *table,
8385796c8dcSSimon Schubert 			    const char *string)
8395796c8dcSSimon Schubert {
8405796c8dcSSimon Schubert   /* Allocate the structure if it has not already been allocated by a
8415796c8dcSSimon Schubert      subclass.  */
8425796c8dcSSimon Schubert   if (entry == NULL)
8435796c8dcSSimon Schubert     {
8445796c8dcSSimon Schubert       entry = (struct bfd_hash_entry *)
8455796c8dcSSimon Schubert           bfd_hash_allocate (table, sizeof (struct elf_i386_link_hash_entry));
8465796c8dcSSimon Schubert       if (entry == NULL)
8475796c8dcSSimon Schubert 	return entry;
8485796c8dcSSimon Schubert     }
8495796c8dcSSimon Schubert 
8505796c8dcSSimon Schubert   /* Call the allocation method of the superclass.  */
8515796c8dcSSimon Schubert   entry = _bfd_elf_link_hash_newfunc (entry, table, string);
8525796c8dcSSimon Schubert   if (entry != NULL)
8535796c8dcSSimon Schubert     {
8545796c8dcSSimon Schubert       struct elf_i386_link_hash_entry *eh;
8555796c8dcSSimon Schubert 
8565796c8dcSSimon Schubert       eh = (struct elf_i386_link_hash_entry *) entry;
8575796c8dcSSimon Schubert       eh->dyn_relocs = NULL;
8585796c8dcSSimon Schubert       eh->tls_type = GOT_UNKNOWN;
8595796c8dcSSimon Schubert       eh->tlsdesc_got = (bfd_vma) -1;
8605796c8dcSSimon Schubert     }
8615796c8dcSSimon Schubert 
8625796c8dcSSimon Schubert   return entry;
8635796c8dcSSimon Schubert }
8645796c8dcSSimon Schubert 
8655796c8dcSSimon Schubert /* Compute a hash of a local hash entry.  We use elf_link_hash_entry
8665796c8dcSSimon Schubert   for local symbol so that we can handle local STT_GNU_IFUNC symbols
8675796c8dcSSimon Schubert   as global symbol.  We reuse indx and dynstr_index for local symbol
8685796c8dcSSimon Schubert   hash since they aren't used by global symbols in this backend.  */
8695796c8dcSSimon Schubert 
8705796c8dcSSimon Schubert static hashval_t
elf_i386_local_htab_hash(const void * ptr)8715796c8dcSSimon Schubert elf_i386_local_htab_hash (const void *ptr)
8725796c8dcSSimon Schubert {
8735796c8dcSSimon Schubert   struct elf_link_hash_entry *h
8745796c8dcSSimon Schubert     = (struct elf_link_hash_entry *) ptr;
8755796c8dcSSimon Schubert   return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
8765796c8dcSSimon Schubert }
8775796c8dcSSimon Schubert 
8785796c8dcSSimon Schubert /* Compare local hash entries.  */
8795796c8dcSSimon Schubert 
8805796c8dcSSimon Schubert static int
elf_i386_local_htab_eq(const void * ptr1,const void * ptr2)8815796c8dcSSimon Schubert elf_i386_local_htab_eq (const void *ptr1, const void *ptr2)
8825796c8dcSSimon Schubert {
8835796c8dcSSimon Schubert   struct elf_link_hash_entry *h1
8845796c8dcSSimon Schubert      = (struct elf_link_hash_entry *) ptr1;
8855796c8dcSSimon Schubert   struct elf_link_hash_entry *h2
8865796c8dcSSimon Schubert     = (struct elf_link_hash_entry *) ptr2;
8875796c8dcSSimon Schubert 
8885796c8dcSSimon Schubert   return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
8895796c8dcSSimon Schubert }
8905796c8dcSSimon Schubert 
8915796c8dcSSimon Schubert /* Find and/or create a hash entry for local symbol.  */
8925796c8dcSSimon Schubert 
8935796c8dcSSimon Schubert static struct elf_link_hash_entry *
elf_i386_get_local_sym_hash(struct elf_i386_link_hash_table * htab,bfd * abfd,const Elf_Internal_Rela * rel,bfd_boolean create)8945796c8dcSSimon Schubert elf_i386_get_local_sym_hash (struct elf_i386_link_hash_table *htab,
8955796c8dcSSimon Schubert 			     bfd *abfd, const Elf_Internal_Rela *rel,
8965796c8dcSSimon Schubert 			     bfd_boolean create)
8975796c8dcSSimon Schubert {
8985796c8dcSSimon Schubert   struct elf_i386_link_hash_entry e, *ret;
8995796c8dcSSimon Schubert   asection *sec = abfd->sections;
9005796c8dcSSimon Schubert   hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
9015796c8dcSSimon Schubert 				       ELF32_R_SYM (rel->r_info));
9025796c8dcSSimon Schubert   void **slot;
9035796c8dcSSimon Schubert 
9045796c8dcSSimon Schubert   e.elf.indx = sec->id;
9055796c8dcSSimon Schubert   e.elf.dynstr_index = ELF32_R_SYM (rel->r_info);
9065796c8dcSSimon Schubert   slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
9075796c8dcSSimon Schubert 				   create ? INSERT : NO_INSERT);
9085796c8dcSSimon Schubert 
9095796c8dcSSimon Schubert   if (!slot)
9105796c8dcSSimon Schubert     return NULL;
9115796c8dcSSimon Schubert 
9125796c8dcSSimon Schubert   if (*slot)
9135796c8dcSSimon Schubert     {
9145796c8dcSSimon Schubert       ret = (struct elf_i386_link_hash_entry *) *slot;
9155796c8dcSSimon Schubert       return &ret->elf;
9165796c8dcSSimon Schubert     }
9175796c8dcSSimon Schubert 
9185796c8dcSSimon Schubert   ret = (struct elf_i386_link_hash_entry *)
9195796c8dcSSimon Schubert 	objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
9205796c8dcSSimon Schubert 			sizeof (struct elf_i386_link_hash_entry));
9215796c8dcSSimon Schubert   if (ret)
9225796c8dcSSimon Schubert     {
9235796c8dcSSimon Schubert       memset (ret, 0, sizeof (*ret));
9245796c8dcSSimon Schubert       ret->elf.indx = sec->id;
9255796c8dcSSimon Schubert       ret->elf.dynstr_index = ELF32_R_SYM (rel->r_info);
9265796c8dcSSimon Schubert       ret->elf.dynindx = -1;
9275796c8dcSSimon Schubert       *slot = ret;
9285796c8dcSSimon Schubert     }
9295796c8dcSSimon Schubert   return &ret->elf;
9305796c8dcSSimon Schubert }
9315796c8dcSSimon Schubert 
9325796c8dcSSimon Schubert /* Create an i386 ELF linker hash table.  */
9335796c8dcSSimon Schubert 
9345796c8dcSSimon Schubert static struct bfd_link_hash_table *
elf_i386_link_hash_table_create(bfd * abfd)9355796c8dcSSimon Schubert elf_i386_link_hash_table_create (bfd *abfd)
9365796c8dcSSimon Schubert {
9375796c8dcSSimon Schubert   struct elf_i386_link_hash_table *ret;
9385796c8dcSSimon Schubert   bfd_size_type amt = sizeof (struct elf_i386_link_hash_table);
9395796c8dcSSimon Schubert 
940*ef5ccd6cSJohn Marino   ret = (struct elf_i386_link_hash_table *) bfd_zmalloc (amt);
9415796c8dcSSimon Schubert   if (ret == NULL)
9425796c8dcSSimon Schubert     return NULL;
9435796c8dcSSimon Schubert 
9445796c8dcSSimon Schubert   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
9455796c8dcSSimon Schubert 				      elf_i386_link_hash_newfunc,
946cf7f2e2dSJohn Marino 				      sizeof (struct elf_i386_link_hash_entry),
947cf7f2e2dSJohn Marino 				      I386_ELF_DATA))
9485796c8dcSSimon Schubert     {
9495796c8dcSSimon Schubert       free (ret);
9505796c8dcSSimon Schubert       return NULL;
9515796c8dcSSimon Schubert     }
9525796c8dcSSimon Schubert 
9535796c8dcSSimon Schubert   ret->loc_hash_table = htab_try_create (1024,
9545796c8dcSSimon Schubert 					 elf_i386_local_htab_hash,
9555796c8dcSSimon Schubert 					 elf_i386_local_htab_eq,
9565796c8dcSSimon Schubert 					 NULL);
9575796c8dcSSimon Schubert   ret->loc_hash_memory = objalloc_create ();
9585796c8dcSSimon Schubert   if (!ret->loc_hash_table || !ret->loc_hash_memory)
9595796c8dcSSimon Schubert     {
9605796c8dcSSimon Schubert       free (ret);
9615796c8dcSSimon Schubert       return NULL;
9625796c8dcSSimon Schubert     }
9635796c8dcSSimon Schubert 
9645796c8dcSSimon Schubert   return &ret->elf.root;
9655796c8dcSSimon Schubert }
9665796c8dcSSimon Schubert 
9675796c8dcSSimon Schubert /* Destroy an i386 ELF linker hash table.  */
9685796c8dcSSimon Schubert 
9695796c8dcSSimon Schubert static void
elf_i386_link_hash_table_free(struct bfd_link_hash_table * hash)9705796c8dcSSimon Schubert elf_i386_link_hash_table_free (struct bfd_link_hash_table *hash)
9715796c8dcSSimon Schubert {
9725796c8dcSSimon Schubert   struct elf_i386_link_hash_table *htab
9735796c8dcSSimon Schubert     = (struct elf_i386_link_hash_table *) hash;
9745796c8dcSSimon Schubert 
9755796c8dcSSimon Schubert   if (htab->loc_hash_table)
9765796c8dcSSimon Schubert     htab_delete (htab->loc_hash_table);
9775796c8dcSSimon Schubert   if (htab->loc_hash_memory)
9785796c8dcSSimon Schubert     objalloc_free ((struct objalloc *) htab->loc_hash_memory);
979*ef5ccd6cSJohn Marino   _bfd_elf_link_hash_table_free (hash);
9805796c8dcSSimon Schubert }
9815796c8dcSSimon Schubert 
9825796c8dcSSimon Schubert /* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and
9835796c8dcSSimon Schubert    .rel.bss sections in DYNOBJ, and set up shortcuts to them in our
9845796c8dcSSimon Schubert    hash table.  */
9855796c8dcSSimon Schubert 
9865796c8dcSSimon Schubert static bfd_boolean
elf_i386_create_dynamic_sections(bfd * dynobj,struct bfd_link_info * info)9875796c8dcSSimon Schubert elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
9885796c8dcSSimon Schubert {
9895796c8dcSSimon Schubert   struct elf_i386_link_hash_table *htab;
9905796c8dcSSimon Schubert 
9915796c8dcSSimon Schubert   if (!_bfd_elf_create_dynamic_sections (dynobj, info))
9925796c8dcSSimon Schubert     return FALSE;
9935796c8dcSSimon Schubert 
9945796c8dcSSimon Schubert   htab = elf_i386_hash_table (info);
995cf7f2e2dSJohn Marino   if (htab == NULL)
996cf7f2e2dSJohn Marino     return FALSE;
997cf7f2e2dSJohn Marino 
998*ef5ccd6cSJohn Marino   htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
9995796c8dcSSimon Schubert   if (!info->shared)
1000*ef5ccd6cSJohn Marino     htab->srelbss = bfd_get_linker_section (dynobj, ".rel.bss");
10015796c8dcSSimon Schubert 
10025796c8dcSSimon Schubert   if (!htab->sdynbss
10035796c8dcSSimon Schubert       || (!info->shared && !htab->srelbss))
10045796c8dcSSimon Schubert     abort ();
10055796c8dcSSimon Schubert 
1006a45ae5f8SJohn Marino   if (get_elf_i386_backend_data (dynobj)->is_vxworks
10075796c8dcSSimon Schubert       && !elf_vxworks_create_dynamic_sections (dynobj, info,
10085796c8dcSSimon Schubert 					       &htab->srelplt2))
10095796c8dcSSimon Schubert     return FALSE;
10105796c8dcSSimon Schubert 
1011a45ae5f8SJohn Marino   if (!info->no_ld_generated_unwind_info
1012*ef5ccd6cSJohn Marino       && htab->plt_eh_frame == NULL
1013a45ae5f8SJohn Marino       && htab->elf.splt != NULL)
1014a45ae5f8SJohn Marino     {
1015*ef5ccd6cSJohn Marino       flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
1016*ef5ccd6cSJohn Marino 			| SEC_HAS_CONTENTS | SEC_IN_MEMORY
1017*ef5ccd6cSJohn Marino 			| SEC_LINKER_CREATED);
1018a45ae5f8SJohn Marino       htab->plt_eh_frame
1019*ef5ccd6cSJohn Marino 	= bfd_make_section_anyway_with_flags (dynobj, ".eh_frame", flags);
1020a45ae5f8SJohn Marino       if (htab->plt_eh_frame == NULL
1021a45ae5f8SJohn Marino 	  || !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 2))
1022a45ae5f8SJohn Marino 	return FALSE;
1023a45ae5f8SJohn Marino     }
1024a45ae5f8SJohn Marino 
10255796c8dcSSimon Schubert   return TRUE;
10265796c8dcSSimon Schubert }
10275796c8dcSSimon Schubert 
10285796c8dcSSimon Schubert /* Copy the extra info we tack onto an elf_link_hash_entry.  */
10295796c8dcSSimon Schubert 
10305796c8dcSSimon Schubert static void
elf_i386_copy_indirect_symbol(struct bfd_link_info * info,struct elf_link_hash_entry * dir,struct elf_link_hash_entry * ind)10315796c8dcSSimon Schubert elf_i386_copy_indirect_symbol (struct bfd_link_info *info,
10325796c8dcSSimon Schubert 			       struct elf_link_hash_entry *dir,
10335796c8dcSSimon Schubert 			       struct elf_link_hash_entry *ind)
10345796c8dcSSimon Schubert {
10355796c8dcSSimon Schubert   struct elf_i386_link_hash_entry *edir, *eind;
10365796c8dcSSimon Schubert 
10375796c8dcSSimon Schubert   edir = (struct elf_i386_link_hash_entry *) dir;
10385796c8dcSSimon Schubert   eind = (struct elf_i386_link_hash_entry *) ind;
10395796c8dcSSimon Schubert 
10405796c8dcSSimon Schubert   if (eind->dyn_relocs != NULL)
10415796c8dcSSimon Schubert     {
10425796c8dcSSimon Schubert       if (edir->dyn_relocs != NULL)
10435796c8dcSSimon Schubert 	{
10445796c8dcSSimon Schubert 	  struct elf_dyn_relocs **pp;
10455796c8dcSSimon Schubert 	  struct elf_dyn_relocs *p;
10465796c8dcSSimon Schubert 
10475796c8dcSSimon Schubert 	  /* Add reloc counts against the indirect sym to the direct sym
10485796c8dcSSimon Schubert 	     list.  Merge any entries against the same section.  */
10495796c8dcSSimon Schubert 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
10505796c8dcSSimon Schubert 	    {
10515796c8dcSSimon Schubert 	      struct elf_dyn_relocs *q;
10525796c8dcSSimon Schubert 
10535796c8dcSSimon Schubert 	      for (q = edir->dyn_relocs; q != NULL; q = q->next)
10545796c8dcSSimon Schubert 		if (q->sec == p->sec)
10555796c8dcSSimon Schubert 		  {
10565796c8dcSSimon Schubert 		    q->pc_count += p->pc_count;
10575796c8dcSSimon Schubert 		    q->count += p->count;
10585796c8dcSSimon Schubert 		    *pp = p->next;
10595796c8dcSSimon Schubert 		    break;
10605796c8dcSSimon Schubert 		  }
10615796c8dcSSimon Schubert 	      if (q == NULL)
10625796c8dcSSimon Schubert 		pp = &p->next;
10635796c8dcSSimon Schubert 	    }
10645796c8dcSSimon Schubert 	  *pp = edir->dyn_relocs;
10655796c8dcSSimon Schubert 	}
10665796c8dcSSimon Schubert 
10675796c8dcSSimon Schubert       edir->dyn_relocs = eind->dyn_relocs;
10685796c8dcSSimon Schubert       eind->dyn_relocs = NULL;
10695796c8dcSSimon Schubert     }
10705796c8dcSSimon Schubert 
10715796c8dcSSimon Schubert   if (ind->root.type == bfd_link_hash_indirect
10725796c8dcSSimon Schubert       && dir->got.refcount <= 0)
10735796c8dcSSimon Schubert     {
10745796c8dcSSimon Schubert       edir->tls_type = eind->tls_type;
10755796c8dcSSimon Schubert       eind->tls_type = GOT_UNKNOWN;
10765796c8dcSSimon Schubert     }
10775796c8dcSSimon Schubert 
10785796c8dcSSimon Schubert   if (ELIMINATE_COPY_RELOCS
10795796c8dcSSimon Schubert       && ind->root.type != bfd_link_hash_indirect
10805796c8dcSSimon Schubert       && dir->dynamic_adjusted)
10815796c8dcSSimon Schubert     {
10825796c8dcSSimon Schubert       /* If called to transfer flags for a weakdef during processing
10835796c8dcSSimon Schubert 	 of elf_adjust_dynamic_symbol, don't copy non_got_ref.
10845796c8dcSSimon Schubert 	 We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
10855796c8dcSSimon Schubert       dir->ref_dynamic |= ind->ref_dynamic;
10865796c8dcSSimon Schubert       dir->ref_regular |= ind->ref_regular;
10875796c8dcSSimon Schubert       dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
10885796c8dcSSimon Schubert       dir->needs_plt |= ind->needs_plt;
10895796c8dcSSimon Schubert       dir->pointer_equality_needed |= ind->pointer_equality_needed;
10905796c8dcSSimon Schubert     }
10915796c8dcSSimon Schubert   else
10925796c8dcSSimon Schubert     _bfd_elf_link_hash_copy_indirect (info, dir, ind);
10935796c8dcSSimon Schubert }
10945796c8dcSSimon Schubert 
10955796c8dcSSimon Schubert /* Return TRUE if the TLS access code sequence support transition
10965796c8dcSSimon Schubert    from R_TYPE.  */
10975796c8dcSSimon Schubert 
10985796c8dcSSimon Schubert static bfd_boolean
elf_i386_check_tls_transition(bfd * abfd,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)10995796c8dcSSimon Schubert elf_i386_check_tls_transition (bfd *abfd, asection *sec,
11005796c8dcSSimon Schubert 			       bfd_byte *contents,
11015796c8dcSSimon Schubert 			       Elf_Internal_Shdr *symtab_hdr,
11025796c8dcSSimon Schubert 			       struct elf_link_hash_entry **sym_hashes,
11035796c8dcSSimon Schubert 			       unsigned int r_type,
11045796c8dcSSimon Schubert 			       const Elf_Internal_Rela *rel,
11055796c8dcSSimon Schubert 			       const Elf_Internal_Rela *relend)
11065796c8dcSSimon Schubert {
11075796c8dcSSimon Schubert   unsigned int val, type;
11085796c8dcSSimon Schubert   unsigned long r_symndx;
11095796c8dcSSimon Schubert   struct elf_link_hash_entry *h;
11105796c8dcSSimon Schubert   bfd_vma offset;
11115796c8dcSSimon Schubert 
11125796c8dcSSimon Schubert   /* Get the section contents.  */
11135796c8dcSSimon Schubert   if (contents == NULL)
11145796c8dcSSimon Schubert     {
11155796c8dcSSimon Schubert       if (elf_section_data (sec)->this_hdr.contents != NULL)
11165796c8dcSSimon Schubert 	contents = elf_section_data (sec)->this_hdr.contents;
11175796c8dcSSimon Schubert       else
11185796c8dcSSimon Schubert 	{
11195796c8dcSSimon Schubert 	  /* FIXME: How to better handle error condition?  */
11205796c8dcSSimon Schubert 	  if (!bfd_malloc_and_get_section (abfd, sec, &contents))
11215796c8dcSSimon Schubert 	    return FALSE;
11225796c8dcSSimon Schubert 
11235796c8dcSSimon Schubert 	  /* Cache the section contents for elf_link_input_bfd.  */
11245796c8dcSSimon Schubert 	  elf_section_data (sec)->this_hdr.contents = contents;
11255796c8dcSSimon Schubert 	}
11265796c8dcSSimon Schubert     }
11275796c8dcSSimon Schubert 
11285796c8dcSSimon Schubert   offset = rel->r_offset;
11295796c8dcSSimon Schubert   switch (r_type)
11305796c8dcSSimon Schubert     {
11315796c8dcSSimon Schubert     case R_386_TLS_GD:
11325796c8dcSSimon Schubert     case R_386_TLS_LDM:
11335796c8dcSSimon Schubert       if (offset < 2 || (rel + 1) >= relend)
11345796c8dcSSimon Schubert 	return FALSE;
11355796c8dcSSimon Schubert 
11365796c8dcSSimon Schubert       type = bfd_get_8 (abfd, contents + offset - 2);
11375796c8dcSSimon Schubert       if (r_type == R_386_TLS_GD)
11385796c8dcSSimon Schubert 	{
11395796c8dcSSimon Schubert 	  /* Check transition from GD access model.  Only
11405796c8dcSSimon Schubert 		leal foo@tlsgd(,%reg,1), %eax; call ___tls_get_addr
11415796c8dcSSimon Schubert 		leal foo@tlsgd(%reg), %eax; call ___tls_get_addr; nop
11425796c8dcSSimon Schubert 	     can transit to different access model.  */
11435796c8dcSSimon Schubert 	  if ((offset + 10) > sec->size ||
11445796c8dcSSimon Schubert 	      (type != 0x8d && type != 0x04))
11455796c8dcSSimon Schubert 	    return FALSE;
11465796c8dcSSimon Schubert 
11475796c8dcSSimon Schubert 	  val = bfd_get_8 (abfd, contents + offset - 1);
11485796c8dcSSimon Schubert 	  if (type == 0x04)
11495796c8dcSSimon Schubert 	    {
11505796c8dcSSimon Schubert 	      /* leal foo@tlsgd(,%reg,1), %eax; call ___tls_get_addr */
11515796c8dcSSimon Schubert 	      if (offset < 3)
11525796c8dcSSimon Schubert 		return FALSE;
11535796c8dcSSimon Schubert 
11545796c8dcSSimon Schubert 	      if (bfd_get_8 (abfd, contents + offset - 3) != 0x8d)
11555796c8dcSSimon Schubert 		return FALSE;
11565796c8dcSSimon Schubert 
11575796c8dcSSimon Schubert 	      if ((val & 0xc7) != 0x05 || val == (4 << 3))
11585796c8dcSSimon Schubert 		return FALSE;
11595796c8dcSSimon Schubert 	    }
11605796c8dcSSimon Schubert 	  else
11615796c8dcSSimon Schubert 	    {
11625796c8dcSSimon Schubert 	      /* leal foo@tlsgd(%reg), %eax; call ___tls_get_addr; nop  */
11635796c8dcSSimon Schubert 	      if ((val & 0xf8) != 0x80 || (val & 7) == 4)
11645796c8dcSSimon Schubert 		return FALSE;
11655796c8dcSSimon Schubert 
11665796c8dcSSimon Schubert 	      if (bfd_get_8 (abfd, contents + offset + 9) != 0x90)
11675796c8dcSSimon Schubert 		return FALSE;
11685796c8dcSSimon Schubert 	    }
11695796c8dcSSimon Schubert 	}
11705796c8dcSSimon Schubert       else
11715796c8dcSSimon Schubert 	{
11725796c8dcSSimon Schubert 	  /* Check transition from LD access model.  Only
11735796c8dcSSimon Schubert 		leal foo@tlsgd(%reg), %eax; call ___tls_get_addr
11745796c8dcSSimon Schubert 	     can transit to different access model.  */
11755796c8dcSSimon Schubert 	  if (type != 0x8d || (offset + 9) > sec->size)
11765796c8dcSSimon Schubert 	    return FALSE;
11775796c8dcSSimon Schubert 
11785796c8dcSSimon Schubert 	  val = bfd_get_8 (abfd, contents + offset - 1);
11795796c8dcSSimon Schubert 	  if ((val & 0xf8) != 0x80 || (val & 7) == 4)
11805796c8dcSSimon Schubert 	    return FALSE;
11815796c8dcSSimon Schubert 	}
11825796c8dcSSimon Schubert 
11835796c8dcSSimon Schubert       if (bfd_get_8 (abfd, contents + offset + 4) != 0xe8)
11845796c8dcSSimon Schubert 	return FALSE;
11855796c8dcSSimon Schubert 
11865796c8dcSSimon Schubert       r_symndx = ELF32_R_SYM (rel[1].r_info);
11875796c8dcSSimon Schubert       if (r_symndx < symtab_hdr->sh_info)
11885796c8dcSSimon Schubert 	return FALSE;
11895796c8dcSSimon Schubert 
11905796c8dcSSimon Schubert       h = sym_hashes[r_symndx - symtab_hdr->sh_info];
11915796c8dcSSimon Schubert       /* Use strncmp to check ___tls_get_addr since ___tls_get_addr
11925796c8dcSSimon Schubert 	 may be versioned.  */
11935796c8dcSSimon Schubert       return (h != NULL
11945796c8dcSSimon Schubert 	      && h->root.root.string != NULL
11955796c8dcSSimon Schubert 	      && (ELF32_R_TYPE (rel[1].r_info) == R_386_PC32
11965796c8dcSSimon Schubert 		  || ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32)
11975796c8dcSSimon Schubert 	      && (strncmp (h->root.root.string, "___tls_get_addr",
11985796c8dcSSimon Schubert 			   15) == 0));
11995796c8dcSSimon Schubert 
12005796c8dcSSimon Schubert     case R_386_TLS_IE:
12015796c8dcSSimon Schubert       /* Check transition from IE access model:
12025796c8dcSSimon Schubert 		movl foo@indntpoff(%rip), %eax
12035796c8dcSSimon Schubert 		movl foo@indntpoff(%rip), %reg
12045796c8dcSSimon Schubert 		addl foo@indntpoff(%rip), %reg
12055796c8dcSSimon Schubert        */
12065796c8dcSSimon Schubert 
12075796c8dcSSimon Schubert       if (offset < 1 || (offset + 4) > sec->size)
12085796c8dcSSimon Schubert 	return FALSE;
12095796c8dcSSimon Schubert 
12105796c8dcSSimon Schubert       /* Check "movl foo@tpoff(%rip), %eax" first.  */
12115796c8dcSSimon Schubert       val = bfd_get_8 (abfd, contents + offset - 1);
12125796c8dcSSimon Schubert       if (val == 0xa1)
12135796c8dcSSimon Schubert 	return TRUE;
12145796c8dcSSimon Schubert 
12155796c8dcSSimon Schubert       if (offset < 2)
12165796c8dcSSimon Schubert 	return FALSE;
12175796c8dcSSimon Schubert 
12185796c8dcSSimon Schubert       /* Check movl|addl foo@tpoff(%rip), %reg.   */
12195796c8dcSSimon Schubert       type = bfd_get_8 (abfd, contents + offset - 2);
12205796c8dcSSimon Schubert       return ((type == 0x8b || type == 0x03)
12215796c8dcSSimon Schubert 	      && (val & 0xc7) == 0x05);
12225796c8dcSSimon Schubert 
12235796c8dcSSimon Schubert     case R_386_TLS_GOTIE:
12245796c8dcSSimon Schubert     case R_386_TLS_IE_32:
12255796c8dcSSimon Schubert       /* Check transition from {IE_32,GOTIE} access model:
12265796c8dcSSimon Schubert 		subl foo@{tpoff,gontoff}(%reg1), %reg2
12275796c8dcSSimon Schubert 		movl foo@{tpoff,gontoff}(%reg1), %reg2
12285796c8dcSSimon Schubert 		addl foo@{tpoff,gontoff}(%reg1), %reg2
12295796c8dcSSimon Schubert        */
12305796c8dcSSimon Schubert 
12315796c8dcSSimon Schubert       if (offset < 2 || (offset + 4) > sec->size)
12325796c8dcSSimon Schubert 	return FALSE;
12335796c8dcSSimon Schubert 
12345796c8dcSSimon Schubert       val = bfd_get_8 (abfd, contents + offset - 1);
12355796c8dcSSimon Schubert       if ((val & 0xc0) != 0x80 || (val & 7) == 4)
12365796c8dcSSimon Schubert 	return FALSE;
12375796c8dcSSimon Schubert 
12385796c8dcSSimon Schubert       type = bfd_get_8 (abfd, contents + offset - 2);
12395796c8dcSSimon Schubert       return type == 0x8b || type == 0x2b || type == 0x03;
12405796c8dcSSimon Schubert 
12415796c8dcSSimon Schubert     case R_386_TLS_GOTDESC:
12425796c8dcSSimon Schubert       /* Check transition from GDesc access model:
12435796c8dcSSimon Schubert 		leal x@tlsdesc(%ebx), %eax
12445796c8dcSSimon Schubert 
12455796c8dcSSimon Schubert 	 Make sure it's a leal adding ebx to a 32-bit offset
12465796c8dcSSimon Schubert 	 into any register, although it's probably almost always
12475796c8dcSSimon Schubert 	 going to be eax.  */
12485796c8dcSSimon Schubert 
12495796c8dcSSimon Schubert       if (offset < 2 || (offset + 4) > sec->size)
12505796c8dcSSimon Schubert 	return FALSE;
12515796c8dcSSimon Schubert 
12525796c8dcSSimon Schubert       if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d)
12535796c8dcSSimon Schubert 	return FALSE;
12545796c8dcSSimon Schubert 
12555796c8dcSSimon Schubert       val = bfd_get_8 (abfd, contents + offset - 1);
12565796c8dcSSimon Schubert       return (val & 0xc7) == 0x83;
12575796c8dcSSimon Schubert 
12585796c8dcSSimon Schubert     case R_386_TLS_DESC_CALL:
12595796c8dcSSimon Schubert       /* Check transition from GDesc access model:
12605796c8dcSSimon Schubert 		call *x@tlsdesc(%rax)
12615796c8dcSSimon Schubert        */
12625796c8dcSSimon Schubert       if (offset + 2 <= sec->size)
12635796c8dcSSimon Schubert 	{
12645796c8dcSSimon Schubert 	  /* Make sure that it's a call *x@tlsdesc(%rax).  */
1265a45ae5f8SJohn Marino 	  static const unsigned char call[] = { 0xff, 0x10 };
1266a45ae5f8SJohn Marino 	  return memcmp (contents + offset, call, 2) == 0;
12675796c8dcSSimon Schubert 	}
12685796c8dcSSimon Schubert 
12695796c8dcSSimon Schubert       return FALSE;
12705796c8dcSSimon Schubert 
12715796c8dcSSimon Schubert     default:
12725796c8dcSSimon Schubert       abort ();
12735796c8dcSSimon Schubert     }
12745796c8dcSSimon Schubert }
12755796c8dcSSimon Schubert 
12765796c8dcSSimon Schubert /* Return TRUE if the TLS access transition is OK or no transition
12775796c8dcSSimon Schubert    will be performed.  Update R_TYPE if there is a transition.  */
12785796c8dcSSimon Schubert 
12795796c8dcSSimon Schubert static bfd_boolean
elf_i386_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)12805796c8dcSSimon Schubert elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd,
12815796c8dcSSimon Schubert 			 asection *sec, bfd_byte *contents,
12825796c8dcSSimon Schubert 			 Elf_Internal_Shdr *symtab_hdr,
12835796c8dcSSimon Schubert 			 struct elf_link_hash_entry **sym_hashes,
12845796c8dcSSimon Schubert 			 unsigned int *r_type, int tls_type,
12855796c8dcSSimon Schubert 			 const Elf_Internal_Rela *rel,
12865796c8dcSSimon Schubert 			 const Elf_Internal_Rela *relend,
12875796c8dcSSimon Schubert 			 struct elf_link_hash_entry *h,
12885796c8dcSSimon Schubert 			 unsigned long r_symndx)
12895796c8dcSSimon Schubert {
12905796c8dcSSimon Schubert   unsigned int from_type = *r_type;
12915796c8dcSSimon Schubert   unsigned int to_type = from_type;
12925796c8dcSSimon Schubert   bfd_boolean check = TRUE;
12935796c8dcSSimon Schubert 
1294c50c785cSJohn Marino   /* Skip TLS transition for functions.  */
1295c50c785cSJohn Marino   if (h != NULL
1296c50c785cSJohn Marino       && (h->type == STT_FUNC
1297c50c785cSJohn Marino 	  || h->type == STT_GNU_IFUNC))
1298c50c785cSJohn Marino     return TRUE;
1299c50c785cSJohn Marino 
13005796c8dcSSimon Schubert   switch (from_type)
13015796c8dcSSimon Schubert     {
13025796c8dcSSimon Schubert     case R_386_TLS_GD:
13035796c8dcSSimon Schubert     case R_386_TLS_GOTDESC:
13045796c8dcSSimon Schubert     case R_386_TLS_DESC_CALL:
13055796c8dcSSimon Schubert     case R_386_TLS_IE_32:
13065796c8dcSSimon Schubert     case R_386_TLS_IE:
13075796c8dcSSimon Schubert     case R_386_TLS_GOTIE:
13085796c8dcSSimon Schubert       if (info->executable)
13095796c8dcSSimon Schubert 	{
13105796c8dcSSimon Schubert 	  if (h == NULL)
13115796c8dcSSimon Schubert 	    to_type = R_386_TLS_LE_32;
13125796c8dcSSimon Schubert 	  else if (from_type != R_386_TLS_IE
13135796c8dcSSimon Schubert 		   && from_type != R_386_TLS_GOTIE)
13145796c8dcSSimon Schubert 	    to_type = R_386_TLS_IE_32;
13155796c8dcSSimon Schubert 	}
13165796c8dcSSimon Schubert 
13175796c8dcSSimon Schubert       /* When we are called from elf_i386_relocate_section, CONTENTS
13185796c8dcSSimon Schubert 	 isn't NULL and there may be additional transitions based on
13195796c8dcSSimon Schubert 	 TLS_TYPE.  */
13205796c8dcSSimon Schubert       if (contents != NULL)
13215796c8dcSSimon Schubert 	{
13225796c8dcSSimon Schubert 	  unsigned int new_to_type = to_type;
13235796c8dcSSimon Schubert 
13245796c8dcSSimon Schubert 	  if (info->executable
13255796c8dcSSimon Schubert 	      && h != NULL
13265796c8dcSSimon Schubert 	      && h->dynindx == -1
13275796c8dcSSimon Schubert 	      && (tls_type & GOT_TLS_IE))
13285796c8dcSSimon Schubert 	    new_to_type = R_386_TLS_LE_32;
13295796c8dcSSimon Schubert 
13305796c8dcSSimon Schubert 	  if (to_type == R_386_TLS_GD
13315796c8dcSSimon Schubert 	      || to_type == R_386_TLS_GOTDESC
13325796c8dcSSimon Schubert 	      || to_type == R_386_TLS_DESC_CALL)
13335796c8dcSSimon Schubert 	    {
13345796c8dcSSimon Schubert 	      if (tls_type == GOT_TLS_IE_POS)
13355796c8dcSSimon Schubert 		new_to_type = R_386_TLS_GOTIE;
13365796c8dcSSimon Schubert 	      else if (tls_type & GOT_TLS_IE)
13375796c8dcSSimon Schubert 		new_to_type = R_386_TLS_IE_32;
13385796c8dcSSimon Schubert 	    }
13395796c8dcSSimon Schubert 
13405796c8dcSSimon Schubert 	  /* We checked the transition before when we were called from
13415796c8dcSSimon Schubert 	     elf_i386_check_relocs.  We only want to check the new
13425796c8dcSSimon Schubert 	     transition which hasn't been checked before.  */
13435796c8dcSSimon Schubert 	  check = new_to_type != to_type && from_type == to_type;
13445796c8dcSSimon Schubert 	  to_type = new_to_type;
13455796c8dcSSimon Schubert 	}
13465796c8dcSSimon Schubert 
13475796c8dcSSimon Schubert       break;
13485796c8dcSSimon Schubert 
13495796c8dcSSimon Schubert     case R_386_TLS_LDM:
13505796c8dcSSimon Schubert       if (info->executable)
13515796c8dcSSimon Schubert 	to_type = R_386_TLS_LE_32;
13525796c8dcSSimon Schubert       break;
13535796c8dcSSimon Schubert 
13545796c8dcSSimon Schubert     default:
13555796c8dcSSimon Schubert       return TRUE;
13565796c8dcSSimon Schubert     }
13575796c8dcSSimon Schubert 
13585796c8dcSSimon Schubert   /* Return TRUE if there is no transition.  */
13595796c8dcSSimon Schubert   if (from_type == to_type)
13605796c8dcSSimon Schubert     return TRUE;
13615796c8dcSSimon Schubert 
13625796c8dcSSimon Schubert   /* Check if the transition can be performed.  */
13635796c8dcSSimon Schubert   if (check
13645796c8dcSSimon Schubert       && ! elf_i386_check_tls_transition (abfd, sec, contents,
13655796c8dcSSimon Schubert 					  symtab_hdr, sym_hashes,
13665796c8dcSSimon Schubert 					  from_type, rel, relend))
13675796c8dcSSimon Schubert     {
13685796c8dcSSimon Schubert       reloc_howto_type *from, *to;
13695796c8dcSSimon Schubert       const char *name;
13705796c8dcSSimon Schubert 
13715796c8dcSSimon Schubert       from = elf_i386_rtype_to_howto (abfd, from_type);
13725796c8dcSSimon Schubert       to = elf_i386_rtype_to_howto (abfd, to_type);
13735796c8dcSSimon Schubert 
13745796c8dcSSimon Schubert       if (h)
13755796c8dcSSimon Schubert 	name = h->root.root.string;
13765796c8dcSSimon Schubert       else
13775796c8dcSSimon Schubert 	{
13785796c8dcSSimon Schubert 	  struct elf_i386_link_hash_table *htab;
1379cf7f2e2dSJohn Marino 
13805796c8dcSSimon Schubert 	  htab = elf_i386_hash_table (info);
1381cf7f2e2dSJohn Marino 	  if (htab == NULL)
1382cf7f2e2dSJohn Marino 	    name = "*unknown*";
1383cf7f2e2dSJohn Marino 	  else
1384cf7f2e2dSJohn Marino 	    {
1385cf7f2e2dSJohn Marino 	      Elf_Internal_Sym *isym;
1386cf7f2e2dSJohn Marino 
13875796c8dcSSimon Schubert 	      isym = bfd_sym_from_r_symndx (&htab->sym_cache,
13885796c8dcSSimon Schubert 					    abfd, r_symndx);
13895796c8dcSSimon Schubert 	      name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
13905796c8dcSSimon Schubert 	    }
1391cf7f2e2dSJohn Marino 	}
13925796c8dcSSimon Schubert 
13935796c8dcSSimon Schubert       (*_bfd_error_handler)
13945796c8dcSSimon Schubert 	(_("%B: TLS transition from %s to %s against `%s' at 0x%lx "
13955796c8dcSSimon Schubert 	   "in section `%A' failed"),
13965796c8dcSSimon Schubert 	 abfd, sec, from->name, to->name, name,
13975796c8dcSSimon Schubert 	 (unsigned long) rel->r_offset);
13985796c8dcSSimon Schubert       bfd_set_error (bfd_error_bad_value);
13995796c8dcSSimon Schubert       return FALSE;
14005796c8dcSSimon Schubert     }
14015796c8dcSSimon Schubert 
14025796c8dcSSimon Schubert   *r_type = to_type;
14035796c8dcSSimon Schubert   return TRUE;
14045796c8dcSSimon Schubert }
14055796c8dcSSimon Schubert 
14065796c8dcSSimon Schubert /* Look through the relocs for a section during the first phase, and
14075796c8dcSSimon Schubert    calculate needed space in the global offset table, procedure linkage
14085796c8dcSSimon Schubert    table, and dynamic reloc sections.  */
14095796c8dcSSimon Schubert 
14105796c8dcSSimon Schubert static bfd_boolean
elf_i386_check_relocs(bfd * abfd,struct bfd_link_info * info,asection * sec,const Elf_Internal_Rela * relocs)14115796c8dcSSimon Schubert elf_i386_check_relocs (bfd *abfd,
14125796c8dcSSimon Schubert 		       struct bfd_link_info *info,
14135796c8dcSSimon Schubert 		       asection *sec,
14145796c8dcSSimon Schubert 		       const Elf_Internal_Rela *relocs)
14155796c8dcSSimon Schubert {
14165796c8dcSSimon Schubert   struct elf_i386_link_hash_table *htab;
14175796c8dcSSimon Schubert   Elf_Internal_Shdr *symtab_hdr;
14185796c8dcSSimon Schubert   struct elf_link_hash_entry **sym_hashes;
14195796c8dcSSimon Schubert   const Elf_Internal_Rela *rel;
14205796c8dcSSimon Schubert   const Elf_Internal_Rela *rel_end;
14215796c8dcSSimon Schubert   asection *sreloc;
14225796c8dcSSimon Schubert 
14235796c8dcSSimon Schubert   if (info->relocatable)
14245796c8dcSSimon Schubert     return TRUE;
14255796c8dcSSimon Schubert 
14265796c8dcSSimon Schubert   BFD_ASSERT (is_i386_elf (abfd));
14275796c8dcSSimon Schubert 
14285796c8dcSSimon Schubert   htab = elf_i386_hash_table (info);
1429cf7f2e2dSJohn Marino   if (htab == NULL)
1430cf7f2e2dSJohn Marino     return FALSE;
1431cf7f2e2dSJohn Marino 
14325796c8dcSSimon Schubert   symtab_hdr = &elf_symtab_hdr (abfd);
14335796c8dcSSimon Schubert   sym_hashes = elf_sym_hashes (abfd);
14345796c8dcSSimon Schubert 
14355796c8dcSSimon Schubert   sreloc = NULL;
14365796c8dcSSimon Schubert 
14375796c8dcSSimon Schubert   rel_end = relocs + sec->reloc_count;
14385796c8dcSSimon Schubert   for (rel = relocs; rel < rel_end; rel++)
14395796c8dcSSimon Schubert     {
14405796c8dcSSimon Schubert       unsigned int r_type;
14415796c8dcSSimon Schubert       unsigned long r_symndx;
14425796c8dcSSimon Schubert       struct elf_link_hash_entry *h;
14435796c8dcSSimon Schubert       Elf_Internal_Sym *isym;
14445796c8dcSSimon Schubert       const char *name;
1445*ef5ccd6cSJohn Marino       bfd_boolean size_reloc;
14465796c8dcSSimon Schubert 
14475796c8dcSSimon Schubert       r_symndx = ELF32_R_SYM (rel->r_info);
14485796c8dcSSimon Schubert       r_type = ELF32_R_TYPE (rel->r_info);
14495796c8dcSSimon Schubert 
14505796c8dcSSimon Schubert       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
14515796c8dcSSimon Schubert 	{
14525796c8dcSSimon Schubert 	  (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
14535796c8dcSSimon Schubert 				 abfd,
14545796c8dcSSimon Schubert 				 r_symndx);
14555796c8dcSSimon Schubert 	  return FALSE;
14565796c8dcSSimon Schubert 	}
14575796c8dcSSimon Schubert 
14585796c8dcSSimon Schubert       if (r_symndx < symtab_hdr->sh_info)
14595796c8dcSSimon Schubert 	{
14605796c8dcSSimon Schubert 	  /* A local symbol.  */
14615796c8dcSSimon Schubert 	  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
14625796c8dcSSimon Schubert 					abfd, r_symndx);
14635796c8dcSSimon Schubert 	  if (isym == NULL)
14645796c8dcSSimon Schubert 	    return FALSE;
14655796c8dcSSimon Schubert 
14665796c8dcSSimon Schubert 	  /* Check relocation against local STT_GNU_IFUNC symbol.  */
14675796c8dcSSimon Schubert 	  if (ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
14685796c8dcSSimon Schubert 	    {
1469c50c785cSJohn Marino 	      h = elf_i386_get_local_sym_hash (htab, abfd, rel, TRUE);
14705796c8dcSSimon Schubert 	      if (h == NULL)
14715796c8dcSSimon Schubert 		return FALSE;
14725796c8dcSSimon Schubert 
14735796c8dcSSimon Schubert 	      /* Fake a STT_GNU_IFUNC symbol.  */
14745796c8dcSSimon Schubert 	      h->type = STT_GNU_IFUNC;
14755796c8dcSSimon Schubert 	      h->def_regular = 1;
14765796c8dcSSimon Schubert 	      h->ref_regular = 1;
14775796c8dcSSimon Schubert 	      h->forced_local = 1;
14785796c8dcSSimon Schubert 	      h->root.type = bfd_link_hash_defined;
14795796c8dcSSimon Schubert 	    }
14805796c8dcSSimon Schubert 	  else
14815796c8dcSSimon Schubert 	    h = NULL;
14825796c8dcSSimon Schubert 	}
14835796c8dcSSimon Schubert       else
14845796c8dcSSimon Schubert 	{
14855796c8dcSSimon Schubert 	  isym = NULL;
14865796c8dcSSimon Schubert 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
14875796c8dcSSimon Schubert 	  while (h->root.type == bfd_link_hash_indirect
14885796c8dcSSimon Schubert 		 || h->root.type == bfd_link_hash_warning)
14895796c8dcSSimon Schubert 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
14905796c8dcSSimon Schubert 	}
14915796c8dcSSimon Schubert 
14925796c8dcSSimon Schubert       if (h != NULL)
14935796c8dcSSimon Schubert 	{
14945796c8dcSSimon Schubert 	  /* Create the ifunc sections for static executables.  If we
14955796c8dcSSimon Schubert 	     never see an indirect function symbol nor we are building
14965796c8dcSSimon Schubert 	     a static executable, those sections will be empty and
14975796c8dcSSimon Schubert 	     won't appear in output.  */
14985796c8dcSSimon Schubert 	  switch (r_type)
14995796c8dcSSimon Schubert 	    {
15005796c8dcSSimon Schubert 	    default:
15015796c8dcSSimon Schubert 	      break;
15025796c8dcSSimon Schubert 
15035796c8dcSSimon Schubert 	    case R_386_32:
15045796c8dcSSimon Schubert 	    case R_386_PC32:
15055796c8dcSSimon Schubert 	    case R_386_PLT32:
15065796c8dcSSimon Schubert 	    case R_386_GOT32:
15075796c8dcSSimon Schubert 	    case R_386_GOTOFF:
1508a45ae5f8SJohn Marino 	      if (htab->elf.dynobj == NULL)
1509a45ae5f8SJohn Marino 		htab->elf.dynobj = abfd;
1510a45ae5f8SJohn Marino 	      if (!_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
15115796c8dcSSimon Schubert 		return FALSE;
15125796c8dcSSimon Schubert 	      break;
15135796c8dcSSimon Schubert 	    }
15145796c8dcSSimon Schubert 
15155796c8dcSSimon Schubert 	  /* It is referenced by a non-shared object. */
15165796c8dcSSimon Schubert 	  h->ref_regular = 1;
15175796c8dcSSimon Schubert 	}
15185796c8dcSSimon Schubert 
15195796c8dcSSimon Schubert       if (! elf_i386_tls_transition (info, abfd, sec, NULL,
15205796c8dcSSimon Schubert 				     symtab_hdr, sym_hashes,
15215796c8dcSSimon Schubert 				     &r_type, GOT_UNKNOWN,
15225796c8dcSSimon Schubert 				     rel, rel_end, h, r_symndx))
15235796c8dcSSimon Schubert 	return FALSE;
15245796c8dcSSimon Schubert 
15255796c8dcSSimon Schubert       switch (r_type)
15265796c8dcSSimon Schubert 	{
15275796c8dcSSimon Schubert 	case R_386_TLS_LDM:
15285796c8dcSSimon Schubert 	  htab->tls_ldm_got.refcount += 1;
15295796c8dcSSimon Schubert 	  goto create_got;
15305796c8dcSSimon Schubert 
15315796c8dcSSimon Schubert 	case R_386_PLT32:
15325796c8dcSSimon Schubert 	  /* This symbol requires a procedure linkage table entry.  We
15335796c8dcSSimon Schubert 	     actually build the entry in adjust_dynamic_symbol,
15345796c8dcSSimon Schubert 	     because this might be a case of linking PIC code which is
15355796c8dcSSimon Schubert 	     never referenced by a dynamic object, in which case we
15365796c8dcSSimon Schubert 	     don't need to generate a procedure linkage table entry
15375796c8dcSSimon Schubert 	     after all.  */
15385796c8dcSSimon Schubert 
15395796c8dcSSimon Schubert 	  /* If this is a local symbol, we resolve it directly without
15405796c8dcSSimon Schubert 	     creating a procedure linkage table entry.  */
15415796c8dcSSimon Schubert 	  if (h == NULL)
15425796c8dcSSimon Schubert 	    continue;
15435796c8dcSSimon Schubert 
15445796c8dcSSimon Schubert 	  h->needs_plt = 1;
15455796c8dcSSimon Schubert 	  h->plt.refcount += 1;
15465796c8dcSSimon Schubert 	  break;
15475796c8dcSSimon Schubert 
1548*ef5ccd6cSJohn Marino 	case R_386_SIZE32:
1549*ef5ccd6cSJohn Marino 	  size_reloc = TRUE;
1550*ef5ccd6cSJohn Marino 	  goto do_size;
1551*ef5ccd6cSJohn Marino 
15525796c8dcSSimon Schubert 	case R_386_TLS_IE_32:
15535796c8dcSSimon Schubert 	case R_386_TLS_IE:
15545796c8dcSSimon Schubert 	case R_386_TLS_GOTIE:
15555796c8dcSSimon Schubert 	  if (!info->executable)
15565796c8dcSSimon Schubert 	    info->flags |= DF_STATIC_TLS;
15575796c8dcSSimon Schubert 	  /* Fall through */
15585796c8dcSSimon Schubert 
15595796c8dcSSimon Schubert 	case R_386_GOT32:
15605796c8dcSSimon Schubert 	case R_386_TLS_GD:
15615796c8dcSSimon Schubert 	case R_386_TLS_GOTDESC:
15625796c8dcSSimon Schubert 	case R_386_TLS_DESC_CALL:
15635796c8dcSSimon Schubert 	  /* This symbol requires a global offset table entry.  */
15645796c8dcSSimon Schubert 	  {
15655796c8dcSSimon Schubert 	    int tls_type, old_tls_type;
15665796c8dcSSimon Schubert 
15675796c8dcSSimon Schubert 	    switch (r_type)
15685796c8dcSSimon Schubert 	      {
15695796c8dcSSimon Schubert 	      default:
15705796c8dcSSimon Schubert 	      case R_386_GOT32: tls_type = GOT_NORMAL; break;
15715796c8dcSSimon Schubert 	      case R_386_TLS_GD: tls_type = GOT_TLS_GD; break;
15725796c8dcSSimon Schubert 	      case R_386_TLS_GOTDESC:
15735796c8dcSSimon Schubert 	      case R_386_TLS_DESC_CALL:
15745796c8dcSSimon Schubert 		tls_type = GOT_TLS_GDESC; break;
15755796c8dcSSimon Schubert 	      case R_386_TLS_IE_32:
15765796c8dcSSimon Schubert 		if (ELF32_R_TYPE (rel->r_info) == r_type)
15775796c8dcSSimon Schubert 		  tls_type = GOT_TLS_IE_NEG;
15785796c8dcSSimon Schubert 		else
15795796c8dcSSimon Schubert 		  /* If this is a GD->IE transition, we may use either of
15805796c8dcSSimon Schubert 		     R_386_TLS_TPOFF and R_386_TLS_TPOFF32.  */
15815796c8dcSSimon Schubert 		  tls_type = GOT_TLS_IE;
15825796c8dcSSimon Schubert 		break;
15835796c8dcSSimon Schubert 	      case R_386_TLS_IE:
15845796c8dcSSimon Schubert 	      case R_386_TLS_GOTIE:
15855796c8dcSSimon Schubert 		tls_type = GOT_TLS_IE_POS; break;
15865796c8dcSSimon Schubert 	      }
15875796c8dcSSimon Schubert 
15885796c8dcSSimon Schubert 	    if (h != NULL)
15895796c8dcSSimon Schubert 	      {
15905796c8dcSSimon Schubert 		h->got.refcount += 1;
15915796c8dcSSimon Schubert 		old_tls_type = elf_i386_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;
16115796c8dcSSimon Schubert 		    elf_i386_local_tlsdesc_gotent (abfd)
16125796c8dcSSimon Schubert 		      = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
16135796c8dcSSimon Schubert 		    elf_i386_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 = elf_i386_local_got_tls_type (abfd) [r_symndx];
16185796c8dcSSimon Schubert 	      }
16195796c8dcSSimon Schubert 
16205796c8dcSSimon Schubert 	    if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_IE))
16215796c8dcSSimon Schubert 	      tls_type |= old_tls_type;
16225796c8dcSSimon Schubert 	    /* If a TLS symbol is accessed using IE at least once,
16235796c8dcSSimon Schubert 	       there is no point to use dynamic model for it.  */
16245796c8dcSSimon Schubert 	    else if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
16255796c8dcSSimon Schubert 		     && (! GOT_TLS_GD_ANY_P (old_tls_type)
16265796c8dcSSimon Schubert 			 || (tls_type & GOT_TLS_IE) == 0))
16275796c8dcSSimon Schubert 	      {
16285796c8dcSSimon Schubert 		if ((old_tls_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (tls_type))
16295796c8dcSSimon Schubert 		  tls_type = old_tls_type;
16305796c8dcSSimon Schubert 		else if (GOT_TLS_GD_ANY_P (old_tls_type)
16315796c8dcSSimon Schubert 			 && GOT_TLS_GD_ANY_P (tls_type))
16325796c8dcSSimon Schubert 		  tls_type |= old_tls_type;
16335796c8dcSSimon Schubert 		else
16345796c8dcSSimon Schubert 		  {
16355796c8dcSSimon Schubert 		    if (h)
16365796c8dcSSimon Schubert 		      name = h->root.root.string;
16375796c8dcSSimon Schubert 		    else
16385796c8dcSSimon Schubert 		      name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
16395796c8dcSSimon Schubert 					     NULL);
16405796c8dcSSimon Schubert 		    (*_bfd_error_handler)
16415796c8dcSSimon Schubert 		      (_("%B: `%s' accessed both as normal and "
16425796c8dcSSimon Schubert 			 "thread local symbol"),
16435796c8dcSSimon Schubert 		       abfd, name);
1644*ef5ccd6cSJohn Marino 		    bfd_set_error (bfd_error_bad_value);
16455796c8dcSSimon Schubert 		    return FALSE;
16465796c8dcSSimon Schubert 		  }
16475796c8dcSSimon Schubert 	      }
16485796c8dcSSimon Schubert 
16495796c8dcSSimon Schubert 	    if (old_tls_type != tls_type)
16505796c8dcSSimon Schubert 	      {
16515796c8dcSSimon Schubert 		if (h != NULL)
16525796c8dcSSimon Schubert 		  elf_i386_hash_entry (h)->tls_type = tls_type;
16535796c8dcSSimon Schubert 		else
16545796c8dcSSimon Schubert 		  elf_i386_local_got_tls_type (abfd) [r_symndx] = tls_type;
16555796c8dcSSimon Schubert 	      }
16565796c8dcSSimon Schubert 	  }
16575796c8dcSSimon Schubert 	  /* Fall through */
16585796c8dcSSimon Schubert 
16595796c8dcSSimon Schubert 	case R_386_GOTOFF:
16605796c8dcSSimon Schubert 	case R_386_GOTPC:
16615796c8dcSSimon Schubert 	create_got:
16625796c8dcSSimon Schubert 	  if (htab->elf.sgot == NULL)
16635796c8dcSSimon Schubert 	    {
16645796c8dcSSimon Schubert 	      if (htab->elf.dynobj == NULL)
16655796c8dcSSimon Schubert 		htab->elf.dynobj = abfd;
16665796c8dcSSimon Schubert 	      if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
16675796c8dcSSimon Schubert 		return FALSE;
16685796c8dcSSimon Schubert 	    }
16695796c8dcSSimon Schubert 	  if (r_type != R_386_TLS_IE)
16705796c8dcSSimon Schubert 	    break;
16715796c8dcSSimon Schubert 	  /* Fall through */
16725796c8dcSSimon Schubert 
16735796c8dcSSimon Schubert 	case R_386_TLS_LE_32:
16745796c8dcSSimon Schubert 	case R_386_TLS_LE:
16755796c8dcSSimon Schubert 	  if (info->executable)
16765796c8dcSSimon Schubert 	    break;
16775796c8dcSSimon Schubert 	  info->flags |= DF_STATIC_TLS;
16785796c8dcSSimon Schubert 	  /* Fall through */
16795796c8dcSSimon Schubert 
16805796c8dcSSimon Schubert 	case R_386_32:
16815796c8dcSSimon Schubert 	case R_386_PC32:
16825796c8dcSSimon Schubert 	  if (h != NULL && info->executable)
16835796c8dcSSimon Schubert 	    {
16845796c8dcSSimon Schubert 	      /* If this reloc is in a read-only section, we might
16855796c8dcSSimon Schubert 		 need a copy reloc.  We can't check reliably at this
16865796c8dcSSimon Schubert 		 stage whether the section is read-only, as input
16875796c8dcSSimon Schubert 		 sections have not yet been mapped to output sections.
16885796c8dcSSimon Schubert 		 Tentatively set the flag for now, and correct in
16895796c8dcSSimon Schubert 		 adjust_dynamic_symbol.  */
16905796c8dcSSimon Schubert 	      h->non_got_ref = 1;
16915796c8dcSSimon Schubert 
16925796c8dcSSimon Schubert 	      /* We may need a .plt entry if the function this reloc
16935796c8dcSSimon Schubert 		 refers to is in a shared lib.  */
16945796c8dcSSimon Schubert 	      h->plt.refcount += 1;
16955796c8dcSSimon Schubert 	      if (r_type != R_386_PC32)
16965796c8dcSSimon Schubert 		h->pointer_equality_needed = 1;
16975796c8dcSSimon Schubert 	    }
16985796c8dcSSimon Schubert 
1699*ef5ccd6cSJohn Marino 	  size_reloc = FALSE;
1700*ef5ccd6cSJohn Marino do_size:
17015796c8dcSSimon Schubert 	  /* If we are creating a shared library, and this is a reloc
17025796c8dcSSimon Schubert 	     against a global symbol, or a non PC relative reloc
17035796c8dcSSimon Schubert 	     against a local symbol, then we need to copy the reloc
17045796c8dcSSimon Schubert 	     into the shared library.  However, if we are linking with
17055796c8dcSSimon Schubert 	     -Bsymbolic, we do not need to copy a reloc against a
17065796c8dcSSimon Schubert 	     global symbol which is defined in an object we are
17075796c8dcSSimon Schubert 	     including in the link (i.e., DEF_REGULAR is set).  At
17085796c8dcSSimon Schubert 	     this point we have not seen all the input files, so it is
17095796c8dcSSimon Schubert 	     possible that DEF_REGULAR is not set now but will be set
17105796c8dcSSimon Schubert 	     later (it is never cleared).  In case of a weak definition,
17115796c8dcSSimon Schubert 	     DEF_REGULAR may be cleared later by a strong definition in
17125796c8dcSSimon Schubert 	     a shared library.  We account for that possibility below by
17135796c8dcSSimon Schubert 	     storing information in the relocs_copied field of the hash
17145796c8dcSSimon Schubert 	     table entry.  A similar situation occurs when creating
17155796c8dcSSimon Schubert 	     shared libraries and symbol visibility changes render the
17165796c8dcSSimon Schubert 	     symbol local.
17175796c8dcSSimon Schubert 
17185796c8dcSSimon Schubert 	     If on the other hand, we are creating an executable, we
17195796c8dcSSimon Schubert 	     may need to keep relocations for symbols satisfied by a
17205796c8dcSSimon Schubert 	     dynamic library if we manage to avoid copy relocs for the
17215796c8dcSSimon Schubert 	     symbol.  */
17225796c8dcSSimon Schubert 	  if ((info->shared
17235796c8dcSSimon Schubert 	       && (sec->flags & SEC_ALLOC) != 0
17245796c8dcSSimon Schubert 	       && (r_type != R_386_PC32
17255796c8dcSSimon Schubert 		   || (h != NULL
17265796c8dcSSimon Schubert 		       && (! SYMBOLIC_BIND (info, h)
17275796c8dcSSimon Schubert 			   || h->root.type == bfd_link_hash_defweak
17285796c8dcSSimon Schubert 			   || !h->def_regular))))
17295796c8dcSSimon Schubert 	      || (ELIMINATE_COPY_RELOCS
17305796c8dcSSimon Schubert 		  && !info->shared
17315796c8dcSSimon Schubert 		  && (sec->flags & SEC_ALLOC) != 0
17325796c8dcSSimon Schubert 		  && h != NULL
17335796c8dcSSimon Schubert 		  && (h->root.type == bfd_link_hash_defweak
17345796c8dcSSimon Schubert 		      || !h->def_regular)))
17355796c8dcSSimon Schubert 	    {
17365796c8dcSSimon Schubert 	      struct elf_dyn_relocs *p;
17375796c8dcSSimon Schubert 	      struct elf_dyn_relocs **head;
17385796c8dcSSimon Schubert 
17395796c8dcSSimon Schubert 	      /* We must copy these reloc types into the output file.
17405796c8dcSSimon Schubert 		 Create a reloc section in dynobj and make room for
17415796c8dcSSimon Schubert 		 this reloc.  */
17425796c8dcSSimon Schubert 	      if (sreloc == NULL)
17435796c8dcSSimon Schubert 		{
17445796c8dcSSimon Schubert 		  if (htab->elf.dynobj == NULL)
17455796c8dcSSimon Schubert 		    htab->elf.dynobj = abfd;
17465796c8dcSSimon Schubert 
17475796c8dcSSimon Schubert 		  sreloc = _bfd_elf_make_dynamic_reloc_section
17485796c8dcSSimon Schubert 		    (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ FALSE);
17495796c8dcSSimon Schubert 
17505796c8dcSSimon Schubert 		  if (sreloc == NULL)
17515796c8dcSSimon Schubert 		    return FALSE;
17525796c8dcSSimon Schubert 		}
17535796c8dcSSimon Schubert 
17545796c8dcSSimon Schubert 	      /* If this is a global symbol, we count the number of
17555796c8dcSSimon Schubert 		 relocations we need for this symbol.  */
17565796c8dcSSimon Schubert 	      if (h != NULL)
17575796c8dcSSimon Schubert 		{
17585796c8dcSSimon Schubert 		  head = &((struct elf_i386_link_hash_entry *) h)->dyn_relocs;
17595796c8dcSSimon Schubert 		}
17605796c8dcSSimon Schubert 	      else
17615796c8dcSSimon Schubert 		{
17625796c8dcSSimon Schubert 		  /* Track dynamic relocs needed for local syms too.
17635796c8dcSSimon Schubert 		     We really need local syms available to do this
17645796c8dcSSimon Schubert 		     easily.  Oh well.  */
17655796c8dcSSimon Schubert 		  void **vpp;
17665796c8dcSSimon Schubert 		  asection *s;
17675796c8dcSSimon Schubert 
17685796c8dcSSimon Schubert 		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
17695796c8dcSSimon Schubert 						abfd, r_symndx);
17705796c8dcSSimon Schubert 		  if (isym == NULL)
17715796c8dcSSimon Schubert 		    return FALSE;
17725796c8dcSSimon Schubert 
17735796c8dcSSimon Schubert 		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
17745796c8dcSSimon Schubert 		  if (s == NULL)
17755796c8dcSSimon Schubert 		    s = sec;
17765796c8dcSSimon Schubert 
17775796c8dcSSimon Schubert 		  vpp = &elf_section_data (s)->local_dynrel;
17785796c8dcSSimon Schubert 		  head = (struct elf_dyn_relocs **)vpp;
17795796c8dcSSimon Schubert 		}
17805796c8dcSSimon Schubert 
17815796c8dcSSimon Schubert 	      p = *head;
17825796c8dcSSimon Schubert 	      if (p == NULL || p->sec != sec)
17835796c8dcSSimon Schubert 		{
17845796c8dcSSimon Schubert 		  bfd_size_type amt = sizeof *p;
17855796c8dcSSimon Schubert 		  p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj,
17865796c8dcSSimon Schubert                                                            amt);
17875796c8dcSSimon Schubert 		  if (p == NULL)
17885796c8dcSSimon Schubert 		    return FALSE;
17895796c8dcSSimon Schubert 		  p->next = *head;
17905796c8dcSSimon Schubert 		  *head = p;
17915796c8dcSSimon Schubert 		  p->sec = sec;
17925796c8dcSSimon Schubert 		  p->count = 0;
17935796c8dcSSimon Schubert 		  p->pc_count = 0;
17945796c8dcSSimon Schubert 		}
17955796c8dcSSimon Schubert 
17965796c8dcSSimon Schubert 	      p->count += 1;
1797*ef5ccd6cSJohn Marino 	      /* Count size relocation as PC-relative relocation.  */
1798*ef5ccd6cSJohn Marino 	      if (r_type == R_386_PC32 || size_reloc)
17995796c8dcSSimon Schubert 		p->pc_count += 1;
18005796c8dcSSimon Schubert 	    }
18015796c8dcSSimon Schubert 	  break;
18025796c8dcSSimon Schubert 
18035796c8dcSSimon Schubert 	  /* This relocation describes the C++ object vtable hierarchy.
18045796c8dcSSimon Schubert 	     Reconstruct it for later use during GC.  */
18055796c8dcSSimon Schubert 	case R_386_GNU_VTINHERIT:
18065796c8dcSSimon Schubert 	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
18075796c8dcSSimon Schubert 	    return FALSE;
18085796c8dcSSimon Schubert 	  break;
18095796c8dcSSimon Schubert 
18105796c8dcSSimon Schubert 	  /* This relocation describes which C++ vtable entries are actually
18115796c8dcSSimon Schubert 	     used.  Record for later use during GC.  */
18125796c8dcSSimon Schubert 	case R_386_GNU_VTENTRY:
18135796c8dcSSimon Schubert 	  BFD_ASSERT (h != NULL);
18145796c8dcSSimon Schubert 	  if (h != NULL
18155796c8dcSSimon Schubert 	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
18165796c8dcSSimon Schubert 	    return FALSE;
18175796c8dcSSimon Schubert 	  break;
18185796c8dcSSimon Schubert 
18195796c8dcSSimon Schubert 	default:
18205796c8dcSSimon Schubert 	  break;
18215796c8dcSSimon Schubert 	}
18225796c8dcSSimon Schubert     }
18235796c8dcSSimon Schubert 
18245796c8dcSSimon Schubert   return TRUE;
18255796c8dcSSimon Schubert }
18265796c8dcSSimon Schubert 
18275796c8dcSSimon Schubert /* Return the section that should be marked against GC for a given
18285796c8dcSSimon Schubert    relocation.  */
18295796c8dcSSimon Schubert 
18305796c8dcSSimon Schubert static asection *
elf_i386_gc_mark_hook(asection * sec,struct bfd_link_info * info,Elf_Internal_Rela * rel,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)18315796c8dcSSimon Schubert elf_i386_gc_mark_hook (asection *sec,
18325796c8dcSSimon Schubert 		       struct bfd_link_info *info,
18335796c8dcSSimon Schubert 		       Elf_Internal_Rela *rel,
18345796c8dcSSimon Schubert 		       struct elf_link_hash_entry *h,
18355796c8dcSSimon Schubert 		       Elf_Internal_Sym *sym)
18365796c8dcSSimon Schubert {
18375796c8dcSSimon Schubert   if (h != NULL)
18385796c8dcSSimon Schubert     switch (ELF32_R_TYPE (rel->r_info))
18395796c8dcSSimon Schubert       {
18405796c8dcSSimon Schubert       case R_386_GNU_VTINHERIT:
18415796c8dcSSimon Schubert       case R_386_GNU_VTENTRY:
18425796c8dcSSimon Schubert 	return NULL;
18435796c8dcSSimon Schubert       }
18445796c8dcSSimon Schubert 
18455796c8dcSSimon Schubert   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
18465796c8dcSSimon Schubert }
18475796c8dcSSimon Schubert 
18485796c8dcSSimon Schubert /* Update the got entry reference counts for the section being removed.  */
18495796c8dcSSimon Schubert 
18505796c8dcSSimon Schubert static bfd_boolean
elf_i386_gc_sweep_hook(bfd * abfd,struct bfd_link_info * info,asection * sec,const Elf_Internal_Rela * relocs)18515796c8dcSSimon Schubert elf_i386_gc_sweep_hook (bfd *abfd,
18525796c8dcSSimon Schubert 			struct bfd_link_info *info,
18535796c8dcSSimon Schubert 			asection *sec,
18545796c8dcSSimon Schubert 			const Elf_Internal_Rela *relocs)
18555796c8dcSSimon Schubert {
1856cf7f2e2dSJohn Marino   struct elf_i386_link_hash_table *htab;
18575796c8dcSSimon Schubert   Elf_Internal_Shdr *symtab_hdr;
18585796c8dcSSimon Schubert   struct elf_link_hash_entry **sym_hashes;
18595796c8dcSSimon Schubert   bfd_signed_vma *local_got_refcounts;
18605796c8dcSSimon Schubert   const Elf_Internal_Rela *rel, *relend;
18615796c8dcSSimon Schubert 
18625796c8dcSSimon Schubert   if (info->relocatable)
18635796c8dcSSimon Schubert     return TRUE;
18645796c8dcSSimon Schubert 
1865cf7f2e2dSJohn Marino   htab = elf_i386_hash_table (info);
1866cf7f2e2dSJohn Marino   if (htab == NULL)
1867cf7f2e2dSJohn Marino     return FALSE;
1868cf7f2e2dSJohn Marino 
18695796c8dcSSimon Schubert   elf_section_data (sec)->local_dynrel = NULL;
18705796c8dcSSimon Schubert 
18715796c8dcSSimon Schubert   symtab_hdr = &elf_symtab_hdr (abfd);
18725796c8dcSSimon Schubert   sym_hashes = elf_sym_hashes (abfd);
18735796c8dcSSimon Schubert   local_got_refcounts = elf_local_got_refcounts (abfd);
18745796c8dcSSimon Schubert 
18755796c8dcSSimon Schubert   relend = relocs + sec->reloc_count;
18765796c8dcSSimon Schubert   for (rel = relocs; rel < relend; rel++)
18775796c8dcSSimon Schubert     {
18785796c8dcSSimon Schubert       unsigned long r_symndx;
18795796c8dcSSimon Schubert       unsigned int r_type;
18805796c8dcSSimon Schubert       struct elf_link_hash_entry *h = NULL;
18815796c8dcSSimon Schubert 
18825796c8dcSSimon Schubert       r_symndx = ELF32_R_SYM (rel->r_info);
18835796c8dcSSimon Schubert       if (r_symndx >= symtab_hdr->sh_info)
18845796c8dcSSimon Schubert 	{
18855796c8dcSSimon Schubert 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
18865796c8dcSSimon Schubert 	  while (h->root.type == bfd_link_hash_indirect
18875796c8dcSSimon Schubert 		 || h->root.type == bfd_link_hash_warning)
18885796c8dcSSimon Schubert 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1889c50c785cSJohn Marino 	}
1890c50c785cSJohn Marino       else
1891c50c785cSJohn Marino 	{
1892c50c785cSJohn Marino 	  /* A local symbol.  */
1893c50c785cSJohn Marino 	  Elf_Internal_Sym *isym;
18945796c8dcSSimon Schubert 
1895c50c785cSJohn Marino 	  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1896c50c785cSJohn Marino 					abfd, r_symndx);
1897c50c785cSJohn Marino 
1898c50c785cSJohn Marino 	  /* Check relocation against local STT_GNU_IFUNC symbol.  */
1899c50c785cSJohn Marino 	  if (isym != NULL
1900c50c785cSJohn Marino 	      && ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
1901c50c785cSJohn Marino 	    {
1902c50c785cSJohn Marino 	      h = elf_i386_get_local_sym_hash (htab, abfd, rel, FALSE);
1903c50c785cSJohn Marino 	      if (h == NULL)
1904c50c785cSJohn Marino 		abort ();
1905c50c785cSJohn Marino 	    }
1906c50c785cSJohn Marino 	}
1907c50c785cSJohn Marino 
1908c50c785cSJohn Marino       if (h)
1909c50c785cSJohn Marino 	{
1910c50c785cSJohn Marino 	  struct elf_i386_link_hash_entry *eh;
1911c50c785cSJohn Marino 	  struct elf_dyn_relocs **pp;
1912c50c785cSJohn Marino 	  struct elf_dyn_relocs *p;
1913c50c785cSJohn Marino 
1914c50c785cSJohn Marino 	  eh = (struct elf_i386_link_hash_entry *) h;
19155796c8dcSSimon Schubert 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
19165796c8dcSSimon Schubert 	    if (p->sec == sec)
19175796c8dcSSimon Schubert 	      {
19185796c8dcSSimon Schubert 		/* Everything must go for SEC.  */
19195796c8dcSSimon Schubert 		*pp = p->next;
19205796c8dcSSimon Schubert 		break;
19215796c8dcSSimon Schubert 	      }
19225796c8dcSSimon Schubert 	}
19235796c8dcSSimon Schubert 
19245796c8dcSSimon Schubert       r_type = ELF32_R_TYPE (rel->r_info);
19255796c8dcSSimon Schubert       if (! elf_i386_tls_transition (info, abfd, sec, NULL,
19265796c8dcSSimon Schubert 				     symtab_hdr, sym_hashes,
19275796c8dcSSimon Schubert 				     &r_type, GOT_UNKNOWN,
19285796c8dcSSimon Schubert 				     rel, relend, h, r_symndx))
19295796c8dcSSimon Schubert 	return FALSE;
19305796c8dcSSimon Schubert 
19315796c8dcSSimon Schubert       switch (r_type)
19325796c8dcSSimon Schubert 	{
19335796c8dcSSimon Schubert 	case R_386_TLS_LDM:
1934cf7f2e2dSJohn Marino 	  if (htab->tls_ldm_got.refcount > 0)
1935cf7f2e2dSJohn Marino 	    htab->tls_ldm_got.refcount -= 1;
19365796c8dcSSimon Schubert 	  break;
19375796c8dcSSimon Schubert 
19385796c8dcSSimon Schubert 	case R_386_TLS_GD:
19395796c8dcSSimon Schubert 	case R_386_TLS_GOTDESC:
19405796c8dcSSimon Schubert 	case R_386_TLS_DESC_CALL:
19415796c8dcSSimon Schubert 	case R_386_TLS_IE_32:
19425796c8dcSSimon Schubert 	case R_386_TLS_IE:
19435796c8dcSSimon Schubert 	case R_386_TLS_GOTIE:
19445796c8dcSSimon Schubert 	case R_386_GOT32:
19455796c8dcSSimon Schubert 	  if (h != NULL)
19465796c8dcSSimon Schubert 	    {
19475796c8dcSSimon Schubert 	      if (h->got.refcount > 0)
19485796c8dcSSimon Schubert 		h->got.refcount -= 1;
1949c50c785cSJohn Marino 	      if (h->type == STT_GNU_IFUNC)
1950c50c785cSJohn Marino 		{
1951c50c785cSJohn Marino 		  if (h->plt.refcount > 0)
1952c50c785cSJohn Marino 		    h->plt.refcount -= 1;
1953c50c785cSJohn Marino 		}
19545796c8dcSSimon Schubert 	    }
19555796c8dcSSimon Schubert 	  else if (local_got_refcounts != NULL)
19565796c8dcSSimon Schubert 	    {
19575796c8dcSSimon Schubert 	      if (local_got_refcounts[r_symndx] > 0)
19585796c8dcSSimon Schubert 		local_got_refcounts[r_symndx] -= 1;
19595796c8dcSSimon Schubert 	    }
19605796c8dcSSimon Schubert 	  break;
19615796c8dcSSimon Schubert 
19625796c8dcSSimon Schubert 	case R_386_32:
19635796c8dcSSimon Schubert 	case R_386_PC32:
1964*ef5ccd6cSJohn Marino 	case R_386_SIZE32:
1965c50c785cSJohn Marino 	  if (info->shared
1966c50c785cSJohn Marino 	      && (h == NULL || h->type != STT_GNU_IFUNC))
19675796c8dcSSimon Schubert 	    break;
19685796c8dcSSimon Schubert 	  /* Fall through */
19695796c8dcSSimon Schubert 
19705796c8dcSSimon Schubert 	case R_386_PLT32:
19715796c8dcSSimon Schubert 	  if (h != NULL)
19725796c8dcSSimon Schubert 	    {
19735796c8dcSSimon Schubert 	      if (h->plt.refcount > 0)
19745796c8dcSSimon Schubert 		h->plt.refcount -= 1;
19755796c8dcSSimon Schubert 	    }
19765796c8dcSSimon Schubert 	  break;
19775796c8dcSSimon Schubert 
1978c50c785cSJohn Marino 	case R_386_GOTOFF:
1979c50c785cSJohn Marino 	  if (h != NULL && h->type == STT_GNU_IFUNC)
1980c50c785cSJohn Marino 	    {
1981c50c785cSJohn Marino 	      if (h->got.refcount > 0)
1982c50c785cSJohn Marino 		h->got.refcount -= 1;
1983c50c785cSJohn Marino 	      if (h->plt.refcount > 0)
1984c50c785cSJohn Marino 		h->plt.refcount -= 1;
1985c50c785cSJohn Marino 	    }
1986c50c785cSJohn Marino 	  break;
1987c50c785cSJohn Marino 
19885796c8dcSSimon Schubert 	default:
19895796c8dcSSimon Schubert 	  break;
19905796c8dcSSimon Schubert 	}
19915796c8dcSSimon Schubert     }
19925796c8dcSSimon Schubert 
19935796c8dcSSimon Schubert   return TRUE;
19945796c8dcSSimon Schubert }
19955796c8dcSSimon Schubert 
19965796c8dcSSimon Schubert /* Adjust a symbol defined by a dynamic object and referenced by a
19975796c8dcSSimon Schubert    regular object.  The current definition is in some section of the
19985796c8dcSSimon Schubert    dynamic object, but we're not including those sections.  We have to
19995796c8dcSSimon Schubert    change the definition to something the rest of the link can
20005796c8dcSSimon Schubert    understand.  */
20015796c8dcSSimon Schubert 
20025796c8dcSSimon Schubert static bfd_boolean
elf_i386_adjust_dynamic_symbol(struct bfd_link_info * info,struct elf_link_hash_entry * h)20035796c8dcSSimon Schubert elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
20045796c8dcSSimon Schubert 				struct elf_link_hash_entry *h)
20055796c8dcSSimon Schubert {
20065796c8dcSSimon Schubert   struct elf_i386_link_hash_table *htab;
20075796c8dcSSimon Schubert   asection *s;
2008*ef5ccd6cSJohn Marino   struct elf_i386_link_hash_entry *eh;
2009*ef5ccd6cSJohn Marino   struct elf_dyn_relocs *p;
20105796c8dcSSimon Schubert 
20115796c8dcSSimon Schubert   /* STT_GNU_IFUNC symbol must go through PLT. */
20125796c8dcSSimon Schubert   if (h->type == STT_GNU_IFUNC)
20135796c8dcSSimon Schubert     {
2014*ef5ccd6cSJohn Marino       /* All local STT_GNU_IFUNC references must be treate as local
2015*ef5ccd6cSJohn Marino 	 calls via local PLT.  */
2016*ef5ccd6cSJohn Marino       if (h->ref_regular
2017*ef5ccd6cSJohn Marino 	  && SYMBOL_CALLS_LOCAL (info, h))
2018*ef5ccd6cSJohn Marino 	{
2019*ef5ccd6cSJohn Marino 	  bfd_size_type pc_count = 0, count = 0;
2020*ef5ccd6cSJohn Marino 	  struct elf_dyn_relocs **pp;
2021*ef5ccd6cSJohn Marino 
2022*ef5ccd6cSJohn Marino 	  eh = (struct elf_i386_link_hash_entry *) h;
2023*ef5ccd6cSJohn Marino 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
2024*ef5ccd6cSJohn Marino 	    {
2025*ef5ccd6cSJohn Marino 	      pc_count += p->pc_count;
2026*ef5ccd6cSJohn Marino 	      p->count -= p->pc_count;
2027*ef5ccd6cSJohn Marino 	      p->pc_count = 0;
2028*ef5ccd6cSJohn Marino 	      count += p->count;
2029*ef5ccd6cSJohn Marino 	      if (p->count == 0)
2030*ef5ccd6cSJohn Marino 		*pp = p->next;
2031*ef5ccd6cSJohn Marino 	      else
2032*ef5ccd6cSJohn Marino 		pp = &p->next;
2033*ef5ccd6cSJohn Marino 	    }
2034*ef5ccd6cSJohn Marino 
2035*ef5ccd6cSJohn Marino 	  if (pc_count || count)
2036*ef5ccd6cSJohn Marino 	    {
2037*ef5ccd6cSJohn Marino 	      h->needs_plt = 1;
2038*ef5ccd6cSJohn Marino 	      h->non_got_ref = 1;
2039*ef5ccd6cSJohn Marino 	      if (h->plt.refcount <= 0)
2040*ef5ccd6cSJohn Marino 		h->plt.refcount = 1;
2041*ef5ccd6cSJohn Marino 	      else
2042*ef5ccd6cSJohn Marino 		h->plt.refcount += 1;
2043*ef5ccd6cSJohn Marino 	    }
2044*ef5ccd6cSJohn Marino 	}
2045*ef5ccd6cSJohn Marino 
20465796c8dcSSimon Schubert       if (h->plt.refcount <= 0)
20475796c8dcSSimon Schubert 	{
20485796c8dcSSimon Schubert 	  h->plt.offset = (bfd_vma) -1;
20495796c8dcSSimon Schubert 	  h->needs_plt = 0;
20505796c8dcSSimon Schubert 	}
20515796c8dcSSimon Schubert       return TRUE;
20525796c8dcSSimon Schubert     }
20535796c8dcSSimon Schubert 
20545796c8dcSSimon Schubert   /* If this is a function, put it in the procedure linkage table.  We
20555796c8dcSSimon Schubert      will fill in the contents of the procedure linkage table later,
20565796c8dcSSimon Schubert      when we know the address of the .got section.  */
20575796c8dcSSimon Schubert   if (h->type == STT_FUNC
20585796c8dcSSimon Schubert       || h->needs_plt)
20595796c8dcSSimon Schubert     {
20605796c8dcSSimon Schubert       if (h->plt.refcount <= 0
20615796c8dcSSimon Schubert 	  || SYMBOL_CALLS_LOCAL (info, h)
20625796c8dcSSimon Schubert 	  || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
20635796c8dcSSimon Schubert 	      && h->root.type == bfd_link_hash_undefweak))
20645796c8dcSSimon Schubert 	{
20655796c8dcSSimon Schubert 	  /* This case can occur if we saw a PLT32 reloc in an input
20665796c8dcSSimon Schubert 	     file, but the symbol was never referred to by a dynamic
20675796c8dcSSimon Schubert 	     object, or if all references were garbage collected.  In
20685796c8dcSSimon Schubert 	     such a case, we don't actually need to build a procedure
20695796c8dcSSimon Schubert 	     linkage table, and we can just do a PC32 reloc instead.  */
20705796c8dcSSimon Schubert 	  h->plt.offset = (bfd_vma) -1;
20715796c8dcSSimon Schubert 	  h->needs_plt = 0;
20725796c8dcSSimon Schubert 	}
20735796c8dcSSimon Schubert 
20745796c8dcSSimon Schubert       return TRUE;
20755796c8dcSSimon Schubert     }
20765796c8dcSSimon Schubert   else
20775796c8dcSSimon Schubert     /* It's possible that we incorrectly decided a .plt reloc was
20785796c8dcSSimon Schubert        needed for an R_386_PC32 reloc to a non-function sym in
20795796c8dcSSimon Schubert        check_relocs.  We can't decide accurately between function and
20805796c8dcSSimon Schubert        non-function syms in check-relocs;  Objects loaded later in
20815796c8dcSSimon Schubert        the link may change h->type.  So fix it now.  */
20825796c8dcSSimon Schubert     h->plt.offset = (bfd_vma) -1;
20835796c8dcSSimon Schubert 
20845796c8dcSSimon Schubert   /* If this is a weak symbol, and there is a real definition, the
20855796c8dcSSimon Schubert      processor independent code will have arranged for us to see the
20865796c8dcSSimon Schubert      real definition first, and we can just use the same value.  */
20875796c8dcSSimon Schubert   if (h->u.weakdef != NULL)
20885796c8dcSSimon Schubert     {
20895796c8dcSSimon Schubert       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
20905796c8dcSSimon Schubert 		  || h->u.weakdef->root.type == bfd_link_hash_defweak);
20915796c8dcSSimon Schubert       h->root.u.def.section = h->u.weakdef->root.u.def.section;
20925796c8dcSSimon Schubert       h->root.u.def.value = h->u.weakdef->root.u.def.value;
20935796c8dcSSimon Schubert       if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
20945796c8dcSSimon Schubert 	h->non_got_ref = h->u.weakdef->non_got_ref;
20955796c8dcSSimon Schubert       return TRUE;
20965796c8dcSSimon Schubert     }
20975796c8dcSSimon Schubert 
20985796c8dcSSimon Schubert   /* This is a reference to a symbol defined by a dynamic object which
20995796c8dcSSimon Schubert      is not a function.  */
21005796c8dcSSimon Schubert 
21015796c8dcSSimon Schubert   /* If we are creating a shared library, we must presume that the
21025796c8dcSSimon Schubert      only references to the symbol are via the global offset table.
21035796c8dcSSimon Schubert      For such cases we need not do anything here; the relocations will
21045796c8dcSSimon Schubert      be handled correctly by relocate_section.  */
21055796c8dcSSimon Schubert   if (info->shared)
21065796c8dcSSimon Schubert     return TRUE;
21075796c8dcSSimon Schubert 
21085796c8dcSSimon Schubert   /* If there are no references to this symbol that do not use the
21095796c8dcSSimon Schubert      GOT, we don't need to generate a copy reloc.  */
21105796c8dcSSimon Schubert   if (!h->non_got_ref)
21115796c8dcSSimon Schubert     return TRUE;
21125796c8dcSSimon Schubert 
21135796c8dcSSimon Schubert   /* If -z nocopyreloc was given, we won't generate them either.  */
21145796c8dcSSimon Schubert   if (info->nocopyreloc)
21155796c8dcSSimon Schubert     {
21165796c8dcSSimon Schubert       h->non_got_ref = 0;
21175796c8dcSSimon Schubert       return TRUE;
21185796c8dcSSimon Schubert     }
21195796c8dcSSimon Schubert 
21205796c8dcSSimon Schubert   htab = elf_i386_hash_table (info);
2121cf7f2e2dSJohn Marino   if (htab == NULL)
2122cf7f2e2dSJohn Marino     return FALSE;
21235796c8dcSSimon Schubert 
21245796c8dcSSimon Schubert   /* If there aren't any dynamic relocs in read-only sections, then
21255796c8dcSSimon Schubert      we can keep the dynamic relocs and avoid the copy reloc.  This
21265796c8dcSSimon Schubert      doesn't work on VxWorks, where we can not have dynamic relocations
21275796c8dcSSimon Schubert      (other than copy and jump slot relocations) in an executable.  */
2128a45ae5f8SJohn Marino   if (ELIMINATE_COPY_RELOCS
2129a45ae5f8SJohn Marino       && !get_elf_i386_backend_data (info->output_bfd)->is_vxworks)
21305796c8dcSSimon Schubert     {
21315796c8dcSSimon Schubert       eh = (struct elf_i386_link_hash_entry *) h;
21325796c8dcSSimon Schubert       for (p = eh->dyn_relocs; p != NULL; p = p->next)
21335796c8dcSSimon Schubert 	{
21345796c8dcSSimon Schubert 	  s = p->sec->output_section;
21355796c8dcSSimon Schubert 	  if (s != NULL && (s->flags & SEC_READONLY) != 0)
21365796c8dcSSimon Schubert 	    break;
21375796c8dcSSimon Schubert 	}
21385796c8dcSSimon Schubert 
21395796c8dcSSimon Schubert       if (p == NULL)
21405796c8dcSSimon Schubert 	{
21415796c8dcSSimon Schubert 	  h->non_got_ref = 0;
21425796c8dcSSimon Schubert 	  return TRUE;
21435796c8dcSSimon Schubert 	}
21445796c8dcSSimon Schubert     }
21455796c8dcSSimon Schubert 
21465796c8dcSSimon Schubert   /* We must allocate the symbol in our .dynbss section, which will
21475796c8dcSSimon Schubert      become part of the .bss section of the executable.  There will be
21485796c8dcSSimon Schubert      an entry for this symbol in the .dynsym section.  The dynamic
21495796c8dcSSimon Schubert      object will contain position independent code, so all references
21505796c8dcSSimon Schubert      from the dynamic object to this symbol will go through the global
21515796c8dcSSimon Schubert      offset table.  The dynamic linker will use the .dynsym entry to
21525796c8dcSSimon Schubert      determine the address it must put in the global offset table, so
21535796c8dcSSimon Schubert      both the dynamic object and the regular object will refer to the
21545796c8dcSSimon Schubert      same memory location for the variable.  */
21555796c8dcSSimon Schubert 
21565796c8dcSSimon Schubert   /* We must generate a R_386_COPY reloc to tell the dynamic linker to
21575796c8dcSSimon Schubert      copy the initial value out of the dynamic object and into the
21585796c8dcSSimon Schubert      runtime process image.  */
2159*ef5ccd6cSJohn Marino   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
21605796c8dcSSimon Schubert     {
21615796c8dcSSimon Schubert       htab->srelbss->size += sizeof (Elf32_External_Rel);
21625796c8dcSSimon Schubert       h->needs_copy = 1;
21635796c8dcSSimon Schubert     }
21645796c8dcSSimon Schubert 
21655796c8dcSSimon Schubert   s = htab->sdynbss;
21665796c8dcSSimon Schubert 
21675796c8dcSSimon Schubert   return _bfd_elf_adjust_dynamic_copy (h, s);
21685796c8dcSSimon Schubert }
21695796c8dcSSimon Schubert 
21705796c8dcSSimon Schubert /* Allocate space in .plt, .got and associated reloc sections for
21715796c8dcSSimon Schubert    dynamic relocs.  */
21725796c8dcSSimon Schubert 
21735796c8dcSSimon Schubert static bfd_boolean
elf_i386_allocate_dynrelocs(struct elf_link_hash_entry * h,void * inf)21745796c8dcSSimon Schubert elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
21755796c8dcSSimon Schubert {
21765796c8dcSSimon Schubert   struct bfd_link_info *info;
21775796c8dcSSimon Schubert   struct elf_i386_link_hash_table *htab;
21785796c8dcSSimon Schubert   struct elf_i386_link_hash_entry *eh;
21795796c8dcSSimon Schubert   struct elf_dyn_relocs *p;
2180a45ae5f8SJohn Marino   unsigned plt_entry_size;
21815796c8dcSSimon Schubert 
21825796c8dcSSimon Schubert   if (h->root.type == bfd_link_hash_indirect)
21835796c8dcSSimon Schubert     return TRUE;
21845796c8dcSSimon Schubert 
21855796c8dcSSimon Schubert   eh = (struct elf_i386_link_hash_entry *) h;
21865796c8dcSSimon Schubert 
21875796c8dcSSimon Schubert   info = (struct bfd_link_info *) inf;
21885796c8dcSSimon Schubert   htab = elf_i386_hash_table (info);
2189cf7f2e2dSJohn Marino   if (htab == NULL)
2190cf7f2e2dSJohn Marino     return FALSE;
21915796c8dcSSimon Schubert 
2192a45ae5f8SJohn Marino   plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
2193a45ae5f8SJohn Marino 
21945796c8dcSSimon Schubert   /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
21955796c8dcSSimon Schubert      here if it is defined and referenced in a non-shared object.  */
21965796c8dcSSimon Schubert   if (h->type == STT_GNU_IFUNC
21975796c8dcSSimon Schubert       && h->def_regular)
2198a45ae5f8SJohn Marino     return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs,
2199a45ae5f8SJohn Marino                                                plt_entry_size, 4);
22005796c8dcSSimon Schubert   else if (htab->elf.dynamic_sections_created
22015796c8dcSSimon Schubert 	   && h->plt.refcount > 0)
22025796c8dcSSimon Schubert     {
22035796c8dcSSimon Schubert       /* Make sure this symbol is output as a dynamic symbol.
22045796c8dcSSimon Schubert 	 Undefined weak syms won't yet be marked as dynamic.  */
22055796c8dcSSimon Schubert       if (h->dynindx == -1
22065796c8dcSSimon Schubert 	  && !h->forced_local)
22075796c8dcSSimon Schubert 	{
22085796c8dcSSimon Schubert 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
22095796c8dcSSimon Schubert 	    return FALSE;
22105796c8dcSSimon Schubert 	}
22115796c8dcSSimon Schubert 
22125796c8dcSSimon Schubert       if (info->shared
22135796c8dcSSimon Schubert 	  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
22145796c8dcSSimon Schubert 	{
22155796c8dcSSimon Schubert 	  asection *s = htab->elf.splt;
22165796c8dcSSimon Schubert 
22175796c8dcSSimon Schubert 	  /* If this is the first .plt entry, make room for the special
22185796c8dcSSimon Schubert 	     first entry.  */
22195796c8dcSSimon Schubert 	  if (s->size == 0)
2220a45ae5f8SJohn Marino 	    s->size += plt_entry_size;
22215796c8dcSSimon Schubert 
22225796c8dcSSimon Schubert 	  h->plt.offset = s->size;
22235796c8dcSSimon Schubert 
22245796c8dcSSimon Schubert 	  /* If this symbol is not defined in a regular file, and we are
22255796c8dcSSimon Schubert 	     not generating a shared library, then set the symbol to this
22265796c8dcSSimon Schubert 	     location in the .plt.  This is required to make function
22275796c8dcSSimon Schubert 	     pointers compare as equal between the normal executable and
22285796c8dcSSimon Schubert 	     the shared library.  */
22295796c8dcSSimon Schubert 	  if (! info->shared
22305796c8dcSSimon Schubert 	      && !h->def_regular)
22315796c8dcSSimon Schubert 	    {
22325796c8dcSSimon Schubert 	      h->root.u.def.section = s;
22335796c8dcSSimon Schubert 	      h->root.u.def.value = h->plt.offset;
22345796c8dcSSimon Schubert 	    }
22355796c8dcSSimon Schubert 
22365796c8dcSSimon Schubert 	  /* Make room for this entry.  */
2237a45ae5f8SJohn Marino 	  s->size += plt_entry_size;
22385796c8dcSSimon Schubert 
22395796c8dcSSimon Schubert 	  /* We also need to make an entry in the .got.plt section, which
22405796c8dcSSimon Schubert 	     will be placed in the .got section by the linker script.  */
22415796c8dcSSimon Schubert 	  htab->elf.sgotplt->size += 4;
22425796c8dcSSimon Schubert 
22435796c8dcSSimon Schubert 	  /* We also need to make an entry in the .rel.plt section.  */
22445796c8dcSSimon Schubert 	  htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
2245a45ae5f8SJohn Marino 	  htab->elf.srelplt->reloc_count++;
22465796c8dcSSimon Schubert 
2247a45ae5f8SJohn Marino 	  if (get_elf_i386_backend_data (info->output_bfd)->is_vxworks
2248a45ae5f8SJohn Marino               && !info->shared)
22495796c8dcSSimon Schubert 	    {
22505796c8dcSSimon Schubert 	      /* VxWorks has a second set of relocations for each PLT entry
22515796c8dcSSimon Schubert 		 in executables.  They go in a separate relocation section,
22525796c8dcSSimon Schubert 		 which is processed by the kernel loader.  */
22535796c8dcSSimon Schubert 
22545796c8dcSSimon Schubert 	      /* There are two relocations for the initial PLT entry: an
22555796c8dcSSimon Schubert 		 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 4 and an
22565796c8dcSSimon Schubert 		 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */
22575796c8dcSSimon Schubert 
2258a45ae5f8SJohn Marino 	      if (h->plt.offset == plt_entry_size)
22595796c8dcSSimon Schubert 		htab->srelplt2->size += (sizeof (Elf32_External_Rel) * 2);
22605796c8dcSSimon Schubert 
22615796c8dcSSimon Schubert 	      /* There are two extra relocations for each subsequent PLT entry:
22625796c8dcSSimon Schubert 		 an R_386_32 relocation for the GOT entry, and an R_386_32
22635796c8dcSSimon Schubert 		 relocation for the PLT entry.  */
22645796c8dcSSimon Schubert 
22655796c8dcSSimon Schubert 	      htab->srelplt2->size += (sizeof (Elf32_External_Rel) * 2);
22665796c8dcSSimon Schubert 	    }
22675796c8dcSSimon Schubert 	}
22685796c8dcSSimon Schubert       else
22695796c8dcSSimon Schubert 	{
22705796c8dcSSimon Schubert 	  h->plt.offset = (bfd_vma) -1;
22715796c8dcSSimon Schubert 	  h->needs_plt = 0;
22725796c8dcSSimon Schubert 	}
22735796c8dcSSimon Schubert     }
22745796c8dcSSimon Schubert   else
22755796c8dcSSimon Schubert     {
22765796c8dcSSimon Schubert       h->plt.offset = (bfd_vma) -1;
22775796c8dcSSimon Schubert       h->needs_plt = 0;
22785796c8dcSSimon Schubert     }
22795796c8dcSSimon Schubert 
22805796c8dcSSimon Schubert   eh->tlsdesc_got = (bfd_vma) -1;
22815796c8dcSSimon Schubert 
22825796c8dcSSimon Schubert   /* If R_386_TLS_{IE_32,IE,GOTIE} symbol is now local to the binary,
22835796c8dcSSimon Schubert      make it a R_386_TLS_LE_32 requiring no TLS entry.  */
22845796c8dcSSimon Schubert   if (h->got.refcount > 0
22855796c8dcSSimon Schubert       && info->executable
22865796c8dcSSimon Schubert       && h->dynindx == -1
22875796c8dcSSimon Schubert       && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE))
22885796c8dcSSimon Schubert     h->got.offset = (bfd_vma) -1;
22895796c8dcSSimon Schubert   else if (h->got.refcount > 0)
22905796c8dcSSimon Schubert     {
22915796c8dcSSimon Schubert       asection *s;
22925796c8dcSSimon Schubert       bfd_boolean dyn;
22935796c8dcSSimon Schubert       int tls_type = elf_i386_hash_entry(h)->tls_type;
22945796c8dcSSimon Schubert 
22955796c8dcSSimon Schubert       /* Make sure this symbol is output as a dynamic symbol.
22965796c8dcSSimon Schubert 	 Undefined weak syms won't yet be marked as dynamic.  */
22975796c8dcSSimon Schubert       if (h->dynindx == -1
22985796c8dcSSimon Schubert 	  && !h->forced_local)
22995796c8dcSSimon Schubert 	{
23005796c8dcSSimon Schubert 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
23015796c8dcSSimon Schubert 	    return FALSE;
23025796c8dcSSimon Schubert 	}
23035796c8dcSSimon Schubert 
23045796c8dcSSimon Schubert       s = htab->elf.sgot;
23055796c8dcSSimon Schubert       if (GOT_TLS_GDESC_P (tls_type))
23065796c8dcSSimon Schubert 	{
23075796c8dcSSimon Schubert 	  eh->tlsdesc_got = htab->elf.sgotplt->size
23085796c8dcSSimon Schubert 	    - elf_i386_compute_jump_table_size (htab);
23095796c8dcSSimon Schubert 	  htab->elf.sgotplt->size += 8;
23105796c8dcSSimon Schubert 	  h->got.offset = (bfd_vma) -2;
23115796c8dcSSimon Schubert 	}
23125796c8dcSSimon Schubert       if (! GOT_TLS_GDESC_P (tls_type)
23135796c8dcSSimon Schubert 	  || GOT_TLS_GD_P (tls_type))
23145796c8dcSSimon Schubert 	{
23155796c8dcSSimon Schubert 	  h->got.offset = s->size;
23165796c8dcSSimon Schubert 	  s->size += 4;
23175796c8dcSSimon Schubert 	  /* R_386_TLS_GD needs 2 consecutive GOT slots.  */
23185796c8dcSSimon Schubert 	  if (GOT_TLS_GD_P (tls_type) || tls_type == GOT_TLS_IE_BOTH)
23195796c8dcSSimon Schubert 	    s->size += 4;
23205796c8dcSSimon Schubert 	}
23215796c8dcSSimon Schubert       dyn = htab->elf.dynamic_sections_created;
23225796c8dcSSimon Schubert       /* R_386_TLS_IE_32 needs one dynamic relocation,
23235796c8dcSSimon Schubert 	 R_386_TLS_IE resp. R_386_TLS_GOTIE needs one dynamic relocation,
23245796c8dcSSimon Schubert 	 (but if both R_386_TLS_IE_32 and R_386_TLS_IE is present, we
23255796c8dcSSimon Schubert 	 need two), R_386_TLS_GD needs one if local symbol and two if
23265796c8dcSSimon Schubert 	 global.  */
23275796c8dcSSimon Schubert       if (tls_type == GOT_TLS_IE_BOTH)
23285796c8dcSSimon Schubert 	htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel);
23295796c8dcSSimon Schubert       else if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
23305796c8dcSSimon Schubert 	       || (tls_type & GOT_TLS_IE))
23315796c8dcSSimon Schubert 	htab->elf.srelgot->size += sizeof (Elf32_External_Rel);
23325796c8dcSSimon Schubert       else if (GOT_TLS_GD_P (tls_type))
23335796c8dcSSimon Schubert 	htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel);
23345796c8dcSSimon Schubert       else if (! GOT_TLS_GDESC_P (tls_type)
23355796c8dcSSimon Schubert 	       && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
23365796c8dcSSimon Schubert 		   || h->root.type != bfd_link_hash_undefweak)
23375796c8dcSSimon Schubert 	       && (info->shared
23385796c8dcSSimon Schubert 		   || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
23395796c8dcSSimon Schubert 	htab->elf.srelgot->size += sizeof (Elf32_External_Rel);
23405796c8dcSSimon Schubert       if (GOT_TLS_GDESC_P (tls_type))
23415796c8dcSSimon Schubert 	htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
23425796c8dcSSimon Schubert     }
23435796c8dcSSimon Schubert   else
23445796c8dcSSimon Schubert     h->got.offset = (bfd_vma) -1;
23455796c8dcSSimon Schubert 
23465796c8dcSSimon Schubert   if (eh->dyn_relocs == NULL)
23475796c8dcSSimon Schubert     return TRUE;
23485796c8dcSSimon Schubert 
23495796c8dcSSimon Schubert   /* In the shared -Bsymbolic case, discard space allocated for
23505796c8dcSSimon Schubert      dynamic pc-relative relocs against symbols which turn out to be
23515796c8dcSSimon Schubert      defined in regular objects.  For the normal shared case, discard
23525796c8dcSSimon Schubert      space for pc-relative relocs that have become local due to symbol
23535796c8dcSSimon Schubert      visibility changes.  */
23545796c8dcSSimon Schubert 
23555796c8dcSSimon Schubert   if (info->shared)
23565796c8dcSSimon Schubert     {
23575796c8dcSSimon Schubert       /* The only reloc that uses pc_count is R_386_PC32, which will
23585796c8dcSSimon Schubert 	 appear on a call or on something like ".long foo - .".  We
23595796c8dcSSimon Schubert 	 want calls to protected symbols to resolve directly to the
23605796c8dcSSimon Schubert 	 function rather than going via the plt.  If people want
23615796c8dcSSimon Schubert 	 function pointer comparisons to work as expected then they
23625796c8dcSSimon Schubert 	 should avoid writing assembly like ".long foo - .".  */
23635796c8dcSSimon Schubert       if (SYMBOL_CALLS_LOCAL (info, h))
23645796c8dcSSimon Schubert 	{
23655796c8dcSSimon Schubert 	  struct elf_dyn_relocs **pp;
23665796c8dcSSimon Schubert 
23675796c8dcSSimon Schubert 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
23685796c8dcSSimon Schubert 	    {
23695796c8dcSSimon Schubert 	      p->count -= p->pc_count;
23705796c8dcSSimon Schubert 	      p->pc_count = 0;
23715796c8dcSSimon Schubert 	      if (p->count == 0)
23725796c8dcSSimon Schubert 		*pp = p->next;
23735796c8dcSSimon Schubert 	      else
23745796c8dcSSimon Schubert 		pp = &p->next;
23755796c8dcSSimon Schubert 	    }
23765796c8dcSSimon Schubert 	}
23775796c8dcSSimon Schubert 
2378a45ae5f8SJohn Marino       if (get_elf_i386_backend_data (info->output_bfd)->is_vxworks)
23795796c8dcSSimon Schubert 	{
23805796c8dcSSimon Schubert 	  struct elf_dyn_relocs **pp;
23815796c8dcSSimon Schubert 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
23825796c8dcSSimon Schubert 	    {
23835796c8dcSSimon Schubert 	      if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
23845796c8dcSSimon Schubert 		*pp = p->next;
23855796c8dcSSimon Schubert 	      else
23865796c8dcSSimon Schubert 		pp = &p->next;
23875796c8dcSSimon Schubert 	    }
23885796c8dcSSimon Schubert 	}
23895796c8dcSSimon Schubert 
23905796c8dcSSimon Schubert       /* Also discard relocs on undefined weak syms with non-default
23915796c8dcSSimon Schubert     	 visibility.  */
23925796c8dcSSimon Schubert       if (eh->dyn_relocs != NULL
23935796c8dcSSimon Schubert 	  && h->root.type == bfd_link_hash_undefweak)
23945796c8dcSSimon Schubert 	{
23955796c8dcSSimon Schubert 	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
23965796c8dcSSimon Schubert 	    eh->dyn_relocs = NULL;
23975796c8dcSSimon Schubert 
23985796c8dcSSimon Schubert 	  /* Make sure undefined weak symbols are output as a dynamic
23995796c8dcSSimon Schubert 	     symbol in PIEs.  */
24005796c8dcSSimon Schubert 	  else if (h->dynindx == -1
24015796c8dcSSimon Schubert 		   && !h->forced_local)
24025796c8dcSSimon Schubert 	    {
24035796c8dcSSimon Schubert 	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
24045796c8dcSSimon Schubert 		return FALSE;
24055796c8dcSSimon Schubert 	    }
24065796c8dcSSimon Schubert 	}
24075796c8dcSSimon Schubert     }
24085796c8dcSSimon Schubert   else if (ELIMINATE_COPY_RELOCS)
24095796c8dcSSimon Schubert     {
24105796c8dcSSimon Schubert       /* For the non-shared case, discard space for relocs against
24115796c8dcSSimon Schubert 	 symbols which turn out to need copy relocs or are not
24125796c8dcSSimon Schubert 	 dynamic.  */
24135796c8dcSSimon Schubert 
24145796c8dcSSimon Schubert       if (!h->non_got_ref
24155796c8dcSSimon Schubert 	  && ((h->def_dynamic
24165796c8dcSSimon Schubert 	       && !h->def_regular)
24175796c8dcSSimon Schubert 	      || (htab->elf.dynamic_sections_created
24185796c8dcSSimon Schubert 		  && (h->root.type == bfd_link_hash_undefweak
24195796c8dcSSimon Schubert 		      || h->root.type == bfd_link_hash_undefined))))
24205796c8dcSSimon Schubert 	{
24215796c8dcSSimon Schubert 	  /* Make sure this symbol is output as a dynamic symbol.
24225796c8dcSSimon Schubert 	     Undefined weak syms won't yet be marked as dynamic.  */
24235796c8dcSSimon Schubert 	  if (h->dynindx == -1
24245796c8dcSSimon Schubert 	      && !h->forced_local)
24255796c8dcSSimon Schubert 	    {
24265796c8dcSSimon Schubert 	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
24275796c8dcSSimon Schubert 		return FALSE;
24285796c8dcSSimon Schubert 	    }
24295796c8dcSSimon Schubert 
24305796c8dcSSimon Schubert 	  /* If that succeeded, we know we'll be keeping all the
24315796c8dcSSimon Schubert 	     relocs.  */
24325796c8dcSSimon Schubert 	  if (h->dynindx != -1)
24335796c8dcSSimon Schubert 	    goto keep;
24345796c8dcSSimon Schubert 	}
24355796c8dcSSimon Schubert 
24365796c8dcSSimon Schubert       eh->dyn_relocs = NULL;
24375796c8dcSSimon Schubert 
24385796c8dcSSimon Schubert     keep: ;
24395796c8dcSSimon Schubert     }
24405796c8dcSSimon Schubert 
24415796c8dcSSimon Schubert   /* Finally, allocate space.  */
24425796c8dcSSimon Schubert   for (p = eh->dyn_relocs; p != NULL; p = p->next)
24435796c8dcSSimon Schubert     {
24445796c8dcSSimon Schubert       asection *sreloc;
24455796c8dcSSimon Schubert 
24465796c8dcSSimon Schubert       sreloc = elf_section_data (p->sec)->sreloc;
24475796c8dcSSimon Schubert 
24485796c8dcSSimon Schubert       BFD_ASSERT (sreloc != NULL);
24495796c8dcSSimon Schubert       sreloc->size += p->count * sizeof (Elf32_External_Rel);
24505796c8dcSSimon Schubert     }
24515796c8dcSSimon Schubert 
24525796c8dcSSimon Schubert   return TRUE;
24535796c8dcSSimon Schubert }
24545796c8dcSSimon Schubert 
24555796c8dcSSimon Schubert /* Allocate space in .plt, .got and associated reloc sections for
24565796c8dcSSimon Schubert    local dynamic relocs.  */
24575796c8dcSSimon Schubert 
24585796c8dcSSimon Schubert static bfd_boolean
elf_i386_allocate_local_dynrelocs(void ** slot,void * inf)24595796c8dcSSimon Schubert elf_i386_allocate_local_dynrelocs (void **slot, void *inf)
24605796c8dcSSimon Schubert {
24615796c8dcSSimon Schubert   struct elf_link_hash_entry *h
24625796c8dcSSimon Schubert     = (struct elf_link_hash_entry *) *slot;
24635796c8dcSSimon Schubert 
24645796c8dcSSimon Schubert   if (h->type != STT_GNU_IFUNC
24655796c8dcSSimon Schubert       || !h->def_regular
24665796c8dcSSimon Schubert       || !h->ref_regular
24675796c8dcSSimon Schubert       || !h->forced_local
24685796c8dcSSimon Schubert       || h->root.type != bfd_link_hash_defined)
24695796c8dcSSimon Schubert     abort ();
24705796c8dcSSimon Schubert 
24715796c8dcSSimon Schubert   return elf_i386_allocate_dynrelocs (h, inf);
24725796c8dcSSimon Schubert }
24735796c8dcSSimon Schubert 
24745796c8dcSSimon Schubert /* Find any dynamic relocs that apply to read-only sections.  */
24755796c8dcSSimon Schubert 
24765796c8dcSSimon Schubert static bfd_boolean
elf_i386_readonly_dynrelocs(struct elf_link_hash_entry * h,void * inf)24775796c8dcSSimon Schubert elf_i386_readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
24785796c8dcSSimon Schubert {
24795796c8dcSSimon Schubert   struct elf_i386_link_hash_entry *eh;
24805796c8dcSSimon Schubert   struct elf_dyn_relocs *p;
24815796c8dcSSimon Schubert 
2482a45ae5f8SJohn Marino   /* Skip local IFUNC symbols. */
2483a45ae5f8SJohn Marino   if (h->forced_local && h->type == STT_GNU_IFUNC)
2484a45ae5f8SJohn Marino     return TRUE;
24855796c8dcSSimon Schubert 
24865796c8dcSSimon Schubert   eh = (struct elf_i386_link_hash_entry *) h;
24875796c8dcSSimon Schubert   for (p = eh->dyn_relocs; p != NULL; p = p->next)
24885796c8dcSSimon Schubert     {
24895796c8dcSSimon Schubert       asection *s = p->sec->output_section;
24905796c8dcSSimon Schubert 
24915796c8dcSSimon Schubert       if (s != NULL && (s->flags & SEC_READONLY) != 0)
24925796c8dcSSimon Schubert 	{
24935796c8dcSSimon Schubert 	  struct bfd_link_info *info = (struct bfd_link_info *) inf;
24945796c8dcSSimon Schubert 
24955796c8dcSSimon Schubert 	  info->flags |= DF_TEXTREL;
24965796c8dcSSimon Schubert 
2497a45ae5f8SJohn Marino 	  if (info->warn_shared_textrel && info->shared)
2498a45ae5f8SJohn Marino 	    info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"),
2499a45ae5f8SJohn Marino 				    p->sec->owner, h->root.root.string,
2500a45ae5f8SJohn Marino 				    p->sec);
2501a45ae5f8SJohn Marino 
25025796c8dcSSimon Schubert 	  /* Not an error, just cut short the traversal.  */
25035796c8dcSSimon Schubert 	  return FALSE;
25045796c8dcSSimon Schubert 	}
25055796c8dcSSimon Schubert     }
25065796c8dcSSimon Schubert   return TRUE;
25075796c8dcSSimon Schubert }
25085796c8dcSSimon Schubert 
2509*ef5ccd6cSJohn Marino /* Convert
2510*ef5ccd6cSJohn Marino    mov foo@GOT(%reg), %reg
2511*ef5ccd6cSJohn Marino    to
2512*ef5ccd6cSJohn Marino    lea foo@GOTOFF(%reg), %reg
2513*ef5ccd6cSJohn Marino    with the local symbol, foo.  */
2514*ef5ccd6cSJohn Marino 
2515*ef5ccd6cSJohn Marino static bfd_boolean
elf_i386_convert_mov_to_lea(bfd * abfd,asection * sec,struct bfd_link_info * link_info)2516*ef5ccd6cSJohn Marino elf_i386_convert_mov_to_lea (bfd *abfd, asection *sec,
2517*ef5ccd6cSJohn Marino 			     struct bfd_link_info *link_info)
2518*ef5ccd6cSJohn Marino {
2519*ef5ccd6cSJohn Marino   Elf_Internal_Shdr *symtab_hdr;
2520*ef5ccd6cSJohn Marino   Elf_Internal_Rela *internal_relocs;
2521*ef5ccd6cSJohn Marino   Elf_Internal_Rela *irel, *irelend;
2522*ef5ccd6cSJohn Marino   bfd_byte *contents;
2523*ef5ccd6cSJohn Marino   struct elf_i386_link_hash_table *htab;
2524*ef5ccd6cSJohn Marino   bfd_boolean changed_contents;
2525*ef5ccd6cSJohn Marino   bfd_boolean changed_relocs;
2526*ef5ccd6cSJohn Marino   bfd_signed_vma *local_got_refcounts;
2527*ef5ccd6cSJohn Marino 
2528*ef5ccd6cSJohn Marino   /* Don't even try to convert non-ELF outputs.  */
2529*ef5ccd6cSJohn Marino   if (!is_elf_hash_table (link_info->hash))
2530*ef5ccd6cSJohn Marino     return FALSE;
2531*ef5ccd6cSJohn Marino 
2532*ef5ccd6cSJohn Marino   /* Nothing to do if there are no codes, no relocations or no output.  */
2533*ef5ccd6cSJohn Marino   if ((sec->flags & (SEC_CODE | SEC_RELOC)) != (SEC_CODE | SEC_RELOC)
2534*ef5ccd6cSJohn Marino       || sec->reloc_count == 0
2535*ef5ccd6cSJohn Marino       || discarded_section (sec))
2536*ef5ccd6cSJohn Marino     return TRUE;
2537*ef5ccd6cSJohn Marino 
2538*ef5ccd6cSJohn Marino   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2539*ef5ccd6cSJohn Marino 
2540*ef5ccd6cSJohn Marino   /* Load the relocations for this section.  */
2541*ef5ccd6cSJohn Marino   internal_relocs = (_bfd_elf_link_read_relocs
2542*ef5ccd6cSJohn Marino 		     (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
2543*ef5ccd6cSJohn Marino 		      link_info->keep_memory));
2544*ef5ccd6cSJohn Marino   if (internal_relocs == NULL)
2545*ef5ccd6cSJohn Marino     return FALSE;
2546*ef5ccd6cSJohn Marino 
2547*ef5ccd6cSJohn Marino   htab = elf_i386_hash_table (link_info);
2548*ef5ccd6cSJohn Marino   changed_contents = FALSE;
2549*ef5ccd6cSJohn Marino   changed_relocs = FALSE;
2550*ef5ccd6cSJohn Marino   local_got_refcounts = elf_local_got_refcounts (abfd);
2551*ef5ccd6cSJohn Marino 
2552*ef5ccd6cSJohn Marino   /* Get the section contents.  */
2553*ef5ccd6cSJohn Marino   if (elf_section_data (sec)->this_hdr.contents != NULL)
2554*ef5ccd6cSJohn Marino     contents = elf_section_data (sec)->this_hdr.contents;
2555*ef5ccd6cSJohn Marino   else
2556*ef5ccd6cSJohn Marino     {
2557*ef5ccd6cSJohn Marino       if (!bfd_malloc_and_get_section (abfd, sec, &contents))
2558*ef5ccd6cSJohn Marino 	goto error_return;
2559*ef5ccd6cSJohn Marino     }
2560*ef5ccd6cSJohn Marino 
2561*ef5ccd6cSJohn Marino   irelend = internal_relocs + sec->reloc_count;
2562*ef5ccd6cSJohn Marino   for (irel = internal_relocs; irel < irelend; irel++)
2563*ef5ccd6cSJohn Marino     {
2564*ef5ccd6cSJohn Marino       unsigned int r_type = ELF32_R_TYPE (irel->r_info);
2565*ef5ccd6cSJohn Marino       unsigned int r_symndx = ELF32_R_SYM (irel->r_info);
2566*ef5ccd6cSJohn Marino       unsigned int indx;
2567*ef5ccd6cSJohn Marino       struct elf_link_hash_entry *h;
2568*ef5ccd6cSJohn Marino 
2569*ef5ccd6cSJohn Marino       if (r_type != R_386_GOT32)
2570*ef5ccd6cSJohn Marino 	continue;
2571*ef5ccd6cSJohn Marino 
2572*ef5ccd6cSJohn Marino       /* Get the symbol referred to by the reloc.  */
2573*ef5ccd6cSJohn Marino       if (r_symndx < symtab_hdr->sh_info)
2574*ef5ccd6cSJohn Marino 	{
2575*ef5ccd6cSJohn Marino 	  Elf_Internal_Sym *isym;
2576*ef5ccd6cSJohn Marino 
2577*ef5ccd6cSJohn Marino 	  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
2578*ef5ccd6cSJohn Marino 					abfd, r_symndx);
2579*ef5ccd6cSJohn Marino 
2580*ef5ccd6cSJohn Marino 	  /* STT_GNU_IFUNC must keep R_386_GOT32 relocation.  */
2581*ef5ccd6cSJohn Marino 	  if (ELF_ST_TYPE (isym->st_info) != STT_GNU_IFUNC
2582*ef5ccd6cSJohn Marino 	      && bfd_get_8 (input_bfd,
2583*ef5ccd6cSJohn Marino 			    contents + irel->r_offset - 2) == 0x8b)
2584*ef5ccd6cSJohn Marino 	    {
2585*ef5ccd6cSJohn Marino 	      bfd_put_8 (output_bfd, 0x8d,
2586*ef5ccd6cSJohn Marino 			 contents + irel->r_offset - 2);
2587*ef5ccd6cSJohn Marino 	      irel->r_info = ELF32_R_INFO (r_symndx, R_386_GOTOFF);
2588*ef5ccd6cSJohn Marino 	      if (local_got_refcounts != NULL
2589*ef5ccd6cSJohn Marino 		  && local_got_refcounts[r_symndx] > 0)
2590*ef5ccd6cSJohn Marino 		local_got_refcounts[r_symndx] -= 1;
2591*ef5ccd6cSJohn Marino 	      changed_contents = TRUE;
2592*ef5ccd6cSJohn Marino 	      changed_relocs = TRUE;
2593*ef5ccd6cSJohn Marino 	    }
2594*ef5ccd6cSJohn Marino 	  continue;
2595*ef5ccd6cSJohn Marino 	}
2596*ef5ccd6cSJohn Marino 
2597*ef5ccd6cSJohn Marino       indx = r_symndx - symtab_hdr->sh_info;
2598*ef5ccd6cSJohn Marino       h = elf_sym_hashes (abfd)[indx];
2599*ef5ccd6cSJohn Marino       BFD_ASSERT (h != NULL);
2600*ef5ccd6cSJohn Marino 
2601*ef5ccd6cSJohn Marino       while (h->root.type == bfd_link_hash_indirect
2602*ef5ccd6cSJohn Marino 	     || h->root.type == bfd_link_hash_warning)
2603*ef5ccd6cSJohn Marino 	h = (struct elf_link_hash_entry *) h->root.u.i.link;
2604*ef5ccd6cSJohn Marino 
2605*ef5ccd6cSJohn Marino       /* STT_GNU_IFUNC must keep R_386_GOT32 relocation.  We also avoid
2606*ef5ccd6cSJohn Marino 	 optimizing _DYNAMIC since ld.so may use its link-time address.  */
2607*ef5ccd6cSJohn Marino       if (h->def_regular
2608*ef5ccd6cSJohn Marino 	  && h->type != STT_GNU_IFUNC
2609*ef5ccd6cSJohn Marino 	  && h != htab->elf.hdynamic
2610*ef5ccd6cSJohn Marino 	  && SYMBOL_REFERENCES_LOCAL (link_info, h)
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 = ELF32_R_INFO (r_symndx, R_386_GOTOFF);
2617*ef5ccd6cSJohn Marino 	  if (h->got.refcount > 0)
2618*ef5ccd6cSJohn Marino 	    h->got.refcount -= 1;
2619*ef5ccd6cSJohn Marino 	  changed_contents = TRUE;
2620*ef5ccd6cSJohn Marino 	  changed_relocs = TRUE;
2621*ef5ccd6cSJohn Marino 	}
2622*ef5ccd6cSJohn Marino     }
2623*ef5ccd6cSJohn Marino 
2624*ef5ccd6cSJohn Marino   if (contents != NULL
2625*ef5ccd6cSJohn Marino       && elf_section_data (sec)->this_hdr.contents != contents)
2626*ef5ccd6cSJohn Marino     {
2627*ef5ccd6cSJohn Marino       if (!changed_contents && !link_info->keep_memory)
2628*ef5ccd6cSJohn Marino 	free (contents);
2629*ef5ccd6cSJohn Marino       else
2630*ef5ccd6cSJohn Marino 	{
2631*ef5ccd6cSJohn Marino 	  /* Cache the section contents for elf_link_input_bfd.  */
2632*ef5ccd6cSJohn Marino 	  elf_section_data (sec)->this_hdr.contents = contents;
2633*ef5ccd6cSJohn Marino 	}
2634*ef5ccd6cSJohn Marino     }
2635*ef5ccd6cSJohn Marino 
2636*ef5ccd6cSJohn Marino   if (elf_section_data (sec)->relocs != internal_relocs)
2637*ef5ccd6cSJohn Marino     {
2638*ef5ccd6cSJohn Marino       if (!changed_relocs)
2639*ef5ccd6cSJohn Marino 	free (internal_relocs);
2640*ef5ccd6cSJohn Marino       else
2641*ef5ccd6cSJohn Marino 	elf_section_data (sec)->relocs = internal_relocs;
2642*ef5ccd6cSJohn Marino     }
2643*ef5ccd6cSJohn Marino 
2644*ef5ccd6cSJohn Marino   return TRUE;
2645*ef5ccd6cSJohn Marino 
2646*ef5ccd6cSJohn Marino  error_return:
2647*ef5ccd6cSJohn Marino   if (contents != NULL
2648*ef5ccd6cSJohn Marino       && elf_section_data (sec)->this_hdr.contents != contents)
2649*ef5ccd6cSJohn Marino     free (contents);
2650*ef5ccd6cSJohn Marino   if (internal_relocs != NULL
2651*ef5ccd6cSJohn Marino       && elf_section_data (sec)->relocs != internal_relocs)
2652*ef5ccd6cSJohn Marino     free (internal_relocs);
2653*ef5ccd6cSJohn Marino   return FALSE;
2654*ef5ccd6cSJohn Marino }
2655*ef5ccd6cSJohn Marino 
26565796c8dcSSimon Schubert /* Set the sizes of the dynamic sections.  */
26575796c8dcSSimon Schubert 
26585796c8dcSSimon Schubert static bfd_boolean
elf_i386_size_dynamic_sections(bfd * output_bfd,struct bfd_link_info * info)2659a45ae5f8SJohn Marino elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
26605796c8dcSSimon Schubert {
26615796c8dcSSimon Schubert   struct elf_i386_link_hash_table *htab;
26625796c8dcSSimon Schubert   bfd *dynobj;
26635796c8dcSSimon Schubert   asection *s;
26645796c8dcSSimon Schubert   bfd_boolean relocs;
26655796c8dcSSimon Schubert   bfd *ibfd;
26665796c8dcSSimon Schubert 
26675796c8dcSSimon Schubert   htab = elf_i386_hash_table (info);
2668cf7f2e2dSJohn Marino   if (htab == NULL)
2669cf7f2e2dSJohn Marino     return FALSE;
26705796c8dcSSimon Schubert   dynobj = htab->elf.dynobj;
26715796c8dcSSimon Schubert   if (dynobj == NULL)
26725796c8dcSSimon Schubert     abort ();
26735796c8dcSSimon Schubert 
26745796c8dcSSimon Schubert   if (htab->elf.dynamic_sections_created)
26755796c8dcSSimon Schubert     {
26765796c8dcSSimon Schubert       /* Set the contents of the .interp section to the interpreter.  */
26775796c8dcSSimon Schubert       if (info->executable)
26785796c8dcSSimon Schubert 	{
2679*ef5ccd6cSJohn Marino 	  s = bfd_get_linker_section (dynobj, ".interp");
26805796c8dcSSimon Schubert 	  if (s == NULL)
26815796c8dcSSimon Schubert 	    abort ();
26825796c8dcSSimon Schubert 	  s->size = sizeof ELF_DYNAMIC_INTERPRETER;
26835796c8dcSSimon Schubert 	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
26845796c8dcSSimon Schubert 	}
26855796c8dcSSimon Schubert     }
26865796c8dcSSimon Schubert 
26875796c8dcSSimon Schubert   /* Set up .got offsets for local syms, and space for local dynamic
26885796c8dcSSimon Schubert      relocs.  */
26895796c8dcSSimon Schubert   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
26905796c8dcSSimon Schubert     {
26915796c8dcSSimon Schubert       bfd_signed_vma *local_got;
26925796c8dcSSimon Schubert       bfd_signed_vma *end_local_got;
26935796c8dcSSimon Schubert       char *local_tls_type;
26945796c8dcSSimon Schubert       bfd_vma *local_tlsdesc_gotent;
26955796c8dcSSimon Schubert       bfd_size_type locsymcount;
26965796c8dcSSimon Schubert       Elf_Internal_Shdr *symtab_hdr;
26975796c8dcSSimon Schubert       asection *srel;
26985796c8dcSSimon Schubert 
26995796c8dcSSimon Schubert       if (! is_i386_elf (ibfd))
27005796c8dcSSimon Schubert 	continue;
27015796c8dcSSimon Schubert 
27025796c8dcSSimon Schubert       for (s = ibfd->sections; s != NULL; s = s->next)
27035796c8dcSSimon Schubert 	{
27045796c8dcSSimon Schubert 	  struct elf_dyn_relocs *p;
27055796c8dcSSimon Schubert 
2706*ef5ccd6cSJohn Marino 	  if (!elf_i386_convert_mov_to_lea (ibfd, s, info))
2707*ef5ccd6cSJohn Marino 	    return FALSE;
2708*ef5ccd6cSJohn Marino 
27095796c8dcSSimon Schubert 	  for (p = ((struct elf_dyn_relocs *)
27105796c8dcSSimon Schubert 		     elf_section_data (s)->local_dynrel);
27115796c8dcSSimon Schubert 	       p != NULL;
27125796c8dcSSimon Schubert 	       p = p->next)
27135796c8dcSSimon Schubert 	    {
27145796c8dcSSimon Schubert 	      if (!bfd_is_abs_section (p->sec)
27155796c8dcSSimon Schubert 		  && bfd_is_abs_section (p->sec->output_section))
27165796c8dcSSimon Schubert 		{
27175796c8dcSSimon Schubert 		  /* Input section has been discarded, either because
27185796c8dcSSimon Schubert 		     it is a copy of a linkonce section or due to
27195796c8dcSSimon Schubert 		     linker script /DISCARD/, so we'll be discarding
27205796c8dcSSimon Schubert 		     the relocs too.  */
27215796c8dcSSimon Schubert 		}
2722a45ae5f8SJohn Marino 	      else if (get_elf_i386_backend_data (output_bfd)->is_vxworks
27235796c8dcSSimon Schubert 		       && strcmp (p->sec->output_section->name,
27245796c8dcSSimon Schubert 				  ".tls_vars") == 0)
27255796c8dcSSimon Schubert 		{
27265796c8dcSSimon Schubert 		  /* Relocations in vxworks .tls_vars sections are
27275796c8dcSSimon Schubert 		     handled specially by the loader.  */
27285796c8dcSSimon Schubert 		}
27295796c8dcSSimon Schubert 	      else if (p->count != 0)
27305796c8dcSSimon Schubert 		{
27315796c8dcSSimon Schubert 		  srel = elf_section_data (p->sec)->sreloc;
27325796c8dcSSimon Schubert 		  srel->size += p->count * sizeof (Elf32_External_Rel);
2733a45ae5f8SJohn Marino 		  if ((p->sec->output_section->flags & SEC_READONLY) != 0
2734a45ae5f8SJohn Marino 		      && (info->flags & DF_TEXTREL) == 0)
2735a45ae5f8SJohn Marino 		    {
27365796c8dcSSimon Schubert 		      info->flags |= DF_TEXTREL;
2737a45ae5f8SJohn Marino 		      if (info->warn_shared_textrel && info->shared)
2738a45ae5f8SJohn Marino 			info->callbacks->einfo (_("%P: %B: warning: relocation in readonly section `%A'.\n"),
2739a45ae5f8SJohn Marino 						p->sec->owner, p->sec);
2740a45ae5f8SJohn Marino 		    }
27415796c8dcSSimon Schubert 		}
27425796c8dcSSimon Schubert 	    }
27435796c8dcSSimon Schubert 	}
27445796c8dcSSimon Schubert 
27455796c8dcSSimon Schubert       local_got = elf_local_got_refcounts (ibfd);
27465796c8dcSSimon Schubert       if (!local_got)
27475796c8dcSSimon Schubert 	continue;
27485796c8dcSSimon Schubert 
27495796c8dcSSimon Schubert       symtab_hdr = &elf_symtab_hdr (ibfd);
27505796c8dcSSimon Schubert       locsymcount = symtab_hdr->sh_info;
27515796c8dcSSimon Schubert       end_local_got = local_got + locsymcount;
27525796c8dcSSimon Schubert       local_tls_type = elf_i386_local_got_tls_type (ibfd);
27535796c8dcSSimon Schubert       local_tlsdesc_gotent = elf_i386_local_tlsdesc_gotent (ibfd);
27545796c8dcSSimon Schubert       s = htab->elf.sgot;
27555796c8dcSSimon Schubert       srel = htab->elf.srelgot;
27565796c8dcSSimon Schubert       for (; local_got < end_local_got;
27575796c8dcSSimon Schubert 	   ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
27585796c8dcSSimon Schubert 	{
27595796c8dcSSimon Schubert 	  *local_tlsdesc_gotent = (bfd_vma) -1;
27605796c8dcSSimon Schubert 	  if (*local_got > 0)
27615796c8dcSSimon Schubert 	    {
27625796c8dcSSimon Schubert 	      if (GOT_TLS_GDESC_P (*local_tls_type))
27635796c8dcSSimon Schubert 		{
27645796c8dcSSimon Schubert 		  *local_tlsdesc_gotent = htab->elf.sgotplt->size
27655796c8dcSSimon Schubert 		    - elf_i386_compute_jump_table_size (htab);
27665796c8dcSSimon Schubert 		  htab->elf.sgotplt->size += 8;
27675796c8dcSSimon Schubert 		  *local_got = (bfd_vma) -2;
27685796c8dcSSimon Schubert 		}
27695796c8dcSSimon Schubert 	      if (! GOT_TLS_GDESC_P (*local_tls_type)
27705796c8dcSSimon Schubert 		  || GOT_TLS_GD_P (*local_tls_type))
27715796c8dcSSimon Schubert 		{
27725796c8dcSSimon Schubert 		  *local_got = s->size;
27735796c8dcSSimon Schubert 		  s->size += 4;
27745796c8dcSSimon Schubert 		  if (GOT_TLS_GD_P (*local_tls_type)
27755796c8dcSSimon Schubert 		      || *local_tls_type == GOT_TLS_IE_BOTH)
27765796c8dcSSimon Schubert 		    s->size += 4;
27775796c8dcSSimon Schubert 		}
27785796c8dcSSimon Schubert 	      if (info->shared
27795796c8dcSSimon Schubert 		  || GOT_TLS_GD_ANY_P (*local_tls_type)
27805796c8dcSSimon Schubert 		  || (*local_tls_type & GOT_TLS_IE))
27815796c8dcSSimon Schubert 		{
27825796c8dcSSimon Schubert 		  if (*local_tls_type == GOT_TLS_IE_BOTH)
27835796c8dcSSimon Schubert 		    srel->size += 2 * sizeof (Elf32_External_Rel);
27845796c8dcSSimon Schubert 		  else if (GOT_TLS_GD_P (*local_tls_type)
27855796c8dcSSimon Schubert 			   || ! GOT_TLS_GDESC_P (*local_tls_type))
27865796c8dcSSimon Schubert 		    srel->size += sizeof (Elf32_External_Rel);
27875796c8dcSSimon Schubert 		  if (GOT_TLS_GDESC_P (*local_tls_type))
27885796c8dcSSimon Schubert 		    htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
27895796c8dcSSimon Schubert 		}
27905796c8dcSSimon Schubert 	    }
27915796c8dcSSimon Schubert 	  else
27925796c8dcSSimon Schubert 	    *local_got = (bfd_vma) -1;
27935796c8dcSSimon Schubert 	}
27945796c8dcSSimon Schubert     }
27955796c8dcSSimon Schubert 
27965796c8dcSSimon Schubert   if (htab->tls_ldm_got.refcount > 0)
27975796c8dcSSimon Schubert     {
27985796c8dcSSimon Schubert       /* Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
27995796c8dcSSimon Schubert 	 relocs.  */
28005796c8dcSSimon Schubert       htab->tls_ldm_got.offset = htab->elf.sgot->size;
28015796c8dcSSimon Schubert       htab->elf.sgot->size += 8;
28025796c8dcSSimon Schubert       htab->elf.srelgot->size += sizeof (Elf32_External_Rel);
28035796c8dcSSimon Schubert     }
28045796c8dcSSimon Schubert   else
28055796c8dcSSimon Schubert     htab->tls_ldm_got.offset = -1;
28065796c8dcSSimon Schubert 
28075796c8dcSSimon Schubert   /* Allocate global sym .plt and .got entries, and space for global
28085796c8dcSSimon Schubert      sym dynamic relocs.  */
28095796c8dcSSimon Schubert   elf_link_hash_traverse (&htab->elf, elf_i386_allocate_dynrelocs, info);
28105796c8dcSSimon Schubert 
28115796c8dcSSimon Schubert   /* Allocate .plt and .got entries, and space for local symbols.  */
28125796c8dcSSimon Schubert   htab_traverse (htab->loc_hash_table,
28135796c8dcSSimon Schubert 		 elf_i386_allocate_local_dynrelocs,
28145796c8dcSSimon Schubert 		 info);
28155796c8dcSSimon Schubert 
28165796c8dcSSimon Schubert   /* For every jump slot reserved in the sgotplt, reloc_count is
28175796c8dcSSimon Schubert      incremented.  However, when we reserve space for TLS descriptors,
28185796c8dcSSimon Schubert      it's not incremented, so in order to compute the space reserved
28195796c8dcSSimon Schubert      for them, it suffices to multiply the reloc count by the jump
2820a45ae5f8SJohn Marino      slot size.
2821a45ae5f8SJohn Marino 
2822a45ae5f8SJohn Marino      PR ld/13302: We start next_irelative_index at the end of .rela.plt
2823a45ae5f8SJohn Marino      so that R_386_IRELATIVE entries come last.  */
28245796c8dcSSimon Schubert   if (htab->elf.srelplt)
2825a45ae5f8SJohn Marino     {
2826a45ae5f8SJohn Marino       htab->next_tls_desc_index = htab->elf.srelplt->reloc_count;
28275796c8dcSSimon Schubert       htab->sgotplt_jump_table_size = htab->next_tls_desc_index * 4;
2828a45ae5f8SJohn Marino       htab->next_irelative_index = htab->elf.srelplt->reloc_count - 1;
2829a45ae5f8SJohn Marino     }
2830a45ae5f8SJohn Marino   else if (htab->elf.irelplt)
2831a45ae5f8SJohn Marino     htab->next_irelative_index = htab->elf.irelplt->reloc_count - 1;
2832a45ae5f8SJohn Marino 
28335796c8dcSSimon Schubert 
2834c50c785cSJohn Marino   if (htab->elf.sgotplt)
2835c50c785cSJohn Marino     {
2836c50c785cSJohn Marino       /* Don't allocate .got.plt section if there are no GOT nor PLT
2837*ef5ccd6cSJohn Marino          entries and there is no reference to _GLOBAL_OFFSET_TABLE_.  */
2838*ef5ccd6cSJohn Marino       if ((htab->elf.hgot == NULL
2839*ef5ccd6cSJohn Marino 	   || !htab->elf.hgot->ref_regular_nonweak)
2840c50c785cSJohn Marino 	  && (htab->elf.sgotplt->size
2841c50c785cSJohn Marino 	      == get_elf_backend_data (output_bfd)->got_header_size)
2842c50c785cSJohn Marino 	  && (htab->elf.splt == NULL
2843c50c785cSJohn Marino 	      || htab->elf.splt->size == 0)
2844c50c785cSJohn Marino 	  && (htab->elf.sgot == NULL
2845c50c785cSJohn Marino 	      || htab->elf.sgot->size == 0)
2846c50c785cSJohn Marino 	  && (htab->elf.iplt == NULL
2847c50c785cSJohn Marino 	      || htab->elf.iplt->size == 0)
2848c50c785cSJohn Marino 	  && (htab->elf.igotplt == NULL
2849c50c785cSJohn Marino 	      || htab->elf.igotplt->size == 0))
2850c50c785cSJohn Marino 	htab->elf.sgotplt->size = 0;
2851c50c785cSJohn Marino     }
2852c50c785cSJohn Marino 
2853*ef5ccd6cSJohn Marino 
2854*ef5ccd6cSJohn Marino   if (htab->plt_eh_frame != NULL
2855*ef5ccd6cSJohn Marino       && htab->elf.splt != NULL
2856*ef5ccd6cSJohn Marino       && htab->elf.splt->size != 0
2857*ef5ccd6cSJohn Marino       && !bfd_is_abs_section (htab->elf.splt->output_section)
2858*ef5ccd6cSJohn Marino       && _bfd_elf_eh_frame_present (info))
2859*ef5ccd6cSJohn Marino     htab->plt_eh_frame->size = sizeof (elf_i386_eh_frame_plt);
2860*ef5ccd6cSJohn Marino 
28615796c8dcSSimon Schubert   /* We now have determined the sizes of the various dynamic sections.
28625796c8dcSSimon Schubert      Allocate memory for them.  */
28635796c8dcSSimon Schubert   relocs = FALSE;
28645796c8dcSSimon Schubert   for (s = dynobj->sections; s != NULL; s = s->next)
28655796c8dcSSimon Schubert     {
28665796c8dcSSimon Schubert       bfd_boolean strip_section = TRUE;
28675796c8dcSSimon Schubert 
28685796c8dcSSimon Schubert       if ((s->flags & SEC_LINKER_CREATED) == 0)
28695796c8dcSSimon Schubert 	continue;
28705796c8dcSSimon Schubert 
28715796c8dcSSimon Schubert       if (s == htab->elf.splt
2872*ef5ccd6cSJohn Marino 	  || s == htab->elf.sgot)
28735796c8dcSSimon Schubert 	{
28745796c8dcSSimon Schubert 	  /* Strip this section if we don't need it; see the
28755796c8dcSSimon Schubert 	     comment below.  */
28765796c8dcSSimon Schubert 	  /* We'd like to strip these sections if they aren't needed, but if
28775796c8dcSSimon Schubert 	     we've exported dynamic symbols from them we must leave them.
28785796c8dcSSimon Schubert 	     It's too late to tell BFD to get rid of the symbols.  */
28795796c8dcSSimon Schubert 
28805796c8dcSSimon Schubert 	  if (htab->elf.hplt != NULL)
28815796c8dcSSimon Schubert 	    strip_section = FALSE;
28825796c8dcSSimon Schubert 	}
2883*ef5ccd6cSJohn Marino       else if (s == htab->elf.sgotplt
2884*ef5ccd6cSJohn Marino 	       || s == htab->elf.iplt
2885*ef5ccd6cSJohn Marino 	       || s == htab->elf.igotplt
2886*ef5ccd6cSJohn Marino 	       || s == htab->plt_eh_frame
2887*ef5ccd6cSJohn Marino 	       || s == htab->sdynbss)
2888*ef5ccd6cSJohn Marino 	{
2889*ef5ccd6cSJohn Marino 	  /* Strip these too.  */
2890*ef5ccd6cSJohn Marino 	}
28915796c8dcSSimon Schubert       else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rel"))
28925796c8dcSSimon Schubert 	{
28935796c8dcSSimon Schubert 	  if (s->size != 0
28945796c8dcSSimon Schubert 	      && s != htab->elf.srelplt
28955796c8dcSSimon Schubert 	      && s != htab->srelplt2)
28965796c8dcSSimon Schubert 	    relocs = TRUE;
28975796c8dcSSimon Schubert 
28985796c8dcSSimon Schubert 	  /* We use the reloc_count field as a counter if we need
28995796c8dcSSimon Schubert 	     to copy relocs into the output file.  */
29005796c8dcSSimon Schubert 	  s->reloc_count = 0;
29015796c8dcSSimon Schubert 	}
29025796c8dcSSimon Schubert       else
29035796c8dcSSimon Schubert 	{
29045796c8dcSSimon Schubert 	  /* It's not one of our sections, so don't allocate space.  */
29055796c8dcSSimon Schubert 	  continue;
29065796c8dcSSimon Schubert 	}
29075796c8dcSSimon Schubert 
29085796c8dcSSimon Schubert       if (s->size == 0)
29095796c8dcSSimon Schubert 	{
29105796c8dcSSimon Schubert 	  /* If we don't need this section, strip it from the
29115796c8dcSSimon Schubert 	     output file.  This is mostly to handle .rel.bss and
29125796c8dcSSimon Schubert 	     .rel.plt.  We must create both sections in
29135796c8dcSSimon Schubert 	     create_dynamic_sections, because they must be created
29145796c8dcSSimon Schubert 	     before the linker maps input sections to output
29155796c8dcSSimon Schubert 	     sections.  The linker does that before
29165796c8dcSSimon Schubert 	     adjust_dynamic_symbol is called, and it is that
29175796c8dcSSimon Schubert 	     function which decides whether anything needs to go
29185796c8dcSSimon Schubert 	     into these sections.  */
29195796c8dcSSimon Schubert 	  if (strip_section)
29205796c8dcSSimon Schubert 	    s->flags |= SEC_EXCLUDE;
29215796c8dcSSimon Schubert 	  continue;
29225796c8dcSSimon Schubert 	}
29235796c8dcSSimon Schubert 
29245796c8dcSSimon Schubert       if ((s->flags & SEC_HAS_CONTENTS) == 0)
29255796c8dcSSimon Schubert 	continue;
29265796c8dcSSimon Schubert 
29275796c8dcSSimon Schubert       /* Allocate memory for the section contents.  We use bfd_zalloc
29285796c8dcSSimon Schubert 	 here in case unused entries are not reclaimed before the
29295796c8dcSSimon Schubert 	 section's contents are written out.  This should not happen,
29305796c8dcSSimon Schubert 	 but this way if it does, we get a R_386_NONE reloc instead
29315796c8dcSSimon Schubert 	 of garbage.  */
29325796c8dcSSimon Schubert       s->contents = (unsigned char *) bfd_zalloc (dynobj, s->size);
29335796c8dcSSimon Schubert       if (s->contents == NULL)
29345796c8dcSSimon Schubert 	return FALSE;
29355796c8dcSSimon Schubert     }
29365796c8dcSSimon Schubert 
2937a45ae5f8SJohn Marino   if (htab->plt_eh_frame != NULL
2938*ef5ccd6cSJohn Marino       && htab->plt_eh_frame->contents != NULL)
2939*ef5ccd6cSJohn Marino     {
2940*ef5ccd6cSJohn Marino       memcpy (htab->plt_eh_frame->contents, elf_i386_eh_frame_plt,
2941*ef5ccd6cSJohn Marino 	      sizeof (elf_i386_eh_frame_plt));
2942a45ae5f8SJohn Marino       bfd_put_32 (dynobj, htab->elf.splt->size,
2943a45ae5f8SJohn Marino 		  htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
2944*ef5ccd6cSJohn Marino     }
2945a45ae5f8SJohn Marino 
29465796c8dcSSimon Schubert   if (htab->elf.dynamic_sections_created)
29475796c8dcSSimon Schubert     {
29485796c8dcSSimon Schubert       /* Add some entries to the .dynamic section.  We fill in the
29495796c8dcSSimon Schubert 	 values later, in elf_i386_finish_dynamic_sections, but we
29505796c8dcSSimon Schubert 	 must add the entries now so that we get the correct size for
29515796c8dcSSimon Schubert 	 the .dynamic section.  The DT_DEBUG entry is filled in by the
29525796c8dcSSimon Schubert 	 dynamic linker and used by the debugger.  */
29535796c8dcSSimon Schubert #define add_dynamic_entry(TAG, VAL) \
29545796c8dcSSimon Schubert   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
29555796c8dcSSimon Schubert 
29565796c8dcSSimon Schubert       if (info->executable)
29575796c8dcSSimon Schubert 	{
29585796c8dcSSimon Schubert 	  if (!add_dynamic_entry (DT_DEBUG, 0))
29595796c8dcSSimon Schubert 	    return FALSE;
29605796c8dcSSimon Schubert 	}
29615796c8dcSSimon Schubert 
29625796c8dcSSimon Schubert       if (htab->elf.splt->size != 0)
29635796c8dcSSimon Schubert 	{
29645796c8dcSSimon Schubert 	  if (!add_dynamic_entry (DT_PLTGOT, 0)
29655796c8dcSSimon Schubert 	      || !add_dynamic_entry (DT_PLTRELSZ, 0)
29665796c8dcSSimon Schubert 	      || !add_dynamic_entry (DT_PLTREL, DT_REL)
29675796c8dcSSimon Schubert 	      || !add_dynamic_entry (DT_JMPREL, 0))
29685796c8dcSSimon Schubert 	    return FALSE;
29695796c8dcSSimon Schubert 	}
29705796c8dcSSimon Schubert 
29715796c8dcSSimon Schubert       if (relocs)
29725796c8dcSSimon Schubert 	{
29735796c8dcSSimon Schubert 	  if (!add_dynamic_entry (DT_REL, 0)
29745796c8dcSSimon Schubert 	      || !add_dynamic_entry (DT_RELSZ, 0)
29755796c8dcSSimon Schubert 	      || !add_dynamic_entry (DT_RELENT, sizeof (Elf32_External_Rel)))
29765796c8dcSSimon Schubert 	    return FALSE;
29775796c8dcSSimon Schubert 
29785796c8dcSSimon Schubert 	  /* If any dynamic relocs apply to a read-only section,
29795796c8dcSSimon Schubert 	     then we need a DT_TEXTREL entry.  */
29805796c8dcSSimon Schubert 	  if ((info->flags & DF_TEXTREL) == 0)
29815796c8dcSSimon Schubert 	    elf_link_hash_traverse (&htab->elf,
29825796c8dcSSimon Schubert 				    elf_i386_readonly_dynrelocs, info);
29835796c8dcSSimon Schubert 
29845796c8dcSSimon Schubert 	  if ((info->flags & DF_TEXTREL) != 0)
29855796c8dcSSimon Schubert 	    {
29865796c8dcSSimon Schubert 	      if (!add_dynamic_entry (DT_TEXTREL, 0))
29875796c8dcSSimon Schubert 		return FALSE;
29885796c8dcSSimon Schubert 	    }
29895796c8dcSSimon Schubert 	}
2990a45ae5f8SJohn Marino       if (get_elf_i386_backend_data (output_bfd)->is_vxworks
29915796c8dcSSimon Schubert 	  && !elf_vxworks_add_dynamic_entries (output_bfd, info))
29925796c8dcSSimon Schubert 	return FALSE;
29935796c8dcSSimon Schubert     }
29945796c8dcSSimon Schubert #undef add_dynamic_entry
29955796c8dcSSimon Schubert 
29965796c8dcSSimon Schubert   return TRUE;
29975796c8dcSSimon Schubert }
29985796c8dcSSimon Schubert 
29995796c8dcSSimon Schubert static bfd_boolean
elf_i386_always_size_sections(bfd * output_bfd,struct bfd_link_info * info)30005796c8dcSSimon Schubert elf_i386_always_size_sections (bfd *output_bfd,
30015796c8dcSSimon Schubert 			       struct bfd_link_info *info)
30025796c8dcSSimon Schubert {
30035796c8dcSSimon Schubert   asection *tls_sec = elf_hash_table (info)->tls_sec;
30045796c8dcSSimon Schubert 
30055796c8dcSSimon Schubert   if (tls_sec)
30065796c8dcSSimon Schubert     {
30075796c8dcSSimon Schubert       struct elf_link_hash_entry *tlsbase;
30085796c8dcSSimon Schubert 
30095796c8dcSSimon Schubert       tlsbase = elf_link_hash_lookup (elf_hash_table (info),
30105796c8dcSSimon Schubert 				      "_TLS_MODULE_BASE_",
30115796c8dcSSimon Schubert 				      FALSE, FALSE, FALSE);
30125796c8dcSSimon Schubert 
30135796c8dcSSimon Schubert       if (tlsbase && tlsbase->type == STT_TLS)
30145796c8dcSSimon Schubert 	{
3015cf7f2e2dSJohn Marino 	  struct elf_i386_link_hash_table *htab;
30165796c8dcSSimon Schubert 	  struct bfd_link_hash_entry *bh = NULL;
30175796c8dcSSimon Schubert 	  const struct elf_backend_data *bed
30185796c8dcSSimon Schubert 	    = get_elf_backend_data (output_bfd);
30195796c8dcSSimon Schubert 
3020cf7f2e2dSJohn Marino 	  htab = elf_i386_hash_table (info);
3021cf7f2e2dSJohn Marino 	  if (htab == NULL)
3022cf7f2e2dSJohn Marino 	    return FALSE;
3023cf7f2e2dSJohn Marino 
30245796c8dcSSimon Schubert 	  if (!(_bfd_generic_link_add_one_symbol
30255796c8dcSSimon Schubert 		(info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
30265796c8dcSSimon Schubert 		 tls_sec, 0, NULL, FALSE,
30275796c8dcSSimon Schubert 		 bed->collect, &bh)))
30285796c8dcSSimon Schubert 	    return FALSE;
30295796c8dcSSimon Schubert 
3030cf7f2e2dSJohn Marino 	  htab->tls_module_base = bh;
30315796c8dcSSimon Schubert 
30325796c8dcSSimon Schubert 	  tlsbase = (struct elf_link_hash_entry *)bh;
30335796c8dcSSimon Schubert 	  tlsbase->def_regular = 1;
30345796c8dcSSimon Schubert 	  tlsbase->other = STV_HIDDEN;
30355796c8dcSSimon Schubert 	  (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
30365796c8dcSSimon Schubert 	}
30375796c8dcSSimon Schubert     }
30385796c8dcSSimon Schubert 
30395796c8dcSSimon Schubert   return TRUE;
30405796c8dcSSimon Schubert }
30415796c8dcSSimon Schubert 
30425796c8dcSSimon Schubert /* Set the correct type for an x86 ELF section.  We do this by the
30435796c8dcSSimon Schubert    section name, which is a hack, but ought to work.  */
30445796c8dcSSimon Schubert 
30455796c8dcSSimon Schubert static bfd_boolean
elf_i386_fake_sections(bfd * abfd ATTRIBUTE_UNUSED,Elf_Internal_Shdr * hdr,asection * sec)30465796c8dcSSimon Schubert elf_i386_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
30475796c8dcSSimon Schubert 			Elf_Internal_Shdr *hdr,
30485796c8dcSSimon Schubert 			asection *sec)
30495796c8dcSSimon Schubert {
3050cf7f2e2dSJohn Marino   const char *name;
30515796c8dcSSimon Schubert 
30525796c8dcSSimon Schubert   name = bfd_get_section_name (abfd, sec);
30535796c8dcSSimon Schubert 
30545796c8dcSSimon Schubert   /* This is an ugly, but unfortunately necessary hack that is
30555796c8dcSSimon Schubert      needed when producing EFI binaries on x86. It tells
30565796c8dcSSimon Schubert      elf.c:elf_fake_sections() not to consider ".reloc" as a section
30575796c8dcSSimon Schubert      containing ELF relocation info.  We need this hack in order to
30585796c8dcSSimon Schubert      be able to generate ELF binaries that can be translated into
30595796c8dcSSimon Schubert      EFI applications (which are essentially COFF objects).  Those
30605796c8dcSSimon Schubert      files contain a COFF ".reloc" section inside an ELFNN object,
30615796c8dcSSimon Schubert      which would normally cause BFD to segfault because it would
30625796c8dcSSimon Schubert      attempt to interpret this section as containing relocation
30635796c8dcSSimon Schubert      entries for section "oc".  With this hack enabled, ".reloc"
30645796c8dcSSimon Schubert      will be treated as a normal data section, which will avoid the
30655796c8dcSSimon Schubert      segfault.  However, you won't be able to create an ELFNN binary
30665796c8dcSSimon Schubert      with a section named "oc" that needs relocations, but that's
30675796c8dcSSimon Schubert      the kind of ugly side-effects you get when detecting section
30685796c8dcSSimon Schubert      types based on their names...  In practice, this limitation is
30695796c8dcSSimon Schubert      unlikely to bite.  */
30705796c8dcSSimon Schubert   if (strcmp (name, ".reloc") == 0)
30715796c8dcSSimon Schubert     hdr->sh_type = SHT_PROGBITS;
30725796c8dcSSimon Schubert 
30735796c8dcSSimon Schubert   return TRUE;
30745796c8dcSSimon Schubert }
30755796c8dcSSimon Schubert 
30765796c8dcSSimon Schubert /* _TLS_MODULE_BASE_ needs to be treated especially when linking
30775796c8dcSSimon Schubert    executables.  Rather than setting it to the beginning of the TLS
30785796c8dcSSimon Schubert    section, we have to set it to the end.    This function may be called
30795796c8dcSSimon Schubert    multiple times, it is idempotent.  */
30805796c8dcSSimon Schubert 
30815796c8dcSSimon Schubert static void
elf_i386_set_tls_module_base(struct bfd_link_info * info)30825796c8dcSSimon Schubert elf_i386_set_tls_module_base (struct bfd_link_info *info)
30835796c8dcSSimon Schubert {
3084cf7f2e2dSJohn Marino   struct elf_i386_link_hash_table *htab;
30855796c8dcSSimon Schubert   struct bfd_link_hash_entry *base;
30865796c8dcSSimon Schubert 
30875796c8dcSSimon Schubert   if (!info->executable)
30885796c8dcSSimon Schubert     return;
30895796c8dcSSimon Schubert 
3090cf7f2e2dSJohn Marino   htab = elf_i386_hash_table (info);
3091cf7f2e2dSJohn Marino   if (htab == NULL)
30925796c8dcSSimon Schubert     return;
30935796c8dcSSimon Schubert 
3094cf7f2e2dSJohn Marino   base = htab->tls_module_base;
3095cf7f2e2dSJohn Marino   if (base == NULL)
3096cf7f2e2dSJohn Marino     return;
3097cf7f2e2dSJohn Marino 
3098cf7f2e2dSJohn Marino   base->u.def.value = htab->elf.tls_size;
30995796c8dcSSimon Schubert }
31005796c8dcSSimon Schubert 
31015796c8dcSSimon Schubert /* Return the base VMA address which should be subtracted from real addresses
31025796c8dcSSimon Schubert    when resolving @dtpoff relocation.
31035796c8dcSSimon Schubert    This is PT_TLS segment p_vaddr.  */
31045796c8dcSSimon Schubert 
31055796c8dcSSimon Schubert static bfd_vma
elf_i386_dtpoff_base(struct bfd_link_info * info)31065796c8dcSSimon Schubert elf_i386_dtpoff_base (struct bfd_link_info *info)
31075796c8dcSSimon Schubert {
31085796c8dcSSimon Schubert   /* If tls_sec is NULL, we should have signalled an error already.  */
31095796c8dcSSimon Schubert   if (elf_hash_table (info)->tls_sec == NULL)
31105796c8dcSSimon Schubert     return 0;
31115796c8dcSSimon Schubert   return elf_hash_table (info)->tls_sec->vma;
31125796c8dcSSimon Schubert }
31135796c8dcSSimon Schubert 
31145796c8dcSSimon Schubert /* Return the relocation value for @tpoff relocation
31155796c8dcSSimon Schubert    if STT_TLS virtual address is ADDRESS.  */
31165796c8dcSSimon Schubert 
31175796c8dcSSimon Schubert static bfd_vma
elf_i386_tpoff(struct bfd_link_info * info,bfd_vma address)31185796c8dcSSimon Schubert elf_i386_tpoff (struct bfd_link_info *info, bfd_vma address)
31195796c8dcSSimon Schubert {
31205796c8dcSSimon Schubert   struct elf_link_hash_table *htab = elf_hash_table (info);
3121c50c785cSJohn Marino   const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
3122c50c785cSJohn Marino   bfd_vma static_tls_size;
31235796c8dcSSimon Schubert 
31245796c8dcSSimon Schubert   /* If tls_sec is NULL, we should have signalled an error already.  */
31255796c8dcSSimon Schubert   if (htab->tls_sec == NULL)
31265796c8dcSSimon Schubert     return 0;
3127c50c785cSJohn Marino 
3128c50c785cSJohn Marino   /* Consider special static TLS alignment requirements.  */
3129c50c785cSJohn Marino   static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment);
3130c50c785cSJohn Marino   return static_tls_size + htab->tls_sec->vma - address;
31315796c8dcSSimon Schubert }
31325796c8dcSSimon Schubert 
31335796c8dcSSimon Schubert /* Relocate an i386 ELF section.  */
31345796c8dcSSimon Schubert 
31355796c8dcSSimon Schubert static bfd_boolean
elf_i386_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)31365796c8dcSSimon Schubert elf_i386_relocate_section (bfd *output_bfd,
31375796c8dcSSimon Schubert 			   struct bfd_link_info *info,
31385796c8dcSSimon Schubert 			   bfd *input_bfd,
31395796c8dcSSimon Schubert 			   asection *input_section,
31405796c8dcSSimon Schubert 			   bfd_byte *contents,
31415796c8dcSSimon Schubert 			   Elf_Internal_Rela *relocs,
31425796c8dcSSimon Schubert 			   Elf_Internal_Sym *local_syms,
31435796c8dcSSimon Schubert 			   asection **local_sections)
31445796c8dcSSimon Schubert {
31455796c8dcSSimon Schubert   struct elf_i386_link_hash_table *htab;
31465796c8dcSSimon Schubert   Elf_Internal_Shdr *symtab_hdr;
31475796c8dcSSimon Schubert   struct elf_link_hash_entry **sym_hashes;
31485796c8dcSSimon Schubert   bfd_vma *local_got_offsets;
31495796c8dcSSimon Schubert   bfd_vma *local_tlsdesc_gotents;
31505796c8dcSSimon Schubert   Elf_Internal_Rela *rel;
31515796c8dcSSimon Schubert   Elf_Internal_Rela *relend;
31525796c8dcSSimon Schubert   bfd_boolean is_vxworks_tls;
3153a45ae5f8SJohn Marino   unsigned plt_entry_size;
31545796c8dcSSimon Schubert 
31555796c8dcSSimon Schubert   BFD_ASSERT (is_i386_elf (input_bfd));
31565796c8dcSSimon Schubert 
31575796c8dcSSimon Schubert   htab = elf_i386_hash_table (info);
3158cf7f2e2dSJohn Marino   if (htab == NULL)
3159cf7f2e2dSJohn Marino     return FALSE;
31605796c8dcSSimon Schubert   symtab_hdr = &elf_symtab_hdr (input_bfd);
31615796c8dcSSimon Schubert   sym_hashes = elf_sym_hashes (input_bfd);
31625796c8dcSSimon Schubert   local_got_offsets = elf_local_got_offsets (input_bfd);
31635796c8dcSSimon Schubert   local_tlsdesc_gotents = elf_i386_local_tlsdesc_gotent (input_bfd);
31645796c8dcSSimon Schubert   /* We have to handle relocations in vxworks .tls_vars sections
31655796c8dcSSimon Schubert      specially, because the dynamic loader is 'weird'.  */
3166a45ae5f8SJohn Marino   is_vxworks_tls = (get_elf_i386_backend_data (output_bfd)->is_vxworks
3167a45ae5f8SJohn Marino                     && info->shared
31685796c8dcSSimon Schubert 		    && !strcmp (input_section->output_section->name,
31695796c8dcSSimon Schubert 				".tls_vars"));
31705796c8dcSSimon Schubert 
31715796c8dcSSimon Schubert   elf_i386_set_tls_module_base (info);
31725796c8dcSSimon Schubert 
3173a45ae5f8SJohn Marino   plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd);
3174a45ae5f8SJohn Marino 
31755796c8dcSSimon Schubert   rel = relocs;
31765796c8dcSSimon Schubert   relend = relocs + input_section->reloc_count;
31775796c8dcSSimon Schubert   for (; rel < relend; rel++)
31785796c8dcSSimon Schubert     {
31795796c8dcSSimon Schubert       unsigned int r_type;
31805796c8dcSSimon Schubert       reloc_howto_type *howto;
31815796c8dcSSimon Schubert       unsigned long r_symndx;
31825796c8dcSSimon Schubert       struct elf_link_hash_entry *h;
31835796c8dcSSimon Schubert       Elf_Internal_Sym *sym;
31845796c8dcSSimon Schubert       asection *sec;
31855796c8dcSSimon Schubert       bfd_vma off, offplt;
31865796c8dcSSimon Schubert       bfd_vma relocation;
31875796c8dcSSimon Schubert       bfd_boolean unresolved_reloc;
31885796c8dcSSimon Schubert       bfd_reloc_status_type r;
31895796c8dcSSimon Schubert       unsigned int indx;
31905796c8dcSSimon Schubert       int tls_type;
3191*ef5ccd6cSJohn Marino       bfd_vma st_size;
31925796c8dcSSimon Schubert 
31935796c8dcSSimon Schubert       r_type = ELF32_R_TYPE (rel->r_info);
31945796c8dcSSimon Schubert       if (r_type == R_386_GNU_VTINHERIT
31955796c8dcSSimon Schubert 	  || r_type == R_386_GNU_VTENTRY)
31965796c8dcSSimon Schubert 	continue;
31975796c8dcSSimon Schubert 
31985796c8dcSSimon Schubert       if ((indx = r_type) >= R_386_standard
31995796c8dcSSimon Schubert 	  && ((indx = r_type - R_386_ext_offset) - R_386_standard
32005796c8dcSSimon Schubert 	      >= R_386_ext - R_386_standard)
32015796c8dcSSimon Schubert 	  && ((indx = r_type - R_386_tls_offset) - R_386_ext
32025796c8dcSSimon Schubert 	      >= R_386_irelative - R_386_ext))
32035796c8dcSSimon Schubert 	{
32045796c8dcSSimon Schubert 	  (*_bfd_error_handler)
32055796c8dcSSimon Schubert 	    (_("%B: unrecognized relocation (0x%x) in section `%A'"),
32065796c8dcSSimon Schubert 	     input_bfd, input_section, r_type);
32075796c8dcSSimon Schubert 	  bfd_set_error (bfd_error_bad_value);
32085796c8dcSSimon Schubert 	  return FALSE;
32095796c8dcSSimon Schubert 	}
32105796c8dcSSimon Schubert       howto = elf_howto_table + indx;
32115796c8dcSSimon Schubert 
32125796c8dcSSimon Schubert       r_symndx = ELF32_R_SYM (rel->r_info);
32135796c8dcSSimon Schubert       h = NULL;
32145796c8dcSSimon Schubert       sym = NULL;
32155796c8dcSSimon Schubert       sec = NULL;
32165796c8dcSSimon Schubert       unresolved_reloc = FALSE;
32175796c8dcSSimon Schubert       if (r_symndx < symtab_hdr->sh_info)
32185796c8dcSSimon Schubert 	{
32195796c8dcSSimon Schubert 	  sym = local_syms + r_symndx;
32205796c8dcSSimon Schubert 	  sec = local_sections[r_symndx];
32215796c8dcSSimon Schubert 	  relocation = (sec->output_section->vma
32225796c8dcSSimon Schubert 			+ sec->output_offset
32235796c8dcSSimon Schubert 			+ sym->st_value);
3224*ef5ccd6cSJohn Marino 	  st_size = sym->st_size;
32255796c8dcSSimon Schubert 
32265796c8dcSSimon Schubert 	  if (ELF_ST_TYPE (sym->st_info) == STT_SECTION
32275796c8dcSSimon Schubert 	      && ((sec->flags & SEC_MERGE) != 0
32285796c8dcSSimon Schubert 		  || (info->relocatable
32295796c8dcSSimon Schubert 		      && sec->output_offset != 0)))
32305796c8dcSSimon Schubert 	    {
32315796c8dcSSimon Schubert 	      bfd_vma addend;
32325796c8dcSSimon Schubert 	      bfd_byte *where = contents + rel->r_offset;
32335796c8dcSSimon Schubert 
32345796c8dcSSimon Schubert 	      switch (howto->size)
32355796c8dcSSimon Schubert 		{
32365796c8dcSSimon Schubert 		case 0:
32375796c8dcSSimon Schubert 		  addend = bfd_get_8 (input_bfd, where);
32385796c8dcSSimon Schubert 		  if (howto->pc_relative)
32395796c8dcSSimon Schubert 		    {
32405796c8dcSSimon Schubert 		      addend = (addend ^ 0x80) - 0x80;
32415796c8dcSSimon Schubert 		      addend += 1;
32425796c8dcSSimon Schubert 		    }
32435796c8dcSSimon Schubert 		  break;
32445796c8dcSSimon Schubert 		case 1:
32455796c8dcSSimon Schubert 		  addend = bfd_get_16 (input_bfd, where);
32465796c8dcSSimon Schubert 		  if (howto->pc_relative)
32475796c8dcSSimon Schubert 		    {
32485796c8dcSSimon Schubert 		      addend = (addend ^ 0x8000) - 0x8000;
32495796c8dcSSimon Schubert 		      addend += 2;
32505796c8dcSSimon Schubert 		    }
32515796c8dcSSimon Schubert 		  break;
32525796c8dcSSimon Schubert 		case 2:
32535796c8dcSSimon Schubert 		  addend = bfd_get_32 (input_bfd, where);
32545796c8dcSSimon Schubert 		  if (howto->pc_relative)
32555796c8dcSSimon Schubert 		    {
32565796c8dcSSimon Schubert 		      addend = (addend ^ 0x80000000) - 0x80000000;
32575796c8dcSSimon Schubert 		      addend += 4;
32585796c8dcSSimon Schubert 		    }
32595796c8dcSSimon Schubert 		  break;
32605796c8dcSSimon Schubert 		default:
32615796c8dcSSimon Schubert 		  abort ();
32625796c8dcSSimon Schubert 		}
32635796c8dcSSimon Schubert 
32645796c8dcSSimon Schubert 	      if (info->relocatable)
32655796c8dcSSimon Schubert 		addend += sec->output_offset;
32665796c8dcSSimon Schubert 	      else
32675796c8dcSSimon Schubert 		{
32685796c8dcSSimon Schubert 		  asection *msec = sec;
32695796c8dcSSimon Schubert 		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec,
32705796c8dcSSimon Schubert 						   addend);
32715796c8dcSSimon Schubert 		  addend -= relocation;
32725796c8dcSSimon Schubert 		  addend += msec->output_section->vma + msec->output_offset;
32735796c8dcSSimon Schubert 		}
32745796c8dcSSimon Schubert 
32755796c8dcSSimon Schubert 	      switch (howto->size)
32765796c8dcSSimon Schubert 		{
32775796c8dcSSimon Schubert 		case 0:
32785796c8dcSSimon Schubert 		  /* FIXME: overflow checks.  */
32795796c8dcSSimon Schubert 		  if (howto->pc_relative)
32805796c8dcSSimon Schubert 		    addend -= 1;
32815796c8dcSSimon Schubert 		  bfd_put_8 (input_bfd, addend, where);
32825796c8dcSSimon Schubert 		  break;
32835796c8dcSSimon Schubert 		case 1:
32845796c8dcSSimon Schubert 		  if (howto->pc_relative)
32855796c8dcSSimon Schubert 		    addend -= 2;
32865796c8dcSSimon Schubert 		  bfd_put_16 (input_bfd, addend, where);
32875796c8dcSSimon Schubert 		  break;
32885796c8dcSSimon Schubert 		case 2:
32895796c8dcSSimon Schubert 		  if (howto->pc_relative)
32905796c8dcSSimon Schubert 		    addend -= 4;
32915796c8dcSSimon Schubert 		  bfd_put_32 (input_bfd, addend, where);
32925796c8dcSSimon Schubert 		  break;
32935796c8dcSSimon Schubert 		}
32945796c8dcSSimon Schubert 	    }
32955796c8dcSSimon Schubert 	  else if (!info->relocatable
32965796c8dcSSimon Schubert 		   && ELF32_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
32975796c8dcSSimon Schubert 	    {
32985796c8dcSSimon Schubert 	      /* Relocate against local STT_GNU_IFUNC symbol.  */
3299c50c785cSJohn Marino 	      h = elf_i386_get_local_sym_hash (htab, input_bfd, rel,
3300c50c785cSJohn Marino 					       FALSE);
33015796c8dcSSimon Schubert 	      if (h == NULL)
33025796c8dcSSimon Schubert 		abort ();
33035796c8dcSSimon Schubert 
33045796c8dcSSimon Schubert 	      /* Set STT_GNU_IFUNC symbol value.  */
33055796c8dcSSimon Schubert 	      h->root.u.def.value = sym->st_value;
33065796c8dcSSimon Schubert 	      h->root.u.def.section = sec;
33075796c8dcSSimon Schubert 	    }
33085796c8dcSSimon Schubert 	}
33095796c8dcSSimon Schubert       else
33105796c8dcSSimon Schubert 	{
3311cf7f2e2dSJohn Marino 	  bfd_boolean warned ATTRIBUTE_UNUSED;
33125796c8dcSSimon Schubert 
33135796c8dcSSimon Schubert 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
33145796c8dcSSimon Schubert 				   r_symndx, symtab_hdr, sym_hashes,
33155796c8dcSSimon Schubert 				   h, sec, relocation,
33165796c8dcSSimon Schubert 				   unresolved_reloc, warned);
3317*ef5ccd6cSJohn Marino 	  st_size = h->size;
33185796c8dcSSimon Schubert 	}
33195796c8dcSSimon Schubert 
3320*ef5ccd6cSJohn Marino       if (sec != NULL && discarded_section (sec))
3321cf7f2e2dSJohn Marino 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
3322*ef5ccd6cSJohn Marino 					 rel, 1, relend, howto, 0, contents);
33235796c8dcSSimon Schubert 
33245796c8dcSSimon Schubert       if (info->relocatable)
33255796c8dcSSimon Schubert 	continue;
33265796c8dcSSimon Schubert 
33275796c8dcSSimon Schubert       /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
33285796c8dcSSimon Schubert 	 it here if it is defined in a non-shared object.  */
33295796c8dcSSimon Schubert       if (h != NULL
33305796c8dcSSimon Schubert 	  && h->type == STT_GNU_IFUNC
33315796c8dcSSimon Schubert 	  && h->def_regular)
33325796c8dcSSimon Schubert 	{
33335796c8dcSSimon Schubert 	  asection *plt, *gotplt, *base_got;
33345796c8dcSSimon Schubert 	  bfd_vma plt_index;
33355796c8dcSSimon Schubert 	  const char *name;
33365796c8dcSSimon Schubert 
33375796c8dcSSimon Schubert 	  if ((input_section->flags & SEC_ALLOC) == 0
33385796c8dcSSimon Schubert 	      || h->plt.offset == (bfd_vma) -1)
33395796c8dcSSimon Schubert 	    abort ();
33405796c8dcSSimon Schubert 
33415796c8dcSSimon Schubert 	  /* STT_GNU_IFUNC symbol must go through PLT.  */
33425796c8dcSSimon Schubert 	  if (htab->elf.splt != NULL)
33435796c8dcSSimon Schubert 	    {
33445796c8dcSSimon Schubert 	      plt = htab->elf.splt;
33455796c8dcSSimon Schubert 	      gotplt = htab->elf.sgotplt;
33465796c8dcSSimon Schubert 	    }
33475796c8dcSSimon Schubert 	  else
33485796c8dcSSimon Schubert 	    {
33495796c8dcSSimon Schubert 	      plt = htab->elf.iplt;
33505796c8dcSSimon Schubert 	      gotplt = htab->elf.igotplt;
33515796c8dcSSimon Schubert 	    }
33525796c8dcSSimon Schubert 
33535796c8dcSSimon Schubert 	  relocation = (plt->output_section->vma
33545796c8dcSSimon Schubert 			+ plt->output_offset + h->plt.offset);
33555796c8dcSSimon Schubert 
33565796c8dcSSimon Schubert 	  switch (r_type)
33575796c8dcSSimon Schubert 	    {
33585796c8dcSSimon Schubert 	    default:
33595796c8dcSSimon Schubert 	      if (h->root.root.string)
33605796c8dcSSimon Schubert 		name = h->root.root.string;
33615796c8dcSSimon Schubert 	      else
33625796c8dcSSimon Schubert 		name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
33635796c8dcSSimon Schubert 					 NULL);
33645796c8dcSSimon Schubert 	      (*_bfd_error_handler)
33655796c8dcSSimon Schubert 		(_("%B: relocation %s against STT_GNU_IFUNC "
33665796c8dcSSimon Schubert 		   "symbol `%s' isn't handled by %s"), input_bfd,
33675796c8dcSSimon Schubert 		 elf_howto_table[r_type].name,
33685796c8dcSSimon Schubert 		 name, __FUNCTION__);
33695796c8dcSSimon Schubert 	      bfd_set_error (bfd_error_bad_value);
33705796c8dcSSimon Schubert 	      return FALSE;
33715796c8dcSSimon Schubert 
33725796c8dcSSimon Schubert 	    case R_386_32:
33735796c8dcSSimon Schubert 	      /* Generate dynamic relcoation only when there is a
3374a45ae5f8SJohn Marino 		 non-GOT reference in a shared object.  */
33755796c8dcSSimon Schubert 	      if (info->shared && h->non_got_ref)
33765796c8dcSSimon Schubert 		{
33775796c8dcSSimon Schubert 		  Elf_Internal_Rela outrel;
33785796c8dcSSimon Schubert 		  asection *sreloc;
33795796c8dcSSimon Schubert 		  bfd_vma offset;
33805796c8dcSSimon Schubert 
33815796c8dcSSimon Schubert 		  /* Need a dynamic relocation to get the real function
33825796c8dcSSimon Schubert 		     adddress.  */
33835796c8dcSSimon Schubert 		  offset = _bfd_elf_section_offset (output_bfd,
33845796c8dcSSimon Schubert 						    info,
33855796c8dcSSimon Schubert 						    input_section,
33865796c8dcSSimon Schubert 						    rel->r_offset);
33875796c8dcSSimon Schubert 		  if (offset == (bfd_vma) -1
33885796c8dcSSimon Schubert 		      || offset == (bfd_vma) -2)
33895796c8dcSSimon Schubert 		    abort ();
33905796c8dcSSimon Schubert 
33915796c8dcSSimon Schubert 		  outrel.r_offset = (input_section->output_section->vma
33925796c8dcSSimon Schubert 				     + input_section->output_offset
33935796c8dcSSimon Schubert 				     + offset);
33945796c8dcSSimon Schubert 
33955796c8dcSSimon Schubert 		  if (h->dynindx == -1
33965796c8dcSSimon Schubert 		      || h->forced_local
33975796c8dcSSimon Schubert 		      || info->executable)
33985796c8dcSSimon Schubert 		    {
33995796c8dcSSimon Schubert 		      /* This symbol is resolved locally.  */
3400*ef5ccd6cSJohn Marino 		      outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
3401*ef5ccd6cSJohn Marino 		      bfd_put_32 (output_bfd,
3402*ef5ccd6cSJohn Marino 				  (h->root.u.def.value
3403*ef5ccd6cSJohn Marino 				   + h->root.u.def.section->output_section->vma
3404*ef5ccd6cSJohn Marino 				   + h->root.u.def.section->output_offset),
3405*ef5ccd6cSJohn Marino 				  contents + offset);
34065796c8dcSSimon Schubert 		    }
34075796c8dcSSimon Schubert 		  else
34085796c8dcSSimon Schubert 		    outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
34095796c8dcSSimon Schubert 
34105796c8dcSSimon Schubert 		  sreloc = htab->elf.irelifunc;
3411*ef5ccd6cSJohn Marino 		  elf_append_rel (output_bfd, sreloc, &outrel);
34125796c8dcSSimon Schubert 
34135796c8dcSSimon Schubert 		  /* If this reloc is against an external symbol, we
34145796c8dcSSimon Schubert 		     do not want to fiddle with the addend.  Otherwise,
34155796c8dcSSimon Schubert 		     we need to include the symbol value so that it
34165796c8dcSSimon Schubert 		     becomes an addend for the dynamic reloc.  For an
34175796c8dcSSimon Schubert 		     internal symbol, we have updated addend.  */
34185796c8dcSSimon Schubert 		  continue;
34195796c8dcSSimon Schubert 		}
3420c50c785cSJohn Marino 	      /* FALLTHROUGH */
34215796c8dcSSimon Schubert 	    case R_386_PC32:
34225796c8dcSSimon Schubert 	    case R_386_PLT32:
34235796c8dcSSimon Schubert 	      goto do_relocation;
34245796c8dcSSimon Schubert 
34255796c8dcSSimon Schubert 	    case R_386_GOT32:
34265796c8dcSSimon Schubert 	      base_got = htab->elf.sgot;
34275796c8dcSSimon Schubert 	      off = h->got.offset;
34285796c8dcSSimon Schubert 
34295796c8dcSSimon Schubert 	      if (base_got == NULL)
34305796c8dcSSimon Schubert 		abort ();
34315796c8dcSSimon Schubert 
34325796c8dcSSimon Schubert 	      if (off == (bfd_vma) -1)
34335796c8dcSSimon Schubert 		{
34345796c8dcSSimon Schubert 		  /* We can't use h->got.offset here to save state, or
34355796c8dcSSimon Schubert 		     even just remember the offset, as finish_dynamic_symbol
34365796c8dcSSimon Schubert 		     would use that as offset into .got.  */
34375796c8dcSSimon Schubert 
34385796c8dcSSimon Schubert 		  if (htab->elf.splt != NULL)
34395796c8dcSSimon Schubert 		    {
3440a45ae5f8SJohn Marino 		      plt_index = h->plt.offset / plt_entry_size - 1;
34415796c8dcSSimon Schubert 		      off = (plt_index + 3) * 4;
34425796c8dcSSimon Schubert 		      base_got = htab->elf.sgotplt;
34435796c8dcSSimon Schubert 		    }
34445796c8dcSSimon Schubert 		  else
34455796c8dcSSimon Schubert 		    {
3446a45ae5f8SJohn Marino 		      plt_index = h->plt.offset / plt_entry_size;
34475796c8dcSSimon Schubert 		      off = plt_index * 4;
34485796c8dcSSimon Schubert 		      base_got = htab->elf.igotplt;
34495796c8dcSSimon Schubert 		    }
34505796c8dcSSimon Schubert 
34515796c8dcSSimon Schubert 		  if (h->dynindx == -1
34525796c8dcSSimon Schubert 		      || h->forced_local
34535796c8dcSSimon Schubert 		      || info->symbolic)
34545796c8dcSSimon Schubert 		    {
34555796c8dcSSimon Schubert 		      /* This references the local defitionion.  We must
34565796c8dcSSimon Schubert 			 initialize this entry in the global offset table.
34575796c8dcSSimon Schubert 			 Since the offset must always be a multiple of 8,
34585796c8dcSSimon Schubert 			 we use the least significant bit to record
34595796c8dcSSimon Schubert 			 whether we have initialized it already.
34605796c8dcSSimon Schubert 
34615796c8dcSSimon Schubert 			 When doing a dynamic link, we create a .rela.got
34625796c8dcSSimon Schubert 			 relocation entry to initialize the value.  This
34635796c8dcSSimon Schubert 			 is done in the finish_dynamic_symbol routine.	 */
34645796c8dcSSimon Schubert 		      if ((off & 1) != 0)
34655796c8dcSSimon Schubert 			off &= ~1;
34665796c8dcSSimon Schubert 		      else
34675796c8dcSSimon Schubert 			{
34685796c8dcSSimon Schubert 			  bfd_put_32 (output_bfd, relocation,
34695796c8dcSSimon Schubert 				      base_got->contents + off);
34705796c8dcSSimon Schubert 			  h->got.offset |= 1;
34715796c8dcSSimon Schubert 			}
34725796c8dcSSimon Schubert 		    }
34735796c8dcSSimon Schubert 
34745796c8dcSSimon Schubert 		  relocation = off;
34755796c8dcSSimon Schubert 
34765796c8dcSSimon Schubert 		  /* Adjust for static executables.  */
34775796c8dcSSimon Schubert 		  if (htab->elf.splt == NULL)
34785796c8dcSSimon Schubert 		    relocation += gotplt->output_offset;
34795796c8dcSSimon Schubert 		}
34805796c8dcSSimon Schubert 	      else
34815796c8dcSSimon Schubert 		{
34825796c8dcSSimon Schubert 		  relocation = (base_got->output_section->vma
34835796c8dcSSimon Schubert 				+ base_got->output_offset + off
34845796c8dcSSimon Schubert 				- gotplt->output_section->vma
34855796c8dcSSimon Schubert 				- gotplt->output_offset);
34865796c8dcSSimon Schubert 		  /* Adjust for static executables.  */
34875796c8dcSSimon Schubert 		  if (htab->elf.splt == NULL)
34885796c8dcSSimon Schubert 		    relocation += gotplt->output_offset;
34895796c8dcSSimon Schubert 		}
34905796c8dcSSimon Schubert 
34915796c8dcSSimon Schubert 	      goto do_relocation;
34925796c8dcSSimon Schubert 
34935796c8dcSSimon Schubert 	    case R_386_GOTOFF:
34945796c8dcSSimon Schubert 	      relocation -= (gotplt->output_section->vma
34955796c8dcSSimon Schubert 			     + gotplt->output_offset);
34965796c8dcSSimon Schubert 	      goto do_relocation;
34975796c8dcSSimon Schubert 	    }
34985796c8dcSSimon Schubert 	}
34995796c8dcSSimon Schubert 
35005796c8dcSSimon Schubert       switch (r_type)
35015796c8dcSSimon Schubert 	{
35025796c8dcSSimon Schubert 	case R_386_GOT32:
35035796c8dcSSimon Schubert 	  /* Relocation is to the entry for this symbol in the global
35045796c8dcSSimon Schubert 	     offset table.  */
35055796c8dcSSimon Schubert 	  if (htab->elf.sgot == NULL)
35065796c8dcSSimon Schubert 	    abort ();
35075796c8dcSSimon Schubert 
35085796c8dcSSimon Schubert 	  if (h != NULL)
35095796c8dcSSimon Schubert 	    {
35105796c8dcSSimon Schubert 	      bfd_boolean dyn;
35115796c8dcSSimon Schubert 
35125796c8dcSSimon Schubert 	      off = h->got.offset;
35135796c8dcSSimon Schubert 	      dyn = htab->elf.dynamic_sections_created;
35145796c8dcSSimon Schubert 	      if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
35155796c8dcSSimon Schubert 		  || (info->shared
35165796c8dcSSimon Schubert 		      && SYMBOL_REFERENCES_LOCAL (info, h))
35175796c8dcSSimon Schubert 		  || (ELF_ST_VISIBILITY (h->other)
35185796c8dcSSimon Schubert 		      && h->root.type == bfd_link_hash_undefweak))
35195796c8dcSSimon Schubert 		{
35205796c8dcSSimon Schubert 		  /* This is actually a static link, or it is a
35215796c8dcSSimon Schubert 		     -Bsymbolic link and the symbol is defined
35225796c8dcSSimon Schubert 		     locally, or the symbol was forced to be local
35235796c8dcSSimon Schubert 		     because of a version file.  We must initialize
35245796c8dcSSimon Schubert 		     this entry in the global offset table.  Since the
35255796c8dcSSimon Schubert 		     offset must always be a multiple of 4, we use the
35265796c8dcSSimon Schubert 		     least significant bit to record whether we have
35275796c8dcSSimon Schubert 		     initialized it already.
35285796c8dcSSimon Schubert 
35295796c8dcSSimon Schubert 		     When doing a dynamic link, we create a .rel.got
35305796c8dcSSimon Schubert 		     relocation entry to initialize the value.  This
35315796c8dcSSimon Schubert 		     is done in the finish_dynamic_symbol routine.  */
35325796c8dcSSimon Schubert 		  if ((off & 1) != 0)
35335796c8dcSSimon Schubert 		    off &= ~1;
35345796c8dcSSimon Schubert 		  else
35355796c8dcSSimon Schubert 		    {
35365796c8dcSSimon Schubert 		      bfd_put_32 (output_bfd, relocation,
35375796c8dcSSimon Schubert 				  htab->elf.sgot->contents + off);
35385796c8dcSSimon Schubert 		      h->got.offset |= 1;
35395796c8dcSSimon Schubert 		    }
35405796c8dcSSimon Schubert 		}
35415796c8dcSSimon Schubert 	      else
35425796c8dcSSimon Schubert 		unresolved_reloc = FALSE;
35435796c8dcSSimon Schubert 	    }
35445796c8dcSSimon Schubert 	  else
35455796c8dcSSimon Schubert 	    {
35465796c8dcSSimon Schubert 	      if (local_got_offsets == NULL)
35475796c8dcSSimon Schubert 		abort ();
35485796c8dcSSimon Schubert 
35495796c8dcSSimon Schubert 	      off = local_got_offsets[r_symndx];
35505796c8dcSSimon Schubert 
35515796c8dcSSimon Schubert 	      /* The offset must always be a multiple of 4.  We use
35525796c8dcSSimon Schubert 		 the least significant bit to record whether we have
35535796c8dcSSimon Schubert 		 already generated the necessary reloc.  */
35545796c8dcSSimon Schubert 	      if ((off & 1) != 0)
35555796c8dcSSimon Schubert 		off &= ~1;
35565796c8dcSSimon Schubert 	      else
35575796c8dcSSimon Schubert 		{
35585796c8dcSSimon Schubert 		  bfd_put_32 (output_bfd, relocation,
35595796c8dcSSimon Schubert 			      htab->elf.sgot->contents + off);
35605796c8dcSSimon Schubert 
35615796c8dcSSimon Schubert 		  if (info->shared)
35625796c8dcSSimon Schubert 		    {
35635796c8dcSSimon Schubert 		      asection *s;
35645796c8dcSSimon Schubert 		      Elf_Internal_Rela outrel;
35655796c8dcSSimon Schubert 
35665796c8dcSSimon Schubert 		      s = htab->elf.srelgot;
35675796c8dcSSimon Schubert 		      if (s == NULL)
35685796c8dcSSimon Schubert 			abort ();
35695796c8dcSSimon Schubert 
35705796c8dcSSimon Schubert 		      outrel.r_offset = (htab->elf.sgot->output_section->vma
35715796c8dcSSimon Schubert 					 + htab->elf.sgot->output_offset
35725796c8dcSSimon Schubert 					 + off);
35735796c8dcSSimon Schubert 		      outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
3574*ef5ccd6cSJohn Marino 		      elf_append_rel (output_bfd, s, &outrel);
35755796c8dcSSimon Schubert 		    }
35765796c8dcSSimon Schubert 
35775796c8dcSSimon Schubert 		  local_got_offsets[r_symndx] |= 1;
35785796c8dcSSimon Schubert 		}
35795796c8dcSSimon Schubert 	    }
35805796c8dcSSimon Schubert 
35815796c8dcSSimon Schubert 	  if (off >= (bfd_vma) -2)
35825796c8dcSSimon Schubert 	    abort ();
35835796c8dcSSimon Schubert 
35845796c8dcSSimon Schubert 	  relocation = htab->elf.sgot->output_section->vma
35855796c8dcSSimon Schubert 		       + htab->elf.sgot->output_offset + off
35865796c8dcSSimon Schubert 		       - htab->elf.sgotplt->output_section->vma
35875796c8dcSSimon Schubert 		       - htab->elf.sgotplt->output_offset;
35885796c8dcSSimon Schubert 	  break;
35895796c8dcSSimon Schubert 
35905796c8dcSSimon Schubert 	case R_386_GOTOFF:
35915796c8dcSSimon Schubert 	  /* Relocation is relative to the start of the global offset
35925796c8dcSSimon Schubert 	     table.  */
35935796c8dcSSimon Schubert 
35945796c8dcSSimon Schubert 	  /* Check to make sure it isn't a protected function symbol
35955796c8dcSSimon Schubert 	     for shared library since it may not be local when used
35965796c8dcSSimon Schubert 	     as function address.  We also need to make sure that a
35975796c8dcSSimon Schubert 	     symbol is defined locally.  */
35985796c8dcSSimon Schubert 	  if (info->shared && h)
35995796c8dcSSimon Schubert 	    {
36005796c8dcSSimon Schubert 	      if (!h->def_regular)
36015796c8dcSSimon Schubert 		{
36025796c8dcSSimon Schubert 		  const char *v;
36035796c8dcSSimon Schubert 
36045796c8dcSSimon Schubert 		  switch (ELF_ST_VISIBILITY (h->other))
36055796c8dcSSimon Schubert 		    {
36065796c8dcSSimon Schubert 		    case STV_HIDDEN:
36075796c8dcSSimon Schubert 		      v = _("hidden symbol");
36085796c8dcSSimon Schubert 		      break;
36095796c8dcSSimon Schubert 		    case STV_INTERNAL:
36105796c8dcSSimon Schubert 		      v = _("internal symbol");
36115796c8dcSSimon Schubert 		      break;
36125796c8dcSSimon Schubert 		    case STV_PROTECTED:
36135796c8dcSSimon Schubert 		      v = _("protected symbol");
36145796c8dcSSimon Schubert 		      break;
36155796c8dcSSimon Schubert 		    default:
36165796c8dcSSimon Schubert 		      v = _("symbol");
36175796c8dcSSimon Schubert 		      break;
36185796c8dcSSimon Schubert 		    }
36195796c8dcSSimon Schubert 
36205796c8dcSSimon Schubert 		  (*_bfd_error_handler)
36215796c8dcSSimon Schubert 		    (_("%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"),
36225796c8dcSSimon Schubert 		     input_bfd, v, h->root.root.string);
36235796c8dcSSimon Schubert 		  bfd_set_error (bfd_error_bad_value);
36245796c8dcSSimon Schubert 		  return FALSE;
36255796c8dcSSimon Schubert 		}
36265796c8dcSSimon Schubert 	      else if (!info->executable
3627*ef5ccd6cSJohn Marino 		       && !SYMBOLIC_BIND (info, h)
36285796c8dcSSimon Schubert 		       && h->type == STT_FUNC
36295796c8dcSSimon Schubert 		       && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
36305796c8dcSSimon Schubert 		{
36315796c8dcSSimon Schubert 		  (*_bfd_error_handler)
36325796c8dcSSimon Schubert 		    (_("%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"),
36335796c8dcSSimon Schubert 		     input_bfd, h->root.root.string);
36345796c8dcSSimon Schubert 		  bfd_set_error (bfd_error_bad_value);
36355796c8dcSSimon Schubert 		  return FALSE;
36365796c8dcSSimon Schubert 		}
36375796c8dcSSimon Schubert 	    }
36385796c8dcSSimon Schubert 
36395796c8dcSSimon Schubert 	  /* Note that sgot is not involved in this
36405796c8dcSSimon Schubert 	     calculation.  We always want the start of .got.plt.  If we
36415796c8dcSSimon Schubert 	     defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
36425796c8dcSSimon Schubert 	     permitted by the ABI, we might have to change this
36435796c8dcSSimon Schubert 	     calculation.  */
36445796c8dcSSimon Schubert 	  relocation -= htab->elf.sgotplt->output_section->vma
36455796c8dcSSimon Schubert 			+ htab->elf.sgotplt->output_offset;
36465796c8dcSSimon Schubert 	  break;
36475796c8dcSSimon Schubert 
36485796c8dcSSimon Schubert 	case R_386_GOTPC:
36495796c8dcSSimon Schubert 	  /* Use global offset table as symbol value.  */
36505796c8dcSSimon Schubert 	  relocation = htab->elf.sgotplt->output_section->vma
36515796c8dcSSimon Schubert 		       + htab->elf.sgotplt->output_offset;
36525796c8dcSSimon Schubert 	  unresolved_reloc = FALSE;
36535796c8dcSSimon Schubert 	  break;
36545796c8dcSSimon Schubert 
36555796c8dcSSimon Schubert 	case R_386_PLT32:
36565796c8dcSSimon Schubert 	  /* Relocation is to the entry for this symbol in the
36575796c8dcSSimon Schubert 	     procedure linkage table.  */
36585796c8dcSSimon Schubert 
36595796c8dcSSimon Schubert 	  /* Resolve a PLT32 reloc against a local symbol directly,
36605796c8dcSSimon Schubert 	     without using the procedure linkage table.  */
36615796c8dcSSimon Schubert 	  if (h == NULL)
36625796c8dcSSimon Schubert 	    break;
36635796c8dcSSimon Schubert 
36645796c8dcSSimon Schubert 	  if (h->plt.offset == (bfd_vma) -1
36655796c8dcSSimon Schubert 	      || htab->elf.splt == NULL)
36665796c8dcSSimon Schubert 	    {
36675796c8dcSSimon Schubert 	      /* We didn't make a PLT entry for this symbol.  This
36685796c8dcSSimon Schubert 		 happens when statically linking PIC code, or when
36695796c8dcSSimon Schubert 		 using -Bsymbolic.  */
36705796c8dcSSimon Schubert 	      break;
36715796c8dcSSimon Schubert 	    }
36725796c8dcSSimon Schubert 
36735796c8dcSSimon Schubert 	  relocation = (htab->elf.splt->output_section->vma
36745796c8dcSSimon Schubert 			+ htab->elf.splt->output_offset
36755796c8dcSSimon Schubert 			+ h->plt.offset);
36765796c8dcSSimon Schubert 	  unresolved_reloc = FALSE;
36775796c8dcSSimon Schubert 	  break;
36785796c8dcSSimon Schubert 
3679*ef5ccd6cSJohn Marino 	case R_386_SIZE32:
3680*ef5ccd6cSJohn Marino 	  /* Set to symbol size.  */
3681*ef5ccd6cSJohn Marino 	  relocation = st_size;
3682*ef5ccd6cSJohn Marino 	  /* Fall through.  */
3683*ef5ccd6cSJohn Marino 
36845796c8dcSSimon Schubert 	case R_386_32:
36855796c8dcSSimon Schubert 	case R_386_PC32:
36865796c8dcSSimon Schubert 	  if ((input_section->flags & SEC_ALLOC) == 0
36875796c8dcSSimon Schubert 	      || is_vxworks_tls)
36885796c8dcSSimon Schubert 	    break;
36895796c8dcSSimon Schubert 
36905796c8dcSSimon Schubert 	  if ((info->shared
36915796c8dcSSimon Schubert 	       && (h == NULL
36925796c8dcSSimon Schubert 		   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
36935796c8dcSSimon Schubert 		   || h->root.type != bfd_link_hash_undefweak)
3694*ef5ccd6cSJohn Marino 	       && ((r_type != R_386_PC32 && r_type != R_386_SIZE32)
36955796c8dcSSimon Schubert 		   || !SYMBOL_CALLS_LOCAL (info, h)))
36965796c8dcSSimon Schubert 	      || (ELIMINATE_COPY_RELOCS
36975796c8dcSSimon Schubert 		  && !info->shared
36985796c8dcSSimon Schubert 		  && h != NULL
36995796c8dcSSimon Schubert 		  && h->dynindx != -1
37005796c8dcSSimon Schubert 		  && !h->non_got_ref
37015796c8dcSSimon Schubert 		  && ((h->def_dynamic
37025796c8dcSSimon Schubert 		       && !h->def_regular)
37035796c8dcSSimon Schubert 		      || h->root.type == bfd_link_hash_undefweak
37045796c8dcSSimon Schubert 		      || h->root.type == bfd_link_hash_undefined)))
37055796c8dcSSimon Schubert 	    {
37065796c8dcSSimon Schubert 	      Elf_Internal_Rela outrel;
37075796c8dcSSimon Schubert 	      bfd_boolean skip, relocate;
37085796c8dcSSimon Schubert 	      asection *sreloc;
37095796c8dcSSimon Schubert 
37105796c8dcSSimon Schubert 	      /* When generating a shared object, these relocations
37115796c8dcSSimon Schubert 		 are copied into the output file to be resolved at run
37125796c8dcSSimon Schubert 		 time.  */
37135796c8dcSSimon Schubert 
37145796c8dcSSimon Schubert 	      skip = FALSE;
37155796c8dcSSimon Schubert 	      relocate = FALSE;
37165796c8dcSSimon Schubert 
37175796c8dcSSimon Schubert 	      outrel.r_offset =
37185796c8dcSSimon Schubert 		_bfd_elf_section_offset (output_bfd, info, input_section,
37195796c8dcSSimon Schubert 					 rel->r_offset);
37205796c8dcSSimon Schubert 	      if (outrel.r_offset == (bfd_vma) -1)
37215796c8dcSSimon Schubert 		skip = TRUE;
37225796c8dcSSimon Schubert 	      else if (outrel.r_offset == (bfd_vma) -2)
37235796c8dcSSimon Schubert 		skip = TRUE, relocate = TRUE;
37245796c8dcSSimon Schubert 	      outrel.r_offset += (input_section->output_section->vma
37255796c8dcSSimon Schubert 				  + input_section->output_offset);
37265796c8dcSSimon Schubert 
37275796c8dcSSimon Schubert 	      if (skip)
37285796c8dcSSimon Schubert 		memset (&outrel, 0, sizeof outrel);
37295796c8dcSSimon Schubert 	      else if (h != NULL
37305796c8dcSSimon Schubert 		       && h->dynindx != -1
37315796c8dcSSimon Schubert 		       && (r_type == R_386_PC32
37325796c8dcSSimon Schubert 			   || !info->shared
37335796c8dcSSimon Schubert 			   || !SYMBOLIC_BIND (info, h)
37345796c8dcSSimon Schubert 			   || !h->def_regular))
37355796c8dcSSimon Schubert 		outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
37365796c8dcSSimon Schubert 	      else
37375796c8dcSSimon Schubert 		{
37385796c8dcSSimon Schubert 		  /* This symbol is local, or marked to become local.  */
37395796c8dcSSimon Schubert 		  relocate = TRUE;
37405796c8dcSSimon Schubert 		  outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
37415796c8dcSSimon Schubert 		}
37425796c8dcSSimon Schubert 
37435796c8dcSSimon Schubert 	      sreloc = elf_section_data (input_section)->sreloc;
37445796c8dcSSimon Schubert 
3745a45ae5f8SJohn Marino 	      if (sreloc == NULL || sreloc->contents == NULL)
3746a45ae5f8SJohn Marino 		{
3747a45ae5f8SJohn Marino 		  r = bfd_reloc_notsupported;
3748a45ae5f8SJohn Marino 		  goto check_relocation_error;
3749a45ae5f8SJohn Marino 		}
37505796c8dcSSimon Schubert 
3751*ef5ccd6cSJohn Marino 	      elf_append_rel (output_bfd, sreloc, &outrel);
37525796c8dcSSimon Schubert 
37535796c8dcSSimon Schubert 	      /* If this reloc is against an external symbol, we do
37545796c8dcSSimon Schubert 		 not want to fiddle with the addend.  Otherwise, we
37555796c8dcSSimon Schubert 		 need to include the symbol value so that it becomes
37565796c8dcSSimon Schubert 		 an addend for the dynamic reloc.  */
37575796c8dcSSimon Schubert 	      if (! relocate)
37585796c8dcSSimon Schubert 		continue;
37595796c8dcSSimon Schubert 	    }
37605796c8dcSSimon Schubert 	  break;
37615796c8dcSSimon Schubert 
37625796c8dcSSimon Schubert 	case R_386_TLS_IE:
37635796c8dcSSimon Schubert 	  if (!info->executable)
37645796c8dcSSimon Schubert 	    {
37655796c8dcSSimon Schubert 	      Elf_Internal_Rela outrel;
37665796c8dcSSimon Schubert 	      asection *sreloc;
37675796c8dcSSimon Schubert 
37685796c8dcSSimon Schubert 	      outrel.r_offset = rel->r_offset
37695796c8dcSSimon Schubert 				+ input_section->output_section->vma
37705796c8dcSSimon Schubert 				+ input_section->output_offset;
37715796c8dcSSimon Schubert 	      outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
37725796c8dcSSimon Schubert 	      sreloc = elf_section_data (input_section)->sreloc;
37735796c8dcSSimon Schubert 	      if (sreloc == NULL)
37745796c8dcSSimon Schubert 		abort ();
3775*ef5ccd6cSJohn Marino 	      elf_append_rel (output_bfd, sreloc, &outrel);
37765796c8dcSSimon Schubert 	    }
37775796c8dcSSimon Schubert 	  /* Fall through */
37785796c8dcSSimon Schubert 
37795796c8dcSSimon Schubert 	case R_386_TLS_GD:
37805796c8dcSSimon Schubert 	case R_386_TLS_GOTDESC:
37815796c8dcSSimon Schubert 	case R_386_TLS_DESC_CALL:
37825796c8dcSSimon Schubert 	case R_386_TLS_IE_32:
37835796c8dcSSimon Schubert 	case R_386_TLS_GOTIE:
37845796c8dcSSimon Schubert 	  tls_type = GOT_UNKNOWN;
37855796c8dcSSimon Schubert 	  if (h == NULL && local_got_offsets)
37865796c8dcSSimon Schubert 	    tls_type = elf_i386_local_got_tls_type (input_bfd) [r_symndx];
37875796c8dcSSimon Schubert 	  else if (h != NULL)
37885796c8dcSSimon Schubert 	    tls_type = elf_i386_hash_entry(h)->tls_type;
37895796c8dcSSimon Schubert 	  if (tls_type == GOT_TLS_IE)
37905796c8dcSSimon Schubert 	    tls_type = GOT_TLS_IE_NEG;
37915796c8dcSSimon Schubert 
37925796c8dcSSimon Schubert 	  if (! elf_i386_tls_transition (info, input_bfd,
37935796c8dcSSimon Schubert 					 input_section, contents,
37945796c8dcSSimon Schubert 					 symtab_hdr, sym_hashes,
37955796c8dcSSimon Schubert 					 &r_type, tls_type, rel,
37965796c8dcSSimon Schubert 					 relend, h, r_symndx))
37975796c8dcSSimon Schubert 	    return FALSE;
37985796c8dcSSimon Schubert 
37995796c8dcSSimon Schubert 	  if (r_type == R_386_TLS_LE_32)
38005796c8dcSSimon Schubert 	    {
38015796c8dcSSimon Schubert 	      BFD_ASSERT (! unresolved_reloc);
38025796c8dcSSimon Schubert 	      if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GD)
38035796c8dcSSimon Schubert 		{
38045796c8dcSSimon Schubert 		  unsigned int type;
38055796c8dcSSimon Schubert 		  bfd_vma roff;
38065796c8dcSSimon Schubert 
38075796c8dcSSimon Schubert 		  /* GD->LE transition.  */
38085796c8dcSSimon Schubert 		  type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
38095796c8dcSSimon Schubert 		  if (type == 0x04)
38105796c8dcSSimon Schubert 		    {
38115796c8dcSSimon Schubert 		      /* leal foo(,%reg,1), %eax; call ___tls_get_addr
38125796c8dcSSimon Schubert 			 Change it into:
38135796c8dcSSimon Schubert 			 movl %gs:0, %eax; subl $foo@tpoff, %eax
38145796c8dcSSimon Schubert 			 (6 byte form of subl).  */
38155796c8dcSSimon Schubert 		      memcpy (contents + rel->r_offset - 3,
38165796c8dcSSimon Schubert 			      "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
38175796c8dcSSimon Schubert 		      roff = rel->r_offset + 5;
38185796c8dcSSimon Schubert 		    }
38195796c8dcSSimon Schubert 		  else
38205796c8dcSSimon Schubert 		    {
38215796c8dcSSimon Schubert 		      /* leal foo(%reg), %eax; call ___tls_get_addr; nop
38225796c8dcSSimon Schubert 			 Change it into:
38235796c8dcSSimon Schubert 			 movl %gs:0, %eax; subl $foo@tpoff, %eax
38245796c8dcSSimon Schubert 			 (6 byte form of subl).  */
38255796c8dcSSimon Schubert 		      memcpy (contents + rel->r_offset - 2,
38265796c8dcSSimon Schubert 			      "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
38275796c8dcSSimon Schubert 		      roff = rel->r_offset + 6;
38285796c8dcSSimon Schubert 		    }
38295796c8dcSSimon Schubert 		  bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation),
38305796c8dcSSimon Schubert 			      contents + roff);
38315796c8dcSSimon Schubert 		  /* Skip R_386_PC32/R_386_PLT32.  */
38325796c8dcSSimon Schubert 		  rel++;
38335796c8dcSSimon Schubert 		  continue;
38345796c8dcSSimon Schubert 		}
38355796c8dcSSimon Schubert 	      else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
38365796c8dcSSimon Schubert 		{
38375796c8dcSSimon Schubert 		  /* GDesc -> LE transition.
38385796c8dcSSimon Schubert 		     It's originally something like:
38395796c8dcSSimon Schubert 		     leal x@tlsdesc(%ebx), %eax
38405796c8dcSSimon Schubert 
38415796c8dcSSimon Schubert 		     leal x@ntpoff, %eax
38425796c8dcSSimon Schubert 
38435796c8dcSSimon Schubert 		     Registers other than %eax may be set up here.  */
38445796c8dcSSimon Schubert 
38455796c8dcSSimon Schubert 		  unsigned int val;
38465796c8dcSSimon Schubert 		  bfd_vma roff;
38475796c8dcSSimon Schubert 
38485796c8dcSSimon Schubert 		  roff = rel->r_offset;
38495796c8dcSSimon Schubert 		  val = bfd_get_8 (input_bfd, contents + roff - 1);
38505796c8dcSSimon Schubert 
38515796c8dcSSimon Schubert 		  /* Now modify the instruction as appropriate.  */
38525796c8dcSSimon Schubert 		  /* aoliva FIXME: remove the above and xor the byte
38535796c8dcSSimon Schubert 		     below with 0x86.  */
38545796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, val ^ 0x86,
38555796c8dcSSimon Schubert 			     contents + roff - 1);
38565796c8dcSSimon Schubert 		  bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
38575796c8dcSSimon Schubert 			      contents + roff);
38585796c8dcSSimon Schubert 		  continue;
38595796c8dcSSimon Schubert 		}
38605796c8dcSSimon Schubert 	      else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_DESC_CALL)
38615796c8dcSSimon Schubert 		{
38625796c8dcSSimon Schubert 		  /* GDesc -> LE transition.
38635796c8dcSSimon Schubert 		     It's originally:
38645796c8dcSSimon Schubert 		     call *(%eax)
38655796c8dcSSimon Schubert 		     Turn it into:
38665796c8dcSSimon Schubert 		     xchg %ax,%ax  */
38675796c8dcSSimon Schubert 
38685796c8dcSSimon Schubert 		  bfd_vma roff;
38695796c8dcSSimon Schubert 
38705796c8dcSSimon Schubert 		  roff = rel->r_offset;
38715796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0x66, contents + roff);
38725796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
38735796c8dcSSimon Schubert 		  continue;
38745796c8dcSSimon Schubert 		}
38755796c8dcSSimon Schubert 	      else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_IE)
38765796c8dcSSimon Schubert 		{
38775796c8dcSSimon Schubert 		  unsigned int val;
38785796c8dcSSimon Schubert 
38795796c8dcSSimon Schubert 		  /* IE->LE transition:
38805796c8dcSSimon Schubert 		     Originally it can be one of:
38815796c8dcSSimon Schubert 		     movl foo, %eax
38825796c8dcSSimon Schubert 		     movl foo, %reg
38835796c8dcSSimon Schubert 		     addl foo, %reg
38845796c8dcSSimon Schubert 		     We change it into:
38855796c8dcSSimon Schubert 		     movl $foo, %eax
38865796c8dcSSimon Schubert 		     movl $foo, %reg
38875796c8dcSSimon Schubert 		     addl $foo, %reg.  */
38885796c8dcSSimon Schubert 		  val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
38895796c8dcSSimon Schubert 		  if (val == 0xa1)
38905796c8dcSSimon Schubert 		    {
38915796c8dcSSimon Schubert 		      /* movl foo, %eax.  */
38925796c8dcSSimon Schubert 		      bfd_put_8 (output_bfd, 0xb8,
38935796c8dcSSimon Schubert 				 contents + rel->r_offset - 1);
38945796c8dcSSimon Schubert 		    }
38955796c8dcSSimon Schubert 		  else
38965796c8dcSSimon Schubert 		    {
38975796c8dcSSimon Schubert 		      unsigned int type;
38985796c8dcSSimon Schubert 
38995796c8dcSSimon Schubert 		      type = bfd_get_8 (input_bfd,
39005796c8dcSSimon Schubert 					contents + rel->r_offset - 2);
39015796c8dcSSimon Schubert 		      switch (type)
39025796c8dcSSimon Schubert 			{
39035796c8dcSSimon Schubert 			case 0x8b:
39045796c8dcSSimon Schubert 			  /* movl */
39055796c8dcSSimon Schubert 			  bfd_put_8 (output_bfd, 0xc7,
39065796c8dcSSimon Schubert 				     contents + rel->r_offset - 2);
39075796c8dcSSimon Schubert 			  bfd_put_8 (output_bfd,
39085796c8dcSSimon Schubert 				     0xc0 | ((val >> 3) & 7),
39095796c8dcSSimon Schubert 				     contents + rel->r_offset - 1);
39105796c8dcSSimon Schubert 			  break;
39115796c8dcSSimon Schubert 			case 0x03:
39125796c8dcSSimon Schubert 			  /* addl */
39135796c8dcSSimon Schubert 			  bfd_put_8 (output_bfd, 0x81,
39145796c8dcSSimon Schubert 				     contents + rel->r_offset - 2);
39155796c8dcSSimon Schubert 			  bfd_put_8 (output_bfd,
39165796c8dcSSimon Schubert 				     0xc0 | ((val >> 3) & 7),
39175796c8dcSSimon Schubert 				     contents + rel->r_offset - 1);
39185796c8dcSSimon Schubert 			  break;
39195796c8dcSSimon Schubert 			default:
39205796c8dcSSimon Schubert 			  BFD_FAIL ();
39215796c8dcSSimon Schubert 			  break;
39225796c8dcSSimon Schubert 			}
39235796c8dcSSimon Schubert 		    }
39245796c8dcSSimon Schubert 		  bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
39255796c8dcSSimon Schubert 			      contents + rel->r_offset);
39265796c8dcSSimon Schubert 		  continue;
39275796c8dcSSimon Schubert 		}
39285796c8dcSSimon Schubert 	      else
39295796c8dcSSimon Schubert 		{
39305796c8dcSSimon Schubert 		  unsigned int val, type;
39315796c8dcSSimon Schubert 
39325796c8dcSSimon Schubert 		  /* {IE_32,GOTIE}->LE transition:
39335796c8dcSSimon Schubert 		     Originally it can be one of:
39345796c8dcSSimon Schubert 		     subl foo(%reg1), %reg2
39355796c8dcSSimon Schubert 		     movl foo(%reg1), %reg2
39365796c8dcSSimon Schubert 		     addl foo(%reg1), %reg2
39375796c8dcSSimon Schubert 		     We change it into:
39385796c8dcSSimon Schubert 		     subl $foo, %reg2
39395796c8dcSSimon Schubert 		     movl $foo, %reg2 (6 byte form)
39405796c8dcSSimon Schubert 		     addl $foo, %reg2.  */
39415796c8dcSSimon Schubert 		  type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
39425796c8dcSSimon Schubert 		  val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
39435796c8dcSSimon Schubert 		  if (type == 0x8b)
39445796c8dcSSimon Schubert 		    {
39455796c8dcSSimon Schubert 		      /* movl */
39465796c8dcSSimon Schubert 		      bfd_put_8 (output_bfd, 0xc7,
39475796c8dcSSimon Schubert 				 contents + rel->r_offset - 2);
39485796c8dcSSimon Schubert 		      bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
39495796c8dcSSimon Schubert 				 contents + rel->r_offset - 1);
39505796c8dcSSimon Schubert 		    }
39515796c8dcSSimon Schubert 		  else if (type == 0x2b)
39525796c8dcSSimon Schubert 		    {
39535796c8dcSSimon Schubert 		      /* subl */
39545796c8dcSSimon Schubert 		      bfd_put_8 (output_bfd, 0x81,
39555796c8dcSSimon Schubert 				 contents + rel->r_offset - 2);
39565796c8dcSSimon Schubert 		      bfd_put_8 (output_bfd, 0xe8 | ((val >> 3) & 7),
39575796c8dcSSimon Schubert 				 contents + rel->r_offset - 1);
39585796c8dcSSimon Schubert 		    }
39595796c8dcSSimon Schubert 		  else if (type == 0x03)
39605796c8dcSSimon Schubert 		    {
39615796c8dcSSimon Schubert 		      /* addl */
39625796c8dcSSimon Schubert 		      bfd_put_8 (output_bfd, 0x81,
39635796c8dcSSimon Schubert 				 contents + rel->r_offset - 2);
39645796c8dcSSimon Schubert 		      bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
39655796c8dcSSimon Schubert 				 contents + rel->r_offset - 1);
39665796c8dcSSimon Schubert 		    }
39675796c8dcSSimon Schubert 		  else
39685796c8dcSSimon Schubert 		    BFD_FAIL ();
39695796c8dcSSimon Schubert 		  if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTIE)
39705796c8dcSSimon Schubert 		    bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
39715796c8dcSSimon Schubert 				contents + rel->r_offset);
39725796c8dcSSimon Schubert 		  else
39735796c8dcSSimon Schubert 		    bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation),
39745796c8dcSSimon Schubert 				contents + rel->r_offset);
39755796c8dcSSimon Schubert 		  continue;
39765796c8dcSSimon Schubert 		}
39775796c8dcSSimon Schubert 	    }
39785796c8dcSSimon Schubert 
39795796c8dcSSimon Schubert 	  if (htab->elf.sgot == NULL)
39805796c8dcSSimon Schubert 	    abort ();
39815796c8dcSSimon Schubert 
39825796c8dcSSimon Schubert 	  if (h != NULL)
39835796c8dcSSimon Schubert 	    {
39845796c8dcSSimon Schubert 	      off = h->got.offset;
39855796c8dcSSimon Schubert 	      offplt = elf_i386_hash_entry (h)->tlsdesc_got;
39865796c8dcSSimon Schubert 	    }
39875796c8dcSSimon Schubert 	  else
39885796c8dcSSimon Schubert 	    {
39895796c8dcSSimon Schubert 	      if (local_got_offsets == NULL)
39905796c8dcSSimon Schubert 		abort ();
39915796c8dcSSimon Schubert 
39925796c8dcSSimon Schubert 	      off = local_got_offsets[r_symndx];
39935796c8dcSSimon Schubert 	      offplt = local_tlsdesc_gotents[r_symndx];
39945796c8dcSSimon Schubert 	    }
39955796c8dcSSimon Schubert 
39965796c8dcSSimon Schubert 	  if ((off & 1) != 0)
39975796c8dcSSimon Schubert 	    off &= ~1;
39985796c8dcSSimon Schubert 	  else
39995796c8dcSSimon Schubert 	    {
40005796c8dcSSimon Schubert 	      Elf_Internal_Rela outrel;
4001cf7f2e2dSJohn Marino 	      int dr_type;
40025796c8dcSSimon Schubert 	      asection *sreloc;
40035796c8dcSSimon Schubert 
40045796c8dcSSimon Schubert 	      if (htab->elf.srelgot == NULL)
40055796c8dcSSimon Schubert 		abort ();
40065796c8dcSSimon Schubert 
40075796c8dcSSimon Schubert 	      indx = h && h->dynindx != -1 ? h->dynindx : 0;
40085796c8dcSSimon Schubert 
40095796c8dcSSimon Schubert 	      if (GOT_TLS_GDESC_P (tls_type))
40105796c8dcSSimon Schubert 		{
4011*ef5ccd6cSJohn Marino 		  bfd_byte *loc;
40125796c8dcSSimon Schubert 		  outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_DESC);
40135796c8dcSSimon Schubert 		  BFD_ASSERT (htab->sgotplt_jump_table_size + offplt + 8
40145796c8dcSSimon Schubert 			      <= htab->elf.sgotplt->size);
40155796c8dcSSimon Schubert 		  outrel.r_offset = (htab->elf.sgotplt->output_section->vma
40165796c8dcSSimon Schubert 				     + htab->elf.sgotplt->output_offset
40175796c8dcSSimon Schubert 				     + offplt
40185796c8dcSSimon Schubert 				     + htab->sgotplt_jump_table_size);
40195796c8dcSSimon Schubert 		  sreloc = htab->elf.srelplt;
40205796c8dcSSimon Schubert 		  loc = sreloc->contents;
40215796c8dcSSimon Schubert 		  loc += (htab->next_tls_desc_index++
40225796c8dcSSimon Schubert 			  * sizeof (Elf32_External_Rel));
40235796c8dcSSimon Schubert 		  BFD_ASSERT (loc + sizeof (Elf32_External_Rel)
40245796c8dcSSimon Schubert 			      <= sreloc->contents + sreloc->size);
40255796c8dcSSimon Schubert 		  bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
40265796c8dcSSimon Schubert 		  if (indx == 0)
40275796c8dcSSimon Schubert 		    {
40285796c8dcSSimon Schubert 		      BFD_ASSERT (! unresolved_reloc);
40295796c8dcSSimon Schubert 		      bfd_put_32 (output_bfd,
40305796c8dcSSimon Schubert 				  relocation - elf_i386_dtpoff_base (info),
40315796c8dcSSimon Schubert 				  htab->elf.sgotplt->contents + offplt
40325796c8dcSSimon Schubert 				  + htab->sgotplt_jump_table_size + 4);
40335796c8dcSSimon Schubert 		    }
40345796c8dcSSimon Schubert 		  else
40355796c8dcSSimon Schubert 		    {
40365796c8dcSSimon Schubert 		      bfd_put_32 (output_bfd, 0,
40375796c8dcSSimon Schubert 				  htab->elf.sgotplt->contents + offplt
40385796c8dcSSimon Schubert 				  + htab->sgotplt_jump_table_size + 4);
40395796c8dcSSimon Schubert 		    }
40405796c8dcSSimon Schubert 		}
40415796c8dcSSimon Schubert 
40425796c8dcSSimon Schubert 	      sreloc = htab->elf.srelgot;
40435796c8dcSSimon Schubert 
40445796c8dcSSimon Schubert 	      outrel.r_offset = (htab->elf.sgot->output_section->vma
40455796c8dcSSimon Schubert 				 + htab->elf.sgot->output_offset + off);
40465796c8dcSSimon Schubert 
40475796c8dcSSimon Schubert 	      if (GOT_TLS_GD_P (tls_type))
40485796c8dcSSimon Schubert 		dr_type = R_386_TLS_DTPMOD32;
40495796c8dcSSimon Schubert 	      else if (GOT_TLS_GDESC_P (tls_type))
40505796c8dcSSimon Schubert 		goto dr_done;
40515796c8dcSSimon Schubert 	      else if (tls_type == GOT_TLS_IE_POS)
40525796c8dcSSimon Schubert 		dr_type = R_386_TLS_TPOFF;
40535796c8dcSSimon Schubert 	      else
40545796c8dcSSimon Schubert 		dr_type = R_386_TLS_TPOFF32;
40555796c8dcSSimon Schubert 
40565796c8dcSSimon Schubert 	      if (dr_type == R_386_TLS_TPOFF && indx == 0)
40575796c8dcSSimon Schubert 		bfd_put_32 (output_bfd,
40585796c8dcSSimon Schubert 			    relocation - elf_i386_dtpoff_base (info),
40595796c8dcSSimon Schubert 			    htab->elf.sgot->contents + off);
40605796c8dcSSimon Schubert 	      else if (dr_type == R_386_TLS_TPOFF32 && indx == 0)
40615796c8dcSSimon Schubert 		bfd_put_32 (output_bfd,
40625796c8dcSSimon Schubert 			    elf_i386_dtpoff_base (info) - relocation,
40635796c8dcSSimon Schubert 			    htab->elf.sgot->contents + off);
40645796c8dcSSimon Schubert 	      else if (dr_type != R_386_TLS_DESC)
40655796c8dcSSimon Schubert 		bfd_put_32 (output_bfd, 0,
40665796c8dcSSimon Schubert 			    htab->elf.sgot->contents + off);
40675796c8dcSSimon Schubert 	      outrel.r_info = ELF32_R_INFO (indx, dr_type);
40685796c8dcSSimon Schubert 
4069*ef5ccd6cSJohn Marino 	      elf_append_rel (output_bfd, sreloc, &outrel);
40705796c8dcSSimon Schubert 
40715796c8dcSSimon Schubert 	      if (GOT_TLS_GD_P (tls_type))
40725796c8dcSSimon Schubert 		{
40735796c8dcSSimon Schubert 		  if (indx == 0)
40745796c8dcSSimon Schubert 		    {
40755796c8dcSSimon Schubert 	    	      BFD_ASSERT (! unresolved_reloc);
40765796c8dcSSimon Schubert 		      bfd_put_32 (output_bfd,
40775796c8dcSSimon Schubert 				  relocation - elf_i386_dtpoff_base (info),
40785796c8dcSSimon Schubert 				  htab->elf.sgot->contents + off + 4);
40795796c8dcSSimon Schubert 		    }
40805796c8dcSSimon Schubert 		  else
40815796c8dcSSimon Schubert 		    {
40825796c8dcSSimon Schubert 		      bfd_put_32 (output_bfd, 0,
40835796c8dcSSimon Schubert 				  htab->elf.sgot->contents + off + 4);
40845796c8dcSSimon Schubert 		      outrel.r_info = ELF32_R_INFO (indx,
40855796c8dcSSimon Schubert 						    R_386_TLS_DTPOFF32);
40865796c8dcSSimon Schubert 		      outrel.r_offset += 4;
4087*ef5ccd6cSJohn Marino 		      elf_append_rel (output_bfd, sreloc, &outrel);
40885796c8dcSSimon Schubert 		    }
40895796c8dcSSimon Schubert 		}
40905796c8dcSSimon Schubert 	      else if (tls_type == GOT_TLS_IE_BOTH)
40915796c8dcSSimon Schubert 		{
40925796c8dcSSimon Schubert 		  bfd_put_32 (output_bfd,
40935796c8dcSSimon Schubert 			      (indx == 0
40945796c8dcSSimon Schubert 			       ? relocation - elf_i386_dtpoff_base (info)
40955796c8dcSSimon Schubert 			       : 0),
40965796c8dcSSimon Schubert 			      htab->elf.sgot->contents + off + 4);
40975796c8dcSSimon Schubert 		  outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
40985796c8dcSSimon Schubert 		  outrel.r_offset += 4;
4099*ef5ccd6cSJohn Marino 		  elf_append_rel (output_bfd, sreloc, &outrel);
41005796c8dcSSimon Schubert 		}
41015796c8dcSSimon Schubert 
41025796c8dcSSimon Schubert 	    dr_done:
41035796c8dcSSimon Schubert 	      if (h != NULL)
41045796c8dcSSimon Schubert 		h->got.offset |= 1;
41055796c8dcSSimon Schubert 	      else
41065796c8dcSSimon Schubert 		local_got_offsets[r_symndx] |= 1;
41075796c8dcSSimon Schubert 	    }
41085796c8dcSSimon Schubert 
41095796c8dcSSimon Schubert 	  if (off >= (bfd_vma) -2
41105796c8dcSSimon Schubert 	      && ! GOT_TLS_GDESC_P (tls_type))
41115796c8dcSSimon Schubert 	    abort ();
41125796c8dcSSimon Schubert 	  if (r_type == R_386_TLS_GOTDESC
41135796c8dcSSimon Schubert 	      || r_type == R_386_TLS_DESC_CALL)
41145796c8dcSSimon Schubert 	    {
41155796c8dcSSimon Schubert 	      relocation = htab->sgotplt_jump_table_size + offplt;
41165796c8dcSSimon Schubert 	      unresolved_reloc = FALSE;
41175796c8dcSSimon Schubert 	    }
41185796c8dcSSimon Schubert 	  else if (r_type == ELF32_R_TYPE (rel->r_info))
41195796c8dcSSimon Schubert 	    {
41205796c8dcSSimon Schubert 	      bfd_vma g_o_t = htab->elf.sgotplt->output_section->vma
41215796c8dcSSimon Schubert 			      + htab->elf.sgotplt->output_offset;
41225796c8dcSSimon Schubert 	      relocation = htab->elf.sgot->output_section->vma
41235796c8dcSSimon Schubert 		+ htab->elf.sgot->output_offset + off - g_o_t;
41245796c8dcSSimon Schubert 	      if ((r_type == R_386_TLS_IE || r_type == R_386_TLS_GOTIE)
41255796c8dcSSimon Schubert 		  && tls_type == GOT_TLS_IE_BOTH)
41265796c8dcSSimon Schubert 		relocation += 4;
41275796c8dcSSimon Schubert 	      if (r_type == R_386_TLS_IE)
41285796c8dcSSimon Schubert 		relocation += g_o_t;
41295796c8dcSSimon Schubert 	      unresolved_reloc = FALSE;
41305796c8dcSSimon Schubert 	    }
41315796c8dcSSimon Schubert 	  else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GD)
41325796c8dcSSimon Schubert 	    {
41335796c8dcSSimon Schubert 	      unsigned int val, type;
41345796c8dcSSimon Schubert 	      bfd_vma roff;
41355796c8dcSSimon Schubert 
41365796c8dcSSimon Schubert 	      /* GD->IE transition.  */
41375796c8dcSSimon Schubert 	      type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
41385796c8dcSSimon Schubert 	      val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
41395796c8dcSSimon Schubert 	      if (type == 0x04)
41405796c8dcSSimon Schubert 		{
41415796c8dcSSimon Schubert 		  /* leal foo(,%reg,1), %eax; call ___tls_get_addr
41425796c8dcSSimon Schubert 		     Change it into:
41435796c8dcSSimon Schubert 		     movl %gs:0, %eax; subl $foo@gottpoff(%reg), %eax.  */
41445796c8dcSSimon Schubert 		  val >>= 3;
41455796c8dcSSimon Schubert 		  roff = rel->r_offset - 3;
41465796c8dcSSimon Schubert 		}
41475796c8dcSSimon Schubert 	      else
41485796c8dcSSimon Schubert 		{
41495796c8dcSSimon Schubert 		  /* leal foo(%reg), %eax; call ___tls_get_addr; nop
41505796c8dcSSimon Schubert 		     Change it into:
41515796c8dcSSimon Schubert 		     movl %gs:0, %eax; subl $foo@gottpoff(%reg), %eax.  */
41525796c8dcSSimon Schubert 		  roff = rel->r_offset - 2;
41535796c8dcSSimon Schubert 		}
41545796c8dcSSimon Schubert 	      memcpy (contents + roff,
41555796c8dcSSimon Schubert 		      "\x65\xa1\0\0\0\0\x2b\x80\0\0\0", 12);
41565796c8dcSSimon Schubert 	      contents[roff + 7] = 0x80 | (val & 7);
41575796c8dcSSimon Schubert 	      /* If foo is used only with foo@gotntpoff(%reg) and
41585796c8dcSSimon Schubert 		 foo@indntpoff, but not with foo@gottpoff(%reg), change
41595796c8dcSSimon Schubert 		 subl $foo@gottpoff(%reg), %eax
41605796c8dcSSimon Schubert 		 into:
41615796c8dcSSimon Schubert 		 addl $foo@gotntpoff(%reg), %eax.  */
41625796c8dcSSimon Schubert 	      if (tls_type == GOT_TLS_IE_POS)
41635796c8dcSSimon Schubert 		contents[roff + 6] = 0x03;
41645796c8dcSSimon Schubert 	      bfd_put_32 (output_bfd,
41655796c8dcSSimon Schubert 			  htab->elf.sgot->output_section->vma
41665796c8dcSSimon Schubert 			  + htab->elf.sgot->output_offset + off
41675796c8dcSSimon Schubert 			  - htab->elf.sgotplt->output_section->vma
41685796c8dcSSimon Schubert 			  - htab->elf.sgotplt->output_offset,
41695796c8dcSSimon Schubert 			  contents + roff + 8);
41705796c8dcSSimon Schubert 	      /* Skip R_386_PLT32.  */
41715796c8dcSSimon Schubert 	      rel++;
41725796c8dcSSimon Schubert 	      continue;
41735796c8dcSSimon Schubert 	    }
41745796c8dcSSimon Schubert 	  else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
41755796c8dcSSimon Schubert 	    {
41765796c8dcSSimon Schubert 	      /* GDesc -> IE transition.
41775796c8dcSSimon Schubert 		 It's originally something like:
41785796c8dcSSimon Schubert 		 leal x@tlsdesc(%ebx), %eax
41795796c8dcSSimon Schubert 
41805796c8dcSSimon Schubert 		 Change it to:
41815796c8dcSSimon Schubert 		 movl x@gotntpoff(%ebx), %eax # before xchg %ax,%ax
41825796c8dcSSimon Schubert 		 or:
41835796c8dcSSimon Schubert 		 movl x@gottpoff(%ebx), %eax # before negl %eax
41845796c8dcSSimon Schubert 
41855796c8dcSSimon Schubert 		 Registers other than %eax may be set up here.  */
41865796c8dcSSimon Schubert 
41875796c8dcSSimon Schubert 	      bfd_vma roff;
41885796c8dcSSimon Schubert 
41895796c8dcSSimon Schubert 	      /* First, make sure it's a leal adding ebx to a 32-bit
41905796c8dcSSimon Schubert 		 offset into any register, although it's probably
41915796c8dcSSimon Schubert 		 almost always going to be eax.  */
41925796c8dcSSimon Schubert 	      roff = rel->r_offset;
41935796c8dcSSimon Schubert 
41945796c8dcSSimon Schubert 	      /* Now modify the instruction as appropriate.  */
41955796c8dcSSimon Schubert 	      /* To turn a leal into a movl in the form we use it, it
41965796c8dcSSimon Schubert 		 suffices to change the first byte from 0x8d to 0x8b.
41975796c8dcSSimon Schubert 		 aoliva FIXME: should we decide to keep the leal, all
41985796c8dcSSimon Schubert 		 we have to do is remove the statement below, and
41995796c8dcSSimon Schubert 		 adjust the relaxation of R_386_TLS_DESC_CALL.  */
42005796c8dcSSimon Schubert 	      bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
42015796c8dcSSimon Schubert 
42025796c8dcSSimon Schubert 	      if (tls_type == GOT_TLS_IE_BOTH)
42035796c8dcSSimon Schubert 		off += 4;
42045796c8dcSSimon Schubert 
42055796c8dcSSimon Schubert 	      bfd_put_32 (output_bfd,
42065796c8dcSSimon Schubert 			  htab->elf.sgot->output_section->vma
42075796c8dcSSimon Schubert 			  + htab->elf.sgot->output_offset + off
42085796c8dcSSimon Schubert 			  - htab->elf.sgotplt->output_section->vma
42095796c8dcSSimon Schubert 			  - htab->elf.sgotplt->output_offset,
42105796c8dcSSimon Schubert 			  contents + roff);
42115796c8dcSSimon Schubert 	      continue;
42125796c8dcSSimon Schubert 	    }
42135796c8dcSSimon Schubert 	  else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_DESC_CALL)
42145796c8dcSSimon Schubert 	    {
42155796c8dcSSimon Schubert 	      /* GDesc -> IE transition.
42165796c8dcSSimon Schubert 		 It's originally:
42175796c8dcSSimon Schubert 		 call *(%eax)
42185796c8dcSSimon Schubert 
42195796c8dcSSimon Schubert 		 Change it to:
42205796c8dcSSimon Schubert 		 xchg %ax,%ax
42215796c8dcSSimon Schubert 		 or
42225796c8dcSSimon Schubert 		 negl %eax
42235796c8dcSSimon Schubert 		 depending on how we transformed the TLS_GOTDESC above.
42245796c8dcSSimon Schubert 	      */
42255796c8dcSSimon Schubert 
42265796c8dcSSimon Schubert 	      bfd_vma roff;
42275796c8dcSSimon Schubert 
42285796c8dcSSimon Schubert 	      roff = rel->r_offset;
42295796c8dcSSimon Schubert 
42305796c8dcSSimon Schubert 	      /* Now modify the instruction as appropriate.  */
42315796c8dcSSimon Schubert 	      if (tls_type != GOT_TLS_IE_NEG)
42325796c8dcSSimon Schubert 		{
42335796c8dcSSimon Schubert 		  /* xchg %ax,%ax */
42345796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0x66, contents + roff);
42355796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
42365796c8dcSSimon Schubert 		}
42375796c8dcSSimon Schubert 	      else
42385796c8dcSSimon Schubert 		{
42395796c8dcSSimon Schubert 		  /* negl %eax */
42405796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0xf7, contents + roff);
42415796c8dcSSimon Schubert 		  bfd_put_8 (output_bfd, 0xd8, contents + roff + 1);
42425796c8dcSSimon Schubert 		}
42435796c8dcSSimon Schubert 
42445796c8dcSSimon Schubert 	      continue;
42455796c8dcSSimon Schubert 	    }
42465796c8dcSSimon Schubert 	  else
42475796c8dcSSimon Schubert 	    BFD_ASSERT (FALSE);
42485796c8dcSSimon Schubert 	  break;
42495796c8dcSSimon Schubert 
42505796c8dcSSimon Schubert 	case R_386_TLS_LDM:
42515796c8dcSSimon Schubert 	  if (! elf_i386_tls_transition (info, input_bfd,
42525796c8dcSSimon Schubert 					 input_section, contents,
42535796c8dcSSimon Schubert 					 symtab_hdr, sym_hashes,
42545796c8dcSSimon Schubert 					 &r_type, GOT_UNKNOWN, rel,
42555796c8dcSSimon Schubert 					 relend, h, r_symndx))
42565796c8dcSSimon Schubert 	    return FALSE;
42575796c8dcSSimon Schubert 
42585796c8dcSSimon Schubert 	  if (r_type != R_386_TLS_LDM)
42595796c8dcSSimon Schubert 	    {
42605796c8dcSSimon Schubert 	      /* LD->LE transition:
42615796c8dcSSimon Schubert 		 leal foo(%reg), %eax; call ___tls_get_addr.
42625796c8dcSSimon Schubert 		 We change it into:
42635796c8dcSSimon Schubert 		 movl %gs:0, %eax; nop; leal 0(%esi,1), %esi.  */
42645796c8dcSSimon Schubert 	      BFD_ASSERT (r_type == R_386_TLS_LE_32);
42655796c8dcSSimon Schubert 	      memcpy (contents + rel->r_offset - 2,
42665796c8dcSSimon Schubert 		      "\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11);
42675796c8dcSSimon Schubert 	      /* Skip R_386_PC32/R_386_PLT32.  */
42685796c8dcSSimon Schubert 	      rel++;
42695796c8dcSSimon Schubert 	      continue;
42705796c8dcSSimon Schubert 	    }
42715796c8dcSSimon Schubert 
42725796c8dcSSimon Schubert 	  if (htab->elf.sgot == NULL)
42735796c8dcSSimon Schubert 	    abort ();
42745796c8dcSSimon Schubert 
42755796c8dcSSimon Schubert 	  off = htab->tls_ldm_got.offset;
42765796c8dcSSimon Schubert 	  if (off & 1)
42775796c8dcSSimon Schubert 	    off &= ~1;
42785796c8dcSSimon Schubert 	  else
42795796c8dcSSimon Schubert 	    {
42805796c8dcSSimon Schubert 	      Elf_Internal_Rela outrel;
42815796c8dcSSimon Schubert 
42825796c8dcSSimon Schubert 	      if (htab->elf.srelgot == NULL)
42835796c8dcSSimon Schubert 		abort ();
42845796c8dcSSimon Schubert 
42855796c8dcSSimon Schubert 	      outrel.r_offset = (htab->elf.sgot->output_section->vma
42865796c8dcSSimon Schubert 				 + htab->elf.sgot->output_offset + off);
42875796c8dcSSimon Schubert 
42885796c8dcSSimon Schubert 	      bfd_put_32 (output_bfd, 0,
42895796c8dcSSimon Schubert 			  htab->elf.sgot->contents + off);
42905796c8dcSSimon Schubert 	      bfd_put_32 (output_bfd, 0,
42915796c8dcSSimon Schubert 			  htab->elf.sgot->contents + off + 4);
42925796c8dcSSimon Schubert 	      outrel.r_info = ELF32_R_INFO (0, R_386_TLS_DTPMOD32);
4293*ef5ccd6cSJohn Marino 	      elf_append_rel (output_bfd, htab->elf.srelgot, &outrel);
42945796c8dcSSimon Schubert 	      htab->tls_ldm_got.offset |= 1;
42955796c8dcSSimon Schubert 	    }
42965796c8dcSSimon Schubert 	  relocation = htab->elf.sgot->output_section->vma
42975796c8dcSSimon Schubert 		       + htab->elf.sgot->output_offset + off
42985796c8dcSSimon Schubert 		       - htab->elf.sgotplt->output_section->vma
42995796c8dcSSimon Schubert 		       - htab->elf.sgotplt->output_offset;
43005796c8dcSSimon Schubert 	  unresolved_reloc = FALSE;
43015796c8dcSSimon Schubert 	  break;
43025796c8dcSSimon Schubert 
43035796c8dcSSimon Schubert 	case R_386_TLS_LDO_32:
4304a45ae5f8SJohn Marino 	  if (!info->executable || (input_section->flags & SEC_CODE) == 0)
43055796c8dcSSimon Schubert 	    relocation -= elf_i386_dtpoff_base (info);
43065796c8dcSSimon Schubert 	  else
43075796c8dcSSimon Schubert 	    /* When converting LDO to LE, we must negate.  */
43085796c8dcSSimon Schubert 	    relocation = -elf_i386_tpoff (info, relocation);
43095796c8dcSSimon Schubert 	  break;
43105796c8dcSSimon Schubert 
43115796c8dcSSimon Schubert 	case R_386_TLS_LE_32:
43125796c8dcSSimon Schubert 	case R_386_TLS_LE:
43135796c8dcSSimon Schubert 	  if (!info->executable)
43145796c8dcSSimon Schubert 	    {
43155796c8dcSSimon Schubert 	      Elf_Internal_Rela outrel;
43165796c8dcSSimon Schubert 	      asection *sreloc;
43175796c8dcSSimon Schubert 
43185796c8dcSSimon Schubert 	      outrel.r_offset = rel->r_offset
43195796c8dcSSimon Schubert 				+ input_section->output_section->vma
43205796c8dcSSimon Schubert 				+ input_section->output_offset;
43215796c8dcSSimon Schubert 	      if (h != NULL && h->dynindx != -1)
43225796c8dcSSimon Schubert 		indx = h->dynindx;
43235796c8dcSSimon Schubert 	      else
43245796c8dcSSimon Schubert 		indx = 0;
43255796c8dcSSimon Schubert 	      if (r_type == R_386_TLS_LE_32)
43265796c8dcSSimon Schubert 		outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF32);
43275796c8dcSSimon Schubert 	      else
43285796c8dcSSimon Schubert 		outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
43295796c8dcSSimon Schubert 	      sreloc = elf_section_data (input_section)->sreloc;
43305796c8dcSSimon Schubert 	      if (sreloc == NULL)
43315796c8dcSSimon Schubert 		abort ();
4332*ef5ccd6cSJohn Marino 	      elf_append_rel (output_bfd, sreloc, &outrel);
43335796c8dcSSimon Schubert 	      if (indx)
43345796c8dcSSimon Schubert 		continue;
43355796c8dcSSimon Schubert 	      else if (r_type == R_386_TLS_LE_32)
43365796c8dcSSimon Schubert 		relocation = elf_i386_dtpoff_base (info) - relocation;
43375796c8dcSSimon Schubert 	      else
43385796c8dcSSimon Schubert 		relocation -= elf_i386_dtpoff_base (info);
43395796c8dcSSimon Schubert 	    }
43405796c8dcSSimon Schubert 	  else if (r_type == R_386_TLS_LE_32)
43415796c8dcSSimon Schubert 	    relocation = elf_i386_tpoff (info, relocation);
43425796c8dcSSimon Schubert 	  else
43435796c8dcSSimon Schubert 	    relocation = -elf_i386_tpoff (info, relocation);
43445796c8dcSSimon Schubert 	  break;
43455796c8dcSSimon Schubert 
43465796c8dcSSimon Schubert 	default:
43475796c8dcSSimon Schubert 	  break;
43485796c8dcSSimon Schubert 	}
43495796c8dcSSimon Schubert 
43505796c8dcSSimon Schubert       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
43515796c8dcSSimon Schubert 	 because such sections are not SEC_ALLOC and thus ld.so will
43525796c8dcSSimon Schubert 	 not process them.  */
43535796c8dcSSimon Schubert       if (unresolved_reloc
43545796c8dcSSimon Schubert 	  && !((input_section->flags & SEC_DEBUGGING) != 0
4355a45ae5f8SJohn Marino 	       && h->def_dynamic)
4356a45ae5f8SJohn Marino 	  && _bfd_elf_section_offset (output_bfd, info, input_section,
4357a45ae5f8SJohn Marino 				      rel->r_offset) != (bfd_vma) -1)
43585796c8dcSSimon Schubert 	{
43595796c8dcSSimon Schubert 	  (*_bfd_error_handler)
43605796c8dcSSimon Schubert 	    (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
43615796c8dcSSimon Schubert 	     input_bfd,
43625796c8dcSSimon Schubert 	     input_section,
43635796c8dcSSimon Schubert 	     (long) rel->r_offset,
43645796c8dcSSimon Schubert 	     howto->name,
43655796c8dcSSimon Schubert 	     h->root.root.string);
43665796c8dcSSimon Schubert 	  return FALSE;
43675796c8dcSSimon Schubert 	}
43685796c8dcSSimon Schubert 
43695796c8dcSSimon Schubert do_relocation:
43705796c8dcSSimon Schubert       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
43715796c8dcSSimon Schubert 				    contents, rel->r_offset,
43725796c8dcSSimon Schubert 				    relocation, 0);
43735796c8dcSSimon Schubert 
4374a45ae5f8SJohn Marino check_relocation_error:
43755796c8dcSSimon Schubert       if (r != bfd_reloc_ok)
43765796c8dcSSimon Schubert 	{
43775796c8dcSSimon Schubert 	  const char *name;
43785796c8dcSSimon Schubert 
43795796c8dcSSimon Schubert 	  if (h != NULL)
43805796c8dcSSimon Schubert 	    name = h->root.root.string;
43815796c8dcSSimon Schubert 	  else
43825796c8dcSSimon Schubert 	    {
43835796c8dcSSimon Schubert 	      name = bfd_elf_string_from_elf_section (input_bfd,
43845796c8dcSSimon Schubert 						      symtab_hdr->sh_link,
43855796c8dcSSimon Schubert 						      sym->st_name);
43865796c8dcSSimon Schubert 	      if (name == NULL)
43875796c8dcSSimon Schubert 		return FALSE;
43885796c8dcSSimon Schubert 	      if (*name == '\0')
43895796c8dcSSimon Schubert 		name = bfd_section_name (input_bfd, sec);
43905796c8dcSSimon Schubert 	    }
43915796c8dcSSimon Schubert 
43925796c8dcSSimon Schubert 	  if (r == bfd_reloc_overflow)
43935796c8dcSSimon Schubert 	    {
43945796c8dcSSimon Schubert 	      if (! ((*info->callbacks->reloc_overflow)
43955796c8dcSSimon Schubert 		     (info, (h ? &h->root : NULL), name, howto->name,
43965796c8dcSSimon Schubert 		      (bfd_vma) 0, input_bfd, input_section,
43975796c8dcSSimon Schubert 		      rel->r_offset)))
43985796c8dcSSimon Schubert 		return FALSE;
43995796c8dcSSimon Schubert 	    }
44005796c8dcSSimon Schubert 	  else
44015796c8dcSSimon Schubert 	    {
44025796c8dcSSimon Schubert 	      (*_bfd_error_handler)
44035796c8dcSSimon Schubert 		(_("%B(%A+0x%lx): reloc against `%s': error %d"),
44045796c8dcSSimon Schubert 		 input_bfd, input_section,
44055796c8dcSSimon Schubert 		 (long) rel->r_offset, name, (int) r);
44065796c8dcSSimon Schubert 	      return FALSE;
44075796c8dcSSimon Schubert 	    }
44085796c8dcSSimon Schubert 	}
44095796c8dcSSimon Schubert     }
44105796c8dcSSimon Schubert 
44115796c8dcSSimon Schubert   return TRUE;
44125796c8dcSSimon Schubert }
44135796c8dcSSimon Schubert 
44145796c8dcSSimon Schubert /* Finish up dynamic symbol handling.  We set the contents of various
44155796c8dcSSimon Schubert    dynamic sections here.  */
44165796c8dcSSimon Schubert 
44175796c8dcSSimon Schubert static bfd_boolean
elf_i386_finish_dynamic_symbol(bfd * output_bfd,struct bfd_link_info * info,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)44185796c8dcSSimon Schubert elf_i386_finish_dynamic_symbol (bfd *output_bfd,
44195796c8dcSSimon Schubert 				struct bfd_link_info *info,
44205796c8dcSSimon Schubert 				struct elf_link_hash_entry *h,
44215796c8dcSSimon Schubert 				Elf_Internal_Sym *sym)
44225796c8dcSSimon Schubert {
44235796c8dcSSimon Schubert   struct elf_i386_link_hash_table *htab;
4424a45ae5f8SJohn Marino   unsigned plt_entry_size;
4425a45ae5f8SJohn Marino   const struct elf_i386_backend_data *abed;
44265796c8dcSSimon Schubert 
44275796c8dcSSimon Schubert   htab = elf_i386_hash_table (info);
4428cf7f2e2dSJohn Marino   if (htab == NULL)
4429cf7f2e2dSJohn Marino     return FALSE;
44305796c8dcSSimon Schubert 
4431a45ae5f8SJohn Marino   abed = get_elf_i386_backend_data (output_bfd);
4432a45ae5f8SJohn Marino   plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd);
4433a45ae5f8SJohn Marino 
44345796c8dcSSimon Schubert   if (h->plt.offset != (bfd_vma) -1)
44355796c8dcSSimon Schubert     {
44365796c8dcSSimon Schubert       bfd_vma plt_index;
44375796c8dcSSimon Schubert       bfd_vma got_offset;
44385796c8dcSSimon Schubert       Elf_Internal_Rela rel;
44395796c8dcSSimon Schubert       bfd_byte *loc;
44405796c8dcSSimon Schubert       asection *plt, *gotplt, *relplt;
44415796c8dcSSimon Schubert 
44425796c8dcSSimon Schubert       /* When building a static executable, use .iplt, .igot.plt and
44435796c8dcSSimon Schubert 	 .rel.iplt sections for STT_GNU_IFUNC symbols.  */
44445796c8dcSSimon Schubert       if (htab->elf.splt != NULL)
44455796c8dcSSimon Schubert 	{
44465796c8dcSSimon Schubert 	  plt = htab->elf.splt;
44475796c8dcSSimon Schubert 	  gotplt = htab->elf.sgotplt;
44485796c8dcSSimon Schubert 	  relplt = htab->elf.srelplt;
44495796c8dcSSimon Schubert 	}
44505796c8dcSSimon Schubert       else
44515796c8dcSSimon Schubert 	{
44525796c8dcSSimon Schubert 	  plt = htab->elf.iplt;
44535796c8dcSSimon Schubert 	  gotplt = htab->elf.igotplt;
44545796c8dcSSimon Schubert 	  relplt = htab->elf.irelplt;
44555796c8dcSSimon Schubert 	}
44565796c8dcSSimon Schubert 
44575796c8dcSSimon Schubert       /* This symbol has an entry in the procedure linkage table.  Set
44585796c8dcSSimon Schubert 	 it up.  */
44595796c8dcSSimon Schubert 
44605796c8dcSSimon Schubert       if ((h->dynindx == -1
44615796c8dcSSimon Schubert 	   && !((h->forced_local || info->executable)
44625796c8dcSSimon Schubert 		&& h->def_regular
44635796c8dcSSimon Schubert 		&& h->type == STT_GNU_IFUNC))
44645796c8dcSSimon Schubert 	  || plt == NULL
44655796c8dcSSimon Schubert 	  || gotplt == NULL
44665796c8dcSSimon Schubert 	  || relplt == NULL)
4467*ef5ccd6cSJohn Marino 	abort ();
44685796c8dcSSimon Schubert 
44695796c8dcSSimon Schubert       /* Get the index in the procedure linkage table which
44705796c8dcSSimon Schubert 	 corresponds to this symbol.  This is the index of this symbol
44715796c8dcSSimon Schubert 	 in all the symbols for which we are making plt entries.  The
44725796c8dcSSimon Schubert 	 first entry in the procedure linkage table is reserved.
44735796c8dcSSimon Schubert 
44745796c8dcSSimon Schubert 	 Get the offset into the .got table of the entry that
44755796c8dcSSimon Schubert 	 corresponds to this function.  Each .got entry is 4 bytes.
44765796c8dcSSimon Schubert 	 The first three are reserved.
44775796c8dcSSimon Schubert 
44785796c8dcSSimon Schubert 	 For static executables, we don't reserve anything.  */
44795796c8dcSSimon Schubert 
44805796c8dcSSimon Schubert       if (plt == htab->elf.splt)
44815796c8dcSSimon Schubert 	{
4482a45ae5f8SJohn Marino 	  got_offset = h->plt.offset / plt_entry_size - 1;
4483a45ae5f8SJohn Marino 	  got_offset = (got_offset + 3) * 4;
44845796c8dcSSimon Schubert 	}
44855796c8dcSSimon Schubert       else
44865796c8dcSSimon Schubert 	{
4487a45ae5f8SJohn Marino 	  got_offset = h->plt.offset / plt_entry_size;
4488a45ae5f8SJohn Marino 	  got_offset = got_offset * 4;
44895796c8dcSSimon Schubert 	}
44905796c8dcSSimon Schubert 
44915796c8dcSSimon Schubert       /* Fill in the entry in the procedure linkage table.  */
44925796c8dcSSimon Schubert       if (! info->shared)
44935796c8dcSSimon Schubert 	{
4494a45ae5f8SJohn Marino 	  memcpy (plt->contents + h->plt.offset, abed->plt->plt_entry,
4495a45ae5f8SJohn Marino 		  abed->plt->plt_entry_size);
44965796c8dcSSimon Schubert 	  bfd_put_32 (output_bfd,
44975796c8dcSSimon Schubert 		      (gotplt->output_section->vma
44985796c8dcSSimon Schubert 		       + gotplt->output_offset
44995796c8dcSSimon Schubert 		       + got_offset),
4500a45ae5f8SJohn Marino 		      plt->contents + h->plt.offset
4501a45ae5f8SJohn Marino                       + abed->plt->plt_got_offset);
45025796c8dcSSimon Schubert 
4503a45ae5f8SJohn Marino 	  if (abed->is_vxworks)
45045796c8dcSSimon Schubert 	    {
45055796c8dcSSimon Schubert 	      int s, k, reloc_index;
45065796c8dcSSimon Schubert 
45075796c8dcSSimon Schubert 	      /* Create the R_386_32 relocation referencing the GOT
45085796c8dcSSimon Schubert 		 for this PLT entry.  */
45095796c8dcSSimon Schubert 
45105796c8dcSSimon Schubert 	      /* S: Current slot number (zero-based).  */
4511a45ae5f8SJohn Marino 	      s = ((h->plt.offset - abed->plt->plt_entry_size)
4512a45ae5f8SJohn Marino                    / abed->plt->plt_entry_size);
45135796c8dcSSimon Schubert 	      /* K: Number of relocations for PLTResolve. */
45145796c8dcSSimon Schubert 	      if (info->shared)
45155796c8dcSSimon Schubert 		k = PLTRESOLVE_RELOCS_SHLIB;
45165796c8dcSSimon Schubert 	      else
45175796c8dcSSimon Schubert 		k = PLTRESOLVE_RELOCS;
45185796c8dcSSimon Schubert 	      /* Skip the PLTresolve relocations, and the relocations for
45195796c8dcSSimon Schubert 		 the other PLT slots. */
45205796c8dcSSimon Schubert 	      reloc_index = k + s * PLT_NON_JUMP_SLOT_RELOCS;
45215796c8dcSSimon Schubert 	      loc = (htab->srelplt2->contents + reloc_index
45225796c8dcSSimon Schubert 		     * sizeof (Elf32_External_Rel));
45235796c8dcSSimon Schubert 
45245796c8dcSSimon Schubert 	      rel.r_offset = (htab->elf.splt->output_section->vma
45255796c8dcSSimon Schubert 			      + htab->elf.splt->output_offset
45265796c8dcSSimon Schubert 			      + h->plt.offset + 2),
45275796c8dcSSimon Schubert 	      rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
45285796c8dcSSimon Schubert 	      bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
45295796c8dcSSimon Schubert 
45305796c8dcSSimon Schubert 	      /* Create the R_386_32 relocation referencing the beginning of
45315796c8dcSSimon Schubert 		 the PLT for this GOT entry.  */
45325796c8dcSSimon Schubert 	      rel.r_offset = (htab->elf.sgotplt->output_section->vma
45335796c8dcSSimon Schubert 			      + htab->elf.sgotplt->output_offset
45345796c8dcSSimon Schubert 			      + got_offset);
45355796c8dcSSimon Schubert 	      rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32);
45365796c8dcSSimon Schubert 	      bfd_elf32_swap_reloc_out (output_bfd, &rel,
45375796c8dcSSimon Schubert 					loc + sizeof (Elf32_External_Rel));
45385796c8dcSSimon Schubert 	    }
45395796c8dcSSimon Schubert 	}
45405796c8dcSSimon Schubert       else
45415796c8dcSSimon Schubert 	{
4542a45ae5f8SJohn Marino 	  memcpy (plt->contents + h->plt.offset, abed->plt->pic_plt_entry,
4543a45ae5f8SJohn Marino 		  abed->plt->plt_entry_size);
45445796c8dcSSimon Schubert 	  bfd_put_32 (output_bfd, got_offset,
4545a45ae5f8SJohn Marino 		      plt->contents + h->plt.offset
4546a45ae5f8SJohn Marino                       + abed->plt->plt_got_offset);
45475796c8dcSSimon Schubert 	}
45485796c8dcSSimon Schubert 
45495796c8dcSSimon Schubert       /* Fill in the entry in the global offset table.  */
45505796c8dcSSimon Schubert       bfd_put_32 (output_bfd,
45515796c8dcSSimon Schubert 		  (plt->output_section->vma
45525796c8dcSSimon Schubert 		   + plt->output_offset
45535796c8dcSSimon Schubert 		   + h->plt.offset
4554a45ae5f8SJohn Marino 		   + abed->plt->plt_lazy_offset),
45555796c8dcSSimon Schubert 		  gotplt->contents + got_offset);
45565796c8dcSSimon Schubert 
45575796c8dcSSimon Schubert       /* Fill in the entry in the .rel.plt section.  */
45585796c8dcSSimon Schubert       rel.r_offset = (gotplt->output_section->vma
45595796c8dcSSimon Schubert 		      + gotplt->output_offset
45605796c8dcSSimon Schubert 		      + got_offset);
45615796c8dcSSimon Schubert       if (h->dynindx == -1
45625796c8dcSSimon Schubert 	  || ((info->executable
45635796c8dcSSimon Schubert 	       || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
45645796c8dcSSimon Schubert 	      && h->def_regular
45655796c8dcSSimon Schubert 	       && h->type == STT_GNU_IFUNC))
45665796c8dcSSimon Schubert 	{
45675796c8dcSSimon Schubert 	  /* If an STT_GNU_IFUNC symbol is locally defined, generate
45685796c8dcSSimon Schubert 	     R_386_IRELATIVE instead of R_386_JUMP_SLOT.  Store addend
45695796c8dcSSimon Schubert 	     in the .got.plt section.  */
45705796c8dcSSimon Schubert 	  bfd_put_32 (output_bfd,
45715796c8dcSSimon Schubert 		      (h->root.u.def.value
45725796c8dcSSimon Schubert 		       + h->root.u.def.section->output_section->vma
45735796c8dcSSimon Schubert 		       + h->root.u.def.section->output_offset),
45745796c8dcSSimon Schubert 		      gotplt->contents + got_offset);
45755796c8dcSSimon Schubert 	  rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
4576a45ae5f8SJohn Marino 	  /* R_386_IRELATIVE comes last.  */
4577a45ae5f8SJohn Marino 	  plt_index = htab->next_irelative_index--;
45785796c8dcSSimon Schubert 	}
45795796c8dcSSimon Schubert       else
4580a45ae5f8SJohn Marino 	{
45815796c8dcSSimon Schubert 	  rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT);
4582a45ae5f8SJohn Marino 	  plt_index = htab->next_jump_slot_index++;
4583a45ae5f8SJohn Marino 	}
45845796c8dcSSimon Schubert       loc = relplt->contents + plt_index * sizeof (Elf32_External_Rel);
45855796c8dcSSimon Schubert       bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
45865796c8dcSSimon Schubert 
4587a45ae5f8SJohn Marino       /* Don't fill PLT entry for static executables.  */
4588a45ae5f8SJohn Marino       if (plt == htab->elf.splt)
4589a45ae5f8SJohn Marino 	{
4590a45ae5f8SJohn Marino 	  bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel),
4591a45ae5f8SJohn Marino 		      plt->contents + h->plt.offset
4592a45ae5f8SJohn Marino                       + abed->plt->plt_reloc_offset);
4593a45ae5f8SJohn Marino 	  bfd_put_32 (output_bfd, - (h->plt.offset
4594a45ae5f8SJohn Marino                                      + abed->plt->plt_plt_offset + 4),
4595a45ae5f8SJohn Marino 		      plt->contents + h->plt.offset
4596a45ae5f8SJohn Marino                       + abed->plt->plt_plt_offset);
4597a45ae5f8SJohn Marino 	}
4598a45ae5f8SJohn Marino 
45995796c8dcSSimon Schubert       if (!h->def_regular)
46005796c8dcSSimon Schubert 	{
46015796c8dcSSimon Schubert 	  /* Mark the symbol as undefined, rather than as defined in
46025796c8dcSSimon Schubert 	     the .plt section.  Leave the value if there were any
46035796c8dcSSimon Schubert 	     relocations where pointer equality matters (this is a clue
46045796c8dcSSimon Schubert 	     for the dynamic linker, to make function pointer
46055796c8dcSSimon Schubert 	     comparisons work between an application and shared
46065796c8dcSSimon Schubert 	     library), otherwise set it to zero.  If a function is only
46075796c8dcSSimon Schubert 	     called from a binary, there is no need to slow down
46085796c8dcSSimon Schubert 	     shared libraries because of that.  */
46095796c8dcSSimon Schubert 	  sym->st_shndx = SHN_UNDEF;
46105796c8dcSSimon Schubert 	  if (!h->pointer_equality_needed)
46115796c8dcSSimon Schubert 	    sym->st_value = 0;
46125796c8dcSSimon Schubert 	}
46135796c8dcSSimon Schubert     }
46145796c8dcSSimon Schubert 
46155796c8dcSSimon Schubert   if (h->got.offset != (bfd_vma) -1
46165796c8dcSSimon Schubert       && ! GOT_TLS_GD_ANY_P (elf_i386_hash_entry(h)->tls_type)
46175796c8dcSSimon Schubert       && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE) == 0)
46185796c8dcSSimon Schubert     {
46195796c8dcSSimon Schubert       Elf_Internal_Rela rel;
46205796c8dcSSimon Schubert 
46215796c8dcSSimon Schubert       /* This symbol has an entry in the global offset table.  Set it
46225796c8dcSSimon Schubert 	 up.  */
46235796c8dcSSimon Schubert 
46245796c8dcSSimon Schubert       if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
46255796c8dcSSimon Schubert 	abort ();
46265796c8dcSSimon Schubert 
46275796c8dcSSimon Schubert       rel.r_offset = (htab->elf.sgot->output_section->vma
46285796c8dcSSimon Schubert 		      + htab->elf.sgot->output_offset
46295796c8dcSSimon Schubert 		      + (h->got.offset & ~(bfd_vma) 1));
46305796c8dcSSimon Schubert 
46315796c8dcSSimon Schubert       /* If this is a static link, or it is a -Bsymbolic link and the
46325796c8dcSSimon Schubert 	 symbol is defined locally or was forced to be local because
46335796c8dcSSimon Schubert 	 of a version file, we just want to emit a RELATIVE reloc.
46345796c8dcSSimon Schubert 	 The entry in the global offset table will already have been
46355796c8dcSSimon Schubert 	 initialized in the relocate_section function.  */
46365796c8dcSSimon Schubert       if (h->def_regular
46375796c8dcSSimon Schubert 	  && h->type == STT_GNU_IFUNC)
46385796c8dcSSimon Schubert 	{
46395796c8dcSSimon Schubert 	  if (info->shared)
46405796c8dcSSimon Schubert 	    {
46415796c8dcSSimon Schubert 	      /* Generate R_386_GLOB_DAT.  */
46425796c8dcSSimon Schubert 	      goto do_glob_dat;
46435796c8dcSSimon Schubert 	    }
46445796c8dcSSimon Schubert 	  else
46455796c8dcSSimon Schubert 	    {
4646cf7f2e2dSJohn Marino 	      asection *plt;
4647cf7f2e2dSJohn Marino 
46485796c8dcSSimon Schubert 	      if (!h->pointer_equality_needed)
46495796c8dcSSimon Schubert 		abort ();
46505796c8dcSSimon Schubert 
46515796c8dcSSimon Schubert 	      /* For non-shared object, we can't use .got.plt, which
46525796c8dcSSimon Schubert 		 contains the real function addres if we need pointer
46535796c8dcSSimon Schubert 		 equality.  We load the GOT entry with the PLT entry.  */
4654cf7f2e2dSJohn Marino 	      plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
46555796c8dcSSimon Schubert 	      bfd_put_32 (output_bfd,
46565796c8dcSSimon Schubert 			  (plt->output_section->vma
46575796c8dcSSimon Schubert 			   + plt->output_offset + h->plt.offset),
46585796c8dcSSimon Schubert 			  htab->elf.sgot->contents + h->got.offset);
46595796c8dcSSimon Schubert 	      return TRUE;
46605796c8dcSSimon Schubert 	    }
46615796c8dcSSimon Schubert 	}
46625796c8dcSSimon Schubert       else if (info->shared
46635796c8dcSSimon Schubert 	       && SYMBOL_REFERENCES_LOCAL (info, h))
46645796c8dcSSimon Schubert 	{
46655796c8dcSSimon Schubert 	  BFD_ASSERT((h->got.offset & 1) != 0);
46665796c8dcSSimon Schubert 	  rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
46675796c8dcSSimon Schubert 	}
46685796c8dcSSimon Schubert       else
46695796c8dcSSimon Schubert 	{
46705796c8dcSSimon Schubert 	  BFD_ASSERT((h->got.offset & 1) == 0);
46715796c8dcSSimon Schubert do_glob_dat:
46725796c8dcSSimon Schubert 	  bfd_put_32 (output_bfd, (bfd_vma) 0,
46735796c8dcSSimon Schubert 		      htab->elf.sgot->contents + h->got.offset);
46745796c8dcSSimon Schubert 	  rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
46755796c8dcSSimon Schubert 	}
46765796c8dcSSimon Schubert 
4677*ef5ccd6cSJohn Marino       elf_append_rel (output_bfd, htab->elf.srelgot, &rel);
46785796c8dcSSimon Schubert     }
46795796c8dcSSimon Schubert 
46805796c8dcSSimon Schubert   if (h->needs_copy)
46815796c8dcSSimon Schubert     {
46825796c8dcSSimon Schubert       Elf_Internal_Rela rel;
46835796c8dcSSimon Schubert 
46845796c8dcSSimon Schubert       /* This symbol needs a copy reloc.  Set it up.  */
46855796c8dcSSimon Schubert 
46865796c8dcSSimon Schubert       if (h->dynindx == -1
46875796c8dcSSimon Schubert 	  || (h->root.type != bfd_link_hash_defined
46885796c8dcSSimon Schubert 	      && h->root.type != bfd_link_hash_defweak)
46895796c8dcSSimon Schubert 	  || htab->srelbss == NULL)
46905796c8dcSSimon Schubert 	abort ();
46915796c8dcSSimon Schubert 
46925796c8dcSSimon Schubert       rel.r_offset = (h->root.u.def.value
46935796c8dcSSimon Schubert 		      + h->root.u.def.section->output_section->vma
46945796c8dcSSimon Schubert 		      + h->root.u.def.section->output_offset);
46955796c8dcSSimon Schubert       rel.r_info = ELF32_R_INFO (h->dynindx, R_386_COPY);
4696*ef5ccd6cSJohn Marino       elf_append_rel (output_bfd, htab->srelbss, &rel);
46975796c8dcSSimon Schubert     }
46985796c8dcSSimon Schubert 
46995796c8dcSSimon Schubert   return TRUE;
47005796c8dcSSimon Schubert }
47015796c8dcSSimon Schubert 
47025796c8dcSSimon Schubert /* Finish up local dynamic symbol handling.  We set the contents of
47035796c8dcSSimon Schubert    various dynamic sections here.  */
47045796c8dcSSimon Schubert 
47055796c8dcSSimon Schubert static bfd_boolean
elf_i386_finish_local_dynamic_symbol(void ** slot,void * inf)47065796c8dcSSimon Schubert elf_i386_finish_local_dynamic_symbol (void **slot, void *inf)
47075796c8dcSSimon Schubert {
47085796c8dcSSimon Schubert   struct elf_link_hash_entry *h
47095796c8dcSSimon Schubert     = (struct elf_link_hash_entry *) *slot;
47105796c8dcSSimon Schubert   struct bfd_link_info *info
47115796c8dcSSimon Schubert     = (struct bfd_link_info *) inf;
47125796c8dcSSimon Schubert 
47135796c8dcSSimon Schubert   return elf_i386_finish_dynamic_symbol (info->output_bfd, info,
47145796c8dcSSimon Schubert 					 h, NULL);
47155796c8dcSSimon Schubert }
47165796c8dcSSimon Schubert 
47175796c8dcSSimon Schubert /* Used to decide how to sort relocs in an optimal manner for the
47185796c8dcSSimon Schubert    dynamic linker, before writing them out.  */
47195796c8dcSSimon Schubert 
47205796c8dcSSimon Schubert static enum elf_reloc_type_class
elf_i386_reloc_type_class(const Elf_Internal_Rela * rela)47215796c8dcSSimon Schubert elf_i386_reloc_type_class (const Elf_Internal_Rela *rela)
47225796c8dcSSimon Schubert {
47235796c8dcSSimon Schubert   switch (ELF32_R_TYPE (rela->r_info))
47245796c8dcSSimon Schubert     {
47255796c8dcSSimon Schubert     case R_386_RELATIVE:
47265796c8dcSSimon Schubert       return reloc_class_relative;
47275796c8dcSSimon Schubert     case R_386_JUMP_SLOT:
47285796c8dcSSimon Schubert       return reloc_class_plt;
47295796c8dcSSimon Schubert     case R_386_COPY:
47305796c8dcSSimon Schubert       return reloc_class_copy;
47315796c8dcSSimon Schubert     default:
47325796c8dcSSimon Schubert       return reloc_class_normal;
47335796c8dcSSimon Schubert     }
47345796c8dcSSimon Schubert }
47355796c8dcSSimon Schubert 
47365796c8dcSSimon Schubert /* Finish up the dynamic sections.  */
47375796c8dcSSimon Schubert 
47385796c8dcSSimon Schubert static bfd_boolean
elf_i386_finish_dynamic_sections(bfd * output_bfd,struct bfd_link_info * info)47395796c8dcSSimon Schubert elf_i386_finish_dynamic_sections (bfd *output_bfd,
47405796c8dcSSimon Schubert 				  struct bfd_link_info *info)
47415796c8dcSSimon Schubert {
47425796c8dcSSimon Schubert   struct elf_i386_link_hash_table *htab;
47435796c8dcSSimon Schubert   bfd *dynobj;
47445796c8dcSSimon Schubert   asection *sdyn;
4745a45ae5f8SJohn Marino   const struct elf_i386_backend_data *abed;
47465796c8dcSSimon Schubert 
47475796c8dcSSimon Schubert   htab = elf_i386_hash_table (info);
4748cf7f2e2dSJohn Marino   if (htab == NULL)
4749cf7f2e2dSJohn Marino     return FALSE;
4750cf7f2e2dSJohn Marino 
47515796c8dcSSimon Schubert   dynobj = htab->elf.dynobj;
4752*ef5ccd6cSJohn Marino   sdyn = bfd_get_linker_section (dynobj, ".dynamic");
4753a45ae5f8SJohn Marino   abed = get_elf_i386_backend_data (output_bfd);
47545796c8dcSSimon Schubert 
47555796c8dcSSimon Schubert   if (htab->elf.dynamic_sections_created)
47565796c8dcSSimon Schubert     {
47575796c8dcSSimon Schubert       Elf32_External_Dyn *dyncon, *dynconend;
47585796c8dcSSimon Schubert 
47595796c8dcSSimon Schubert       if (sdyn == NULL || htab->elf.sgot == NULL)
47605796c8dcSSimon Schubert 	abort ();
47615796c8dcSSimon Schubert 
47625796c8dcSSimon Schubert       dyncon = (Elf32_External_Dyn *) sdyn->contents;
47635796c8dcSSimon Schubert       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
47645796c8dcSSimon Schubert       for (; dyncon < dynconend; dyncon++)
47655796c8dcSSimon Schubert 	{
47665796c8dcSSimon Schubert 	  Elf_Internal_Dyn dyn;
47675796c8dcSSimon Schubert 	  asection *s;
47685796c8dcSSimon Schubert 
47695796c8dcSSimon Schubert 	  bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
47705796c8dcSSimon Schubert 
47715796c8dcSSimon Schubert 	  switch (dyn.d_tag)
47725796c8dcSSimon Schubert 	    {
47735796c8dcSSimon Schubert 	    default:
4774a45ae5f8SJohn Marino 	      if (abed->is_vxworks
47755796c8dcSSimon Schubert                   && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
47765796c8dcSSimon Schubert 		break;
47775796c8dcSSimon Schubert 	      continue;
47785796c8dcSSimon Schubert 
47795796c8dcSSimon Schubert 	    case DT_PLTGOT:
47805796c8dcSSimon Schubert 	      s = htab->elf.sgotplt;
47815796c8dcSSimon Schubert 	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
47825796c8dcSSimon Schubert 	      break;
47835796c8dcSSimon Schubert 
47845796c8dcSSimon Schubert 	    case DT_JMPREL:
47855796c8dcSSimon Schubert 	      s = htab->elf.srelplt;
47865796c8dcSSimon Schubert 	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
47875796c8dcSSimon Schubert 	      break;
47885796c8dcSSimon Schubert 
47895796c8dcSSimon Schubert 	    case DT_PLTRELSZ:
47905796c8dcSSimon Schubert 	      s = htab->elf.srelplt;
47915796c8dcSSimon Schubert 	      dyn.d_un.d_val = s->size;
47925796c8dcSSimon Schubert 	      break;
47935796c8dcSSimon Schubert 
47945796c8dcSSimon Schubert 	    case DT_RELSZ:
47955796c8dcSSimon Schubert 	      /* My reading of the SVR4 ABI indicates that the
47965796c8dcSSimon Schubert 		 procedure linkage table relocs (DT_JMPREL) should be
47975796c8dcSSimon Schubert 		 included in the overall relocs (DT_REL).  This is
47985796c8dcSSimon Schubert 		 what Solaris does.  However, UnixWare can not handle
47995796c8dcSSimon Schubert 		 that case.  Therefore, we override the DT_RELSZ entry
48005796c8dcSSimon Schubert 		 here to make it not include the JMPREL relocs.  */
48015796c8dcSSimon Schubert 	      s = htab->elf.srelplt;
48025796c8dcSSimon Schubert 	      if (s == NULL)
48035796c8dcSSimon Schubert 		continue;
48045796c8dcSSimon Schubert 	      dyn.d_un.d_val -= s->size;
48055796c8dcSSimon Schubert 	      break;
48065796c8dcSSimon Schubert 
48075796c8dcSSimon Schubert 	    case DT_REL:
48085796c8dcSSimon Schubert 	      /* We may not be using the standard ELF linker script.
48095796c8dcSSimon Schubert 		 If .rel.plt is the first .rel section, we adjust
48105796c8dcSSimon Schubert 		 DT_REL to not include it.  */
48115796c8dcSSimon Schubert 	      s = htab->elf.srelplt;
48125796c8dcSSimon Schubert 	      if (s == NULL)
48135796c8dcSSimon Schubert 		continue;
48145796c8dcSSimon Schubert 	      if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
48155796c8dcSSimon Schubert 		continue;
48165796c8dcSSimon Schubert 	      dyn.d_un.d_ptr += s->size;
48175796c8dcSSimon Schubert 	      break;
48185796c8dcSSimon Schubert 	    }
48195796c8dcSSimon Schubert 
48205796c8dcSSimon Schubert 	  bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
48215796c8dcSSimon Schubert 	}
48225796c8dcSSimon Schubert 
48235796c8dcSSimon Schubert       /* Fill in the first entry in the procedure linkage table.  */
48245796c8dcSSimon Schubert       if (htab->elf.splt && htab->elf.splt->size > 0)
48255796c8dcSSimon Schubert 	{
48265796c8dcSSimon Schubert 	  if (info->shared)
48275796c8dcSSimon Schubert 	    {
4828a45ae5f8SJohn Marino 	      memcpy (htab->elf.splt->contents, abed->plt->pic_plt0_entry,
4829a45ae5f8SJohn Marino 		      abed->plt->plt0_entry_size);
4830a45ae5f8SJohn Marino 	      memset (htab->elf.splt->contents + abed->plt->plt0_entry_size,
4831a45ae5f8SJohn Marino 		      abed->plt0_pad_byte,
4832a45ae5f8SJohn Marino 		      abed->plt->plt_entry_size - abed->plt->plt0_entry_size);
48335796c8dcSSimon Schubert 	    }
48345796c8dcSSimon Schubert 	  else
48355796c8dcSSimon Schubert 	    {
4836a45ae5f8SJohn Marino 	      memcpy (htab->elf.splt->contents, abed->plt->plt0_entry,
4837a45ae5f8SJohn Marino 		      abed->plt->plt0_entry_size);
4838a45ae5f8SJohn Marino 	      memset (htab->elf.splt->contents + abed->plt->plt0_entry_size,
4839a45ae5f8SJohn Marino 		      abed->plt0_pad_byte,
4840a45ae5f8SJohn Marino 		      abed->plt->plt_entry_size - abed->plt->plt0_entry_size);
48415796c8dcSSimon Schubert 	      bfd_put_32 (output_bfd,
48425796c8dcSSimon Schubert 			  (htab->elf.sgotplt->output_section->vma
48435796c8dcSSimon Schubert 			   + htab->elf.sgotplt->output_offset
48445796c8dcSSimon Schubert 			   + 4),
4845a45ae5f8SJohn Marino 			  htab->elf.splt->contents
4846a45ae5f8SJohn Marino                           + abed->plt->plt0_got1_offset);
48475796c8dcSSimon Schubert 	      bfd_put_32 (output_bfd,
48485796c8dcSSimon Schubert 			  (htab->elf.sgotplt->output_section->vma
48495796c8dcSSimon Schubert 			   + htab->elf.sgotplt->output_offset
48505796c8dcSSimon Schubert 			   + 8),
4851a45ae5f8SJohn Marino 			  htab->elf.splt->contents
4852a45ae5f8SJohn Marino                           + abed->plt->plt0_got2_offset);
48535796c8dcSSimon Schubert 
4854a45ae5f8SJohn Marino 	      if (abed->is_vxworks)
48555796c8dcSSimon Schubert 		{
48565796c8dcSSimon Schubert 		  Elf_Internal_Rela rel;
48575796c8dcSSimon Schubert 
48585796c8dcSSimon Schubert 		  /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 4.
48595796c8dcSSimon Schubert 		     On IA32 we use REL relocations so the addend goes in
48605796c8dcSSimon Schubert 		     the PLT directly.  */
48615796c8dcSSimon Schubert 		  rel.r_offset = (htab->elf.splt->output_section->vma
48625796c8dcSSimon Schubert 				  + htab->elf.splt->output_offset
4863a45ae5f8SJohn Marino 				  + abed->plt->plt0_got1_offset);
48645796c8dcSSimon Schubert 		  rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
48655796c8dcSSimon Schubert 		  bfd_elf32_swap_reloc_out (output_bfd, &rel,
48665796c8dcSSimon Schubert 					    htab->srelplt2->contents);
48675796c8dcSSimon Schubert 		  /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */
48685796c8dcSSimon Schubert 		  rel.r_offset = (htab->elf.splt->output_section->vma
48695796c8dcSSimon Schubert 				  + htab->elf.splt->output_offset
4870a45ae5f8SJohn Marino 				  + abed->plt->plt0_got2_offset);
48715796c8dcSSimon Schubert 		  rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
48725796c8dcSSimon Schubert 		  bfd_elf32_swap_reloc_out (output_bfd, &rel,
48735796c8dcSSimon Schubert 					    htab->srelplt2->contents +
48745796c8dcSSimon Schubert 					    sizeof (Elf32_External_Rel));
48755796c8dcSSimon Schubert 		}
48765796c8dcSSimon Schubert 	    }
48775796c8dcSSimon Schubert 
48785796c8dcSSimon Schubert 	  /* UnixWare sets the entsize of .plt to 4, although that doesn't
48795796c8dcSSimon Schubert 	     really seem like the right value.  */
48805796c8dcSSimon Schubert 	  elf_section_data (htab->elf.splt->output_section)
48815796c8dcSSimon Schubert 	    ->this_hdr.sh_entsize = 4;
48825796c8dcSSimon Schubert 
48835796c8dcSSimon Schubert 	  /* Correct the .rel.plt.unloaded relocations.  */
4884a45ae5f8SJohn Marino 	  if (abed->is_vxworks && !info->shared)
48855796c8dcSSimon Schubert 	    {
4886a45ae5f8SJohn Marino 	      int num_plts = (htab->elf.splt->size
4887a45ae5f8SJohn Marino                               / abed->plt->plt_entry_size) - 1;
48885796c8dcSSimon Schubert 	      unsigned char *p;
48895796c8dcSSimon Schubert 
48905796c8dcSSimon Schubert 	      p = htab->srelplt2->contents;
48915796c8dcSSimon Schubert 	      if (info->shared)
48925796c8dcSSimon Schubert 		p += PLTRESOLVE_RELOCS_SHLIB * sizeof (Elf32_External_Rel);
48935796c8dcSSimon Schubert 	      else
48945796c8dcSSimon Schubert 		p += PLTRESOLVE_RELOCS * sizeof (Elf32_External_Rel);
48955796c8dcSSimon Schubert 
48965796c8dcSSimon Schubert 	      for (; num_plts; num_plts--)
48975796c8dcSSimon Schubert 		{
48985796c8dcSSimon Schubert 		  Elf_Internal_Rela rel;
48995796c8dcSSimon Schubert 		  bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
49005796c8dcSSimon Schubert 		  rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
49015796c8dcSSimon Schubert 		  bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
49025796c8dcSSimon Schubert 		  p += sizeof (Elf32_External_Rel);
49035796c8dcSSimon Schubert 
49045796c8dcSSimon Schubert 		  bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
49055796c8dcSSimon Schubert 		  rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32);
49065796c8dcSSimon Schubert 		  bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
49075796c8dcSSimon Schubert 		  p += sizeof (Elf32_External_Rel);
49085796c8dcSSimon Schubert 		}
49095796c8dcSSimon Schubert 	    }
49105796c8dcSSimon Schubert 	}
49115796c8dcSSimon Schubert     }
49125796c8dcSSimon Schubert 
49135796c8dcSSimon Schubert   if (htab->elf.sgotplt)
49145796c8dcSSimon Schubert     {
4915c50c785cSJohn Marino       if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
4916c50c785cSJohn Marino 	{
4917c50c785cSJohn Marino 	  (*_bfd_error_handler)
4918c50c785cSJohn Marino 	    (_("discarded output section: `%A'"), htab->elf.sgotplt);
4919c50c785cSJohn Marino 	  return FALSE;
4920c50c785cSJohn Marino 	}
4921c50c785cSJohn Marino 
49225796c8dcSSimon Schubert       /* Fill in the first three entries in the global offset table.  */
49235796c8dcSSimon Schubert       if (htab->elf.sgotplt->size > 0)
49245796c8dcSSimon Schubert 	{
49255796c8dcSSimon Schubert 	  bfd_put_32 (output_bfd,
49265796c8dcSSimon Schubert 		      (sdyn == NULL ? 0
49275796c8dcSSimon Schubert 		       : sdyn->output_section->vma + sdyn->output_offset),
49285796c8dcSSimon Schubert 		      htab->elf.sgotplt->contents);
49295796c8dcSSimon Schubert 	  bfd_put_32 (output_bfd, 0, htab->elf.sgotplt->contents + 4);
49305796c8dcSSimon Schubert 	  bfd_put_32 (output_bfd, 0, htab->elf.sgotplt->contents + 8);
49315796c8dcSSimon Schubert 	}
49325796c8dcSSimon Schubert 
49335796c8dcSSimon Schubert       elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize = 4;
49345796c8dcSSimon Schubert     }
49355796c8dcSSimon Schubert 
4936a45ae5f8SJohn Marino   /* Adjust .eh_frame for .plt section.  */
4937*ef5ccd6cSJohn Marino   if (htab->plt_eh_frame != NULL
4938*ef5ccd6cSJohn Marino       && htab->plt_eh_frame->contents != NULL)
4939a45ae5f8SJohn Marino     {
4940a45ae5f8SJohn Marino       if (htab->elf.splt != NULL
4941a45ae5f8SJohn Marino 	  && htab->elf.splt->size != 0
4942a45ae5f8SJohn Marino 	  && (htab->elf.splt->flags & SEC_EXCLUDE) == 0
4943a45ae5f8SJohn Marino 	  && htab->elf.splt->output_section != NULL
4944a45ae5f8SJohn Marino 	  && htab->plt_eh_frame->output_section != NULL)
4945a45ae5f8SJohn Marino 	{
4946a45ae5f8SJohn Marino 	  bfd_vma plt_start = htab->elf.splt->output_section->vma;
4947a45ae5f8SJohn Marino 	  bfd_vma eh_frame_start = htab->plt_eh_frame->output_section->vma
4948a45ae5f8SJohn Marino 				   + htab->plt_eh_frame->output_offset
4949a45ae5f8SJohn Marino 				   + PLT_FDE_START_OFFSET;
4950a45ae5f8SJohn Marino 	  bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
4951a45ae5f8SJohn Marino 			     htab->plt_eh_frame->contents
4952a45ae5f8SJohn Marino 			     + PLT_FDE_START_OFFSET);
4953a45ae5f8SJohn Marino 	}
4954a45ae5f8SJohn Marino       if (htab->plt_eh_frame->sec_info_type
4955*ef5ccd6cSJohn Marino 	  == SEC_INFO_TYPE_EH_FRAME)
4956a45ae5f8SJohn Marino 	{
4957a45ae5f8SJohn Marino 	  if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
4958a45ae5f8SJohn Marino 						 htab->plt_eh_frame,
4959a45ae5f8SJohn Marino 						 htab->plt_eh_frame->contents))
4960a45ae5f8SJohn Marino 	    return FALSE;
4961a45ae5f8SJohn Marino 	}
4962a45ae5f8SJohn Marino     }
4963a45ae5f8SJohn Marino 
49645796c8dcSSimon Schubert   if (htab->elf.sgot && htab->elf.sgot->size > 0)
49655796c8dcSSimon Schubert     elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
49665796c8dcSSimon Schubert 
49675796c8dcSSimon Schubert   /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
49685796c8dcSSimon Schubert   htab_traverse (htab->loc_hash_table,
49695796c8dcSSimon Schubert 		 elf_i386_finish_local_dynamic_symbol,
49705796c8dcSSimon Schubert 		 info);
49715796c8dcSSimon Schubert 
49725796c8dcSSimon Schubert   return TRUE;
49735796c8dcSSimon Schubert }
49745796c8dcSSimon Schubert 
49755796c8dcSSimon Schubert /* Return address for Ith PLT stub in section PLT, for relocation REL
49765796c8dcSSimon Schubert    or (bfd_vma) -1 if it should not be included.  */
49775796c8dcSSimon Schubert 
49785796c8dcSSimon Schubert static bfd_vma
elf_i386_plt_sym_val(bfd_vma i,const asection * plt,const arelent * rel ATTRIBUTE_UNUSED)49795796c8dcSSimon Schubert elf_i386_plt_sym_val (bfd_vma i, const asection *plt,
49805796c8dcSSimon Schubert 		      const arelent *rel ATTRIBUTE_UNUSED)
49815796c8dcSSimon Schubert {
4982a45ae5f8SJohn Marino   return plt->vma + (i + 1) * GET_PLT_ENTRY_SIZE (plt->owner);
49835796c8dcSSimon Schubert }
49845796c8dcSSimon Schubert 
49855796c8dcSSimon Schubert /* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
49865796c8dcSSimon Schubert 
49875796c8dcSSimon Schubert static bfd_boolean
elf_i386_hash_symbol(struct elf_link_hash_entry * h)49885796c8dcSSimon Schubert elf_i386_hash_symbol (struct elf_link_hash_entry *h)
49895796c8dcSSimon Schubert {
49905796c8dcSSimon Schubert   if (h->plt.offset != (bfd_vma) -1
49915796c8dcSSimon Schubert       && !h->def_regular
49925796c8dcSSimon Schubert       && !h->pointer_equality_needed)
49935796c8dcSSimon Schubert     return FALSE;
49945796c8dcSSimon Schubert 
49955796c8dcSSimon Schubert   return _bfd_elf_hash_symbol (h);
49965796c8dcSSimon Schubert }
49975796c8dcSSimon Schubert 
49985796c8dcSSimon Schubert /* Hook called by the linker routine which adds symbols from an object
49995796c8dcSSimon Schubert    file.  */
50005796c8dcSSimon Schubert 
50015796c8dcSSimon Schubert static bfd_boolean
elf_i386_add_symbol_hook(bfd * abfd,struct bfd_link_info * info ATTRIBUTE_UNUSED,Elf_Internal_Sym * sym,const char ** namep ATTRIBUTE_UNUSED,flagword * flagsp ATTRIBUTE_UNUSED,asection ** secp ATTRIBUTE_UNUSED,bfd_vma * valp ATTRIBUTE_UNUSED)5002cf7f2e2dSJohn Marino elf_i386_add_symbol_hook (bfd * abfd,
50035796c8dcSSimon Schubert 			  struct bfd_link_info * info ATTRIBUTE_UNUSED,
50045796c8dcSSimon Schubert 			  Elf_Internal_Sym * sym,
50055796c8dcSSimon Schubert 			  const char ** namep ATTRIBUTE_UNUSED,
50065796c8dcSSimon Schubert 			  flagword * flagsp ATTRIBUTE_UNUSED,
50075796c8dcSSimon Schubert 			  asection ** secp ATTRIBUTE_UNUSED,
50085796c8dcSSimon Schubert 			  bfd_vma * valp ATTRIBUTE_UNUSED)
50095796c8dcSSimon Schubert {
5010cf7f2e2dSJohn Marino   if ((abfd->flags & DYNAMIC) == 0
5011a45ae5f8SJohn Marino       && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
5012a45ae5f8SJohn Marino 	  || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
5013a45ae5f8SJohn Marino     elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
50145796c8dcSSimon Schubert 
50155796c8dcSSimon Schubert   return TRUE;
50165796c8dcSSimon Schubert }
50175796c8dcSSimon Schubert 
50185796c8dcSSimon Schubert #define TARGET_LITTLE_SYM		bfd_elf32_i386_vec
50195796c8dcSSimon Schubert #define TARGET_LITTLE_NAME		"elf32-i386"
50205796c8dcSSimon Schubert #define ELF_ARCH			bfd_arch_i386
5021c50c785cSJohn Marino #define ELF_TARGET_ID			I386_ELF_DATA
50225796c8dcSSimon Schubert #define ELF_MACHINE_CODE		EM_386
50235796c8dcSSimon Schubert #define ELF_MAXPAGESIZE			0x1000
50245796c8dcSSimon Schubert 
50255796c8dcSSimon Schubert #define elf_backend_can_gc_sections	1
50265796c8dcSSimon Schubert #define elf_backend_can_refcount	1
50275796c8dcSSimon Schubert #define elf_backend_want_got_plt	1
50285796c8dcSSimon Schubert #define elf_backend_plt_readonly	1
50295796c8dcSSimon Schubert #define elf_backend_want_plt_sym	0
50305796c8dcSSimon Schubert #define elf_backend_got_header_size	12
5031a45ae5f8SJohn Marino #define elf_backend_plt_alignment	4
50325796c8dcSSimon Schubert 
50335796c8dcSSimon Schubert /* Support RELA for objdump of prelink objects.  */
50345796c8dcSSimon Schubert #define elf_info_to_howto		      elf_i386_info_to_howto_rel
50355796c8dcSSimon Schubert #define elf_info_to_howto_rel		      elf_i386_info_to_howto_rel
50365796c8dcSSimon Schubert 
50375796c8dcSSimon Schubert #define bfd_elf32_mkobject		      elf_i386_mkobject
50385796c8dcSSimon Schubert 
50395796c8dcSSimon Schubert #define bfd_elf32_bfd_is_local_label_name     elf_i386_is_local_label_name
50405796c8dcSSimon Schubert #define bfd_elf32_bfd_link_hash_table_create  elf_i386_link_hash_table_create
50415796c8dcSSimon Schubert #define bfd_elf32_bfd_link_hash_table_free    elf_i386_link_hash_table_free
50425796c8dcSSimon Schubert #define bfd_elf32_bfd_reloc_type_lookup	      elf_i386_reloc_type_lookup
50435796c8dcSSimon Schubert #define bfd_elf32_bfd_reloc_name_lookup	      elf_i386_reloc_name_lookup
50445796c8dcSSimon Schubert 
50455796c8dcSSimon Schubert #define elf_backend_adjust_dynamic_symbol     elf_i386_adjust_dynamic_symbol
50465796c8dcSSimon Schubert #define elf_backend_relocs_compatible	      _bfd_elf_relocs_compatible
50475796c8dcSSimon Schubert #define elf_backend_check_relocs	      elf_i386_check_relocs
50485796c8dcSSimon Schubert #define elf_backend_copy_indirect_symbol      elf_i386_copy_indirect_symbol
50495796c8dcSSimon Schubert #define elf_backend_create_dynamic_sections   elf_i386_create_dynamic_sections
50505796c8dcSSimon Schubert #define elf_backend_fake_sections	      elf_i386_fake_sections
50515796c8dcSSimon Schubert #define elf_backend_finish_dynamic_sections   elf_i386_finish_dynamic_sections
50525796c8dcSSimon Schubert #define elf_backend_finish_dynamic_symbol     elf_i386_finish_dynamic_symbol
50535796c8dcSSimon Schubert #define elf_backend_gc_mark_hook	      elf_i386_gc_mark_hook
50545796c8dcSSimon Schubert #define elf_backend_gc_sweep_hook	      elf_i386_gc_sweep_hook
50555796c8dcSSimon Schubert #define elf_backend_grok_prstatus	      elf_i386_grok_prstatus
50565796c8dcSSimon Schubert #define elf_backend_grok_psinfo		      elf_i386_grok_psinfo
50575796c8dcSSimon Schubert #define elf_backend_reloc_type_class	      elf_i386_reloc_type_class
50585796c8dcSSimon Schubert #define elf_backend_relocate_section	      elf_i386_relocate_section
50595796c8dcSSimon Schubert #define elf_backend_size_dynamic_sections     elf_i386_size_dynamic_sections
50605796c8dcSSimon Schubert #define elf_backend_always_size_sections      elf_i386_always_size_sections
50615796c8dcSSimon Schubert #define elf_backend_omit_section_dynsym \
50625796c8dcSSimon Schubert   ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
50635796c8dcSSimon Schubert #define elf_backend_plt_sym_val		      elf_i386_plt_sym_val
50645796c8dcSSimon Schubert #define elf_backend_hash_symbol		      elf_i386_hash_symbol
50655796c8dcSSimon Schubert #define elf_backend_add_symbol_hook           elf_i386_add_symbol_hook
50665796c8dcSSimon Schubert #undef	elf_backend_post_process_headers
50675796c8dcSSimon Schubert #define	elf_backend_post_process_headers	_bfd_elf_set_osabi
50685796c8dcSSimon Schubert 
50695796c8dcSSimon Schubert #include "elf32-target.h"
50705796c8dcSSimon Schubert 
50715796c8dcSSimon Schubert /* FreeBSD support.  */
50725796c8dcSSimon Schubert 
50735796c8dcSSimon Schubert #undef	TARGET_LITTLE_SYM
50745796c8dcSSimon Schubert #define	TARGET_LITTLE_SYM		bfd_elf32_i386_freebsd_vec
50755796c8dcSSimon Schubert #undef	TARGET_LITTLE_NAME
50765796c8dcSSimon Schubert #define	TARGET_LITTLE_NAME		"elf32-i386-freebsd"
50775796c8dcSSimon Schubert #undef	ELF_OSABI
50785796c8dcSSimon Schubert #define	ELF_OSABI			ELFOSABI_FREEBSD
50795796c8dcSSimon Schubert 
50805796c8dcSSimon Schubert /* The kernel recognizes executables as valid only if they carry a
50815796c8dcSSimon Schubert    "FreeBSD" label in the ELF header.  So we put this label on all
50825796c8dcSSimon Schubert    executables and (for simplicity) also all other object files.  */
50835796c8dcSSimon Schubert 
50845796c8dcSSimon Schubert static void
elf_i386_fbsd_post_process_headers(bfd * abfd,struct bfd_link_info * info)50855796c8dcSSimon Schubert elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
50865796c8dcSSimon Schubert {
50875796c8dcSSimon Schubert   _bfd_elf_set_osabi (abfd, info);
50885796c8dcSSimon Schubert 
50895796c8dcSSimon Schubert #ifdef OLD_FREEBSD_ABI_LABEL
50905796c8dcSSimon Schubert   /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard.  */
50915796c8dcSSimon Schubert   memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
50925796c8dcSSimon Schubert #endif
50935796c8dcSSimon Schubert }
50945796c8dcSSimon Schubert 
50955796c8dcSSimon Schubert #undef	elf_backend_post_process_headers
50965796c8dcSSimon Schubert #define	elf_backend_post_process_headers	elf_i386_fbsd_post_process_headers
50975796c8dcSSimon Schubert #undef	elf32_bed
50985796c8dcSSimon Schubert #define	elf32_bed				elf32_i386_fbsd_bed
50995796c8dcSSimon Schubert 
51005796c8dcSSimon Schubert #undef elf_backend_add_symbol_hook
51015796c8dcSSimon Schubert 
51025796c8dcSSimon Schubert #include "elf32-target.h"
51035796c8dcSSimon Schubert 
5104cf7f2e2dSJohn Marino /* Solaris 2.  */
5105cf7f2e2dSJohn Marino 
5106cf7f2e2dSJohn Marino #undef	TARGET_LITTLE_SYM
5107cf7f2e2dSJohn Marino #define	TARGET_LITTLE_SYM		bfd_elf32_i386_sol2_vec
5108cf7f2e2dSJohn Marino #undef	TARGET_LITTLE_NAME
5109cf7f2e2dSJohn Marino #define	TARGET_LITTLE_NAME		"elf32-i386-sol2"
5110cf7f2e2dSJohn Marino 
5111cf7f2e2dSJohn Marino /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
5112cf7f2e2dSJohn Marino    objects won't be recognized.  */
5113cf7f2e2dSJohn Marino #undef ELF_OSABI
5114cf7f2e2dSJohn Marino 
5115cf7f2e2dSJohn Marino #undef	elf32_bed
5116cf7f2e2dSJohn Marino #define	elf32_bed			elf32_i386_sol2_bed
5117cf7f2e2dSJohn Marino 
5118c50c785cSJohn Marino /* The 32-bit static TLS arena size is rounded to the nearest 8-byte
5119c50c785cSJohn Marino    boundary.  */
5120c50c785cSJohn Marino #undef elf_backend_static_tls_alignment
5121c50c785cSJohn Marino #define elf_backend_static_tls_alignment 8
5122c50c785cSJohn Marino 
5123cf7f2e2dSJohn Marino /* The Solaris 2 ABI requires a plt symbol on all platforms.
5124cf7f2e2dSJohn Marino 
5125cf7f2e2dSJohn Marino    Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
5126cf7f2e2dSJohn Marino    File, p.63.  */
5127cf7f2e2dSJohn Marino #undef elf_backend_want_plt_sym
5128cf7f2e2dSJohn Marino #define elf_backend_want_plt_sym	1
5129cf7f2e2dSJohn Marino 
5130cf7f2e2dSJohn Marino #include "elf32-target.h"
5131cf7f2e2dSJohn Marino 
5132a45ae5f8SJohn Marino /* Native Client support.  */
5133a45ae5f8SJohn Marino 
5134a45ae5f8SJohn Marino #undef	TARGET_LITTLE_SYM
5135a45ae5f8SJohn Marino #define	TARGET_LITTLE_SYM		bfd_elf32_i386_nacl_vec
5136a45ae5f8SJohn Marino #undef	TARGET_LITTLE_NAME
5137a45ae5f8SJohn Marino #define	TARGET_LITTLE_NAME		"elf32-i386-nacl"
5138a45ae5f8SJohn Marino #undef	elf32_bed
5139a45ae5f8SJohn Marino #define	elf32_bed			elf32_i386_nacl_bed
5140a45ae5f8SJohn Marino 
5141a45ae5f8SJohn Marino #undef	ELF_MAXPAGESIZE
5142a45ae5f8SJohn Marino #define	ELF_MAXPAGESIZE			0x10000
5143a45ae5f8SJohn Marino 
5144a45ae5f8SJohn Marino /* Restore defaults.  */
5145a45ae5f8SJohn Marino #undef	ELF_OSABI
5146a45ae5f8SJohn Marino #undef	elf_backend_want_plt_sym
5147a45ae5f8SJohn Marino #define elf_backend_want_plt_sym	0
5148a45ae5f8SJohn Marino #undef	elf_backend_post_process_headers
5149a45ae5f8SJohn Marino #define	elf_backend_post_process_headers	_bfd_elf_set_osabi
5150a45ae5f8SJohn Marino #undef	elf_backend_static_tls_alignment
5151a45ae5f8SJohn Marino 
5152a45ae5f8SJohn Marino /* NaCl uses substantially different PLT entries for the same effects.  */
5153a45ae5f8SJohn Marino 
5154a45ae5f8SJohn Marino #undef	elf_backend_plt_alignment
5155a45ae5f8SJohn Marino #define elf_backend_plt_alignment	5
5156a45ae5f8SJohn Marino #define NACL_PLT_ENTRY_SIZE		64
5157a45ae5f8SJohn Marino #define	NACLMASK			0xe0 /* 32-byte alignment mask.  */
5158a45ae5f8SJohn Marino 
5159a45ae5f8SJohn Marino static const bfd_byte elf_i386_nacl_plt0_entry[] =
5160a45ae5f8SJohn Marino   {
5161a45ae5f8SJohn Marino     0xff, 0x35,			  /* pushl contents of address */
5162a45ae5f8SJohn Marino     0, 0, 0, 0,			  /* replaced with address of .got + 4.	 */
5163a45ae5f8SJohn Marino     0x8b, 0x0d,                   /* movl contents of address, %ecx */
5164a45ae5f8SJohn Marino     0, 0, 0, 0,			  /* replaced with address of .got + 8.	 */
5165a45ae5f8SJohn Marino     0x83, 0xe1, NACLMASK,	  /* andl $NACLMASK, %ecx */
5166a45ae5f8SJohn Marino     0xff, 0xe1			  /* jmp *%ecx */
5167a45ae5f8SJohn Marino   };
5168a45ae5f8SJohn Marino 
5169a45ae5f8SJohn Marino static const bfd_byte elf_i386_nacl_plt_entry[NACL_PLT_ENTRY_SIZE] =
5170a45ae5f8SJohn Marino   {
5171a45ae5f8SJohn Marino     0x8b, 0x0d,				/* movl contents of address, %ecx */
5172a45ae5f8SJohn Marino     0, 0, 0, 0,				/* replaced with GOT slot address.  */
5173a45ae5f8SJohn Marino     0x83, 0xe1, NACLMASK,		/* andl $NACLMASK, %ecx */
5174a45ae5f8SJohn Marino     0xff, 0xe1,				/* jmp *%ecx */
5175a45ae5f8SJohn Marino 
5176a45ae5f8SJohn Marino     /* Pad to the next 32-byte boundary with nop instructions.	*/
5177a45ae5f8SJohn Marino     0x90,
5178a45ae5f8SJohn Marino     0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
5179a45ae5f8SJohn Marino     0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
5180a45ae5f8SJohn Marino 
5181a45ae5f8SJohn Marino     /* Lazy GOT entries point here (32-byte aligned).  */
5182a45ae5f8SJohn Marino     0x68,			       /* pushl immediate */
5183a45ae5f8SJohn Marino     0, 0, 0, 0,			       /* replaced with reloc offset.  */
5184a45ae5f8SJohn Marino     0xe9,			       /* jmp relative */
5185a45ae5f8SJohn Marino     0, 0, 0, 0,			       /* replaced with offset to .plt.	 */
5186a45ae5f8SJohn Marino 
5187a45ae5f8SJohn Marino     /* Pad to the next 32-byte boundary with nop instructions.	*/
5188a45ae5f8SJohn Marino     0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
5189a45ae5f8SJohn Marino     0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
5190a45ae5f8SJohn Marino     0x90, 0x90
5191a45ae5f8SJohn Marino   };
5192a45ae5f8SJohn Marino 
5193a45ae5f8SJohn Marino static const bfd_byte
5194a45ae5f8SJohn Marino elf_i386_nacl_pic_plt0_entry[sizeof (elf_i386_nacl_plt0_entry)] =
5195a45ae5f8SJohn Marino   {
5196a45ae5f8SJohn Marino     0xff, 0x73, 0x04,		/* pushl 4(%ebx) */
5197a45ae5f8SJohn Marino     0x8b, 0x4b, 0x08,		/* mov 0x8(%ebx), %ecx */
5198a45ae5f8SJohn Marino     0x83, 0xe1, 0xe0,		/* and $NACLMASK, %ecx */
5199a45ae5f8SJohn Marino     0xff, 0xe1,			/* jmp *%ecx */
5200*ef5ccd6cSJohn Marino 
5201*ef5ccd6cSJohn Marino     /* This is expected to be the same size as elf_i386_nacl_plt0_entry,
5202*ef5ccd6cSJohn Marino        so pad to that size with nop instructions.  */
5203*ef5ccd6cSJohn Marino     0x90, 0x90, 0x90, 0x90, 0x90, 0x90
5204a45ae5f8SJohn Marino   };
5205a45ae5f8SJohn Marino 
5206a45ae5f8SJohn Marino static const bfd_byte elf_i386_nacl_pic_plt_entry[NACL_PLT_ENTRY_SIZE] =
5207a45ae5f8SJohn Marino   {
5208a45ae5f8SJohn Marino     0x8b, 0x8b,          /* movl offset(%ebx), %ecx */
5209a45ae5f8SJohn Marino     0, 0, 0, 0,          /* replaced with offset of this symbol in .got.  */
5210a45ae5f8SJohn Marino     0x83, 0xe1, 0xe0,    /* andl $NACLMASK, %ecx */
5211a45ae5f8SJohn Marino     0xff, 0xe1,          /* jmp *%ecx */
5212a45ae5f8SJohn Marino 
5213a45ae5f8SJohn Marino     /* Pad to the next 32-byte boundary with nop instructions.	*/
5214a45ae5f8SJohn Marino     0x90,
5215a45ae5f8SJohn Marino     0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
5216a45ae5f8SJohn Marino     0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
5217a45ae5f8SJohn Marino 
5218a45ae5f8SJohn Marino     /* Lazy GOT entries point here (32-byte aligned).  */
5219a45ae5f8SJohn Marino     0x68,                /* pushl immediate */
5220a45ae5f8SJohn Marino     0, 0, 0, 0,          /* replaced with offset into relocation table.  */
5221a45ae5f8SJohn Marino     0xe9,                /* jmp relative */
5222a45ae5f8SJohn Marino     0, 0, 0, 0,          /* replaced with offset to start of .plt.  */
5223a45ae5f8SJohn Marino 
5224a45ae5f8SJohn Marino     /* Pad to the next 32-byte boundary with nop instructions.	*/
5225a45ae5f8SJohn Marino     0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
5226a45ae5f8SJohn Marino     0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
5227a45ae5f8SJohn Marino     0x90, 0x90
5228a45ae5f8SJohn Marino   };
5229a45ae5f8SJohn Marino 
5230a45ae5f8SJohn Marino static const bfd_byte elf_i386_nacl_eh_frame_plt[] =
5231a45ae5f8SJohn Marino   {
5232a45ae5f8SJohn Marino #if (PLT_CIE_LENGTH != 20                               \
5233a45ae5f8SJohn Marino      || PLT_FDE_LENGTH != 36                            \
5234a45ae5f8SJohn Marino      || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8  \
5235a45ae5f8SJohn Marino      || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12)
5236a45ae5f8SJohn Marino # error "Need elf_i386_backend_data parameters for eh_frame_plt offsets!"
5237a45ae5f8SJohn Marino #endif
5238a45ae5f8SJohn Marino     PLT_CIE_LENGTH, 0, 0, 0,		/* CIE length */
5239a45ae5f8SJohn Marino     0, 0, 0, 0,                         /* CIE ID */
5240a45ae5f8SJohn Marino     1,                                  /* CIE version */
5241a45ae5f8SJohn Marino     'z', 'R', 0,                        /* Augmentation string */
5242a45ae5f8SJohn Marino     1,                                  /* Code alignment factor */
5243a45ae5f8SJohn Marino     0x7c,                               /* Data alignment factor: -4 */
5244a45ae5f8SJohn Marino     8,                                  /* Return address column */
5245a45ae5f8SJohn Marino     1,					/* Augmentation size */
5246a45ae5f8SJohn Marino     DW_EH_PE_pcrel | DW_EH_PE_sdata4,	/* FDE encoding */
5247a45ae5f8SJohn Marino     DW_CFA_def_cfa, 4, 4,		/* DW_CFA_def_cfa: r4 (esp) ofs 4 */
5248a45ae5f8SJohn Marino     DW_CFA_offset + 8, 1,		/* DW_CFA_offset: r8 (eip) at cfa-4 */
5249a45ae5f8SJohn Marino     DW_CFA_nop, DW_CFA_nop,
5250a45ae5f8SJohn Marino 
5251a45ae5f8SJohn Marino     PLT_FDE_LENGTH, 0, 0, 0,     /* FDE length */
5252a45ae5f8SJohn Marino     PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
5253a45ae5f8SJohn Marino     0, 0, 0, 0,                  /* R_386_PC32 .plt goes here */
5254a45ae5f8SJohn Marino     0, 0, 0, 0,                  /* .plt size goes here */
5255a45ae5f8SJohn Marino     0,                           /* Augmentation size */
5256a45ae5f8SJohn Marino     DW_CFA_def_cfa_offset, 8,    /* DW_CFA_def_cfa_offset: 8 */
5257a45ae5f8SJohn Marino     DW_CFA_advance_loc + 6,      /* DW_CFA_advance_loc: 6 to __PLT__+6 */
5258a45ae5f8SJohn Marino     DW_CFA_def_cfa_offset, 12,   /* DW_CFA_def_cfa_offset: 12 */
5259a45ae5f8SJohn Marino     DW_CFA_advance_loc + 58,     /* DW_CFA_advance_loc: 58 to __PLT__+64 */
5260a45ae5f8SJohn Marino     DW_CFA_def_cfa_expression,   /* DW_CFA_def_cfa_expression */
5261a45ae5f8SJohn Marino     13,                          /* Block length */
5262a45ae5f8SJohn Marino     DW_OP_breg4, 4,              /* DW_OP_breg4 (esp): 4 */
5263a45ae5f8SJohn Marino     DW_OP_breg8, 0,              /* DW_OP_breg8 (eip): 0 */
5264a45ae5f8SJohn Marino     DW_OP_const1u, 63, DW_OP_and, DW_OP_const1u, 37, DW_OP_ge,
5265a45ae5f8SJohn Marino     DW_OP_lit2, DW_OP_shl, DW_OP_plus,
5266a45ae5f8SJohn Marino     DW_CFA_nop, DW_CFA_nop
5267a45ae5f8SJohn Marino   };
5268a45ae5f8SJohn Marino 
5269a45ae5f8SJohn Marino static const struct elf_i386_plt_layout elf_i386_nacl_plt =
5270a45ae5f8SJohn Marino   {
5271a45ae5f8SJohn Marino     elf_i386_nacl_plt0_entry,		/* plt0_entry */
5272a45ae5f8SJohn Marino     sizeof (elf_i386_nacl_plt0_entry),	/* plt0_entry_size */
5273a45ae5f8SJohn Marino     2,					/* plt0_got1_offset */
5274a45ae5f8SJohn Marino     8,					/* plt0_got2_offset */
5275a45ae5f8SJohn Marino     elf_i386_nacl_plt_entry,		/* plt_entry */
5276a45ae5f8SJohn Marino     NACL_PLT_ENTRY_SIZE,		/* plt_entry_size */
5277a45ae5f8SJohn Marino     2,					/* plt_got_offset */
5278a45ae5f8SJohn Marino     33,					/* plt_reloc_offset */
5279a45ae5f8SJohn Marino     38,					/* plt_plt_offset */
5280a45ae5f8SJohn Marino     32,					/* plt_lazy_offset */
5281a45ae5f8SJohn Marino     elf_i386_nacl_pic_plt0_entry,	/* pic_plt0_entry */
5282a45ae5f8SJohn Marino     elf_i386_nacl_pic_plt_entry,	/* pic_plt_entry */
5283a45ae5f8SJohn Marino     elf_i386_nacl_eh_frame_plt,		/* eh_frame_plt */
5284a45ae5f8SJohn Marino     sizeof (elf_i386_nacl_eh_frame_plt),/* eh_frame_plt_size */
5285a45ae5f8SJohn Marino   };
5286a45ae5f8SJohn Marino 
5287a45ae5f8SJohn Marino static const struct elf_i386_backend_data elf_i386_nacl_arch_bed =
5288a45ae5f8SJohn Marino   {
5289a45ae5f8SJohn Marino     &elf_i386_nacl_plt,                      /* plt */
5290a45ae5f8SJohn Marino     0x90,				/* plt0_pad_byte: nop insn */
5291a45ae5f8SJohn Marino     0,                                  /* is_vxworks */
5292a45ae5f8SJohn Marino   };
5293a45ae5f8SJohn Marino 
5294a45ae5f8SJohn Marino #undef	elf_backend_arch_data
5295a45ae5f8SJohn Marino #define elf_backend_arch_data	&elf_i386_nacl_arch_bed
5296a45ae5f8SJohn Marino 
5297*ef5ccd6cSJohn Marino #undef	elf_backend_modify_segment_map
5298*ef5ccd6cSJohn Marino #define	elf_backend_modify_segment_map		nacl_modify_segment_map
5299*ef5ccd6cSJohn Marino #undef	elf_backend_modify_program_headers
5300*ef5ccd6cSJohn Marino #define	elf_backend_modify_program_headers	nacl_modify_program_headers
5301*ef5ccd6cSJohn Marino 
5302a45ae5f8SJohn Marino #include "elf32-target.h"
5303a45ae5f8SJohn Marino 
5304*ef5ccd6cSJohn Marino /* Restore defaults.  */
5305*ef5ccd6cSJohn Marino #undef	elf_backend_modify_segment_map
5306*ef5ccd6cSJohn Marino #undef	elf_backend_modify_program_headers
5307*ef5ccd6cSJohn Marino 
53085796c8dcSSimon Schubert /* VxWorks support.  */
53095796c8dcSSimon Schubert 
53105796c8dcSSimon Schubert #undef	TARGET_LITTLE_SYM
53115796c8dcSSimon Schubert #define TARGET_LITTLE_SYM		bfd_elf32_i386_vxworks_vec
53125796c8dcSSimon Schubert #undef	TARGET_LITTLE_NAME
53135796c8dcSSimon Schubert #define TARGET_LITTLE_NAME		"elf32-i386-vxworks"
53145796c8dcSSimon Schubert #undef	ELF_OSABI
5315a45ae5f8SJohn Marino #undef	elf_backend_plt_alignment
5316a45ae5f8SJohn Marino #define elf_backend_plt_alignment	4
53175796c8dcSSimon Schubert 
5318a45ae5f8SJohn Marino static const struct elf_i386_backend_data elf_i386_vxworks_arch_bed =
53195796c8dcSSimon Schubert   {
5320a45ae5f8SJohn Marino     &elf_i386_plt,                      /* plt */
5321a45ae5f8SJohn Marino     0x90,                               /* plt0_pad_byte */
5322a45ae5f8SJohn Marino     1,                                  /* is_vxworks */
5323a45ae5f8SJohn Marino   };
53245796c8dcSSimon Schubert 
5325a45ae5f8SJohn Marino #undef	elf_backend_arch_data
5326a45ae5f8SJohn Marino #define	elf_backend_arch_data	&elf_i386_vxworks_arch_bed
53275796c8dcSSimon Schubert 
53285796c8dcSSimon Schubert #undef elf_backend_relocs_compatible
53295796c8dcSSimon Schubert #undef elf_backend_post_process_headers
53305796c8dcSSimon Schubert #undef elf_backend_add_symbol_hook
53315796c8dcSSimon Schubert #define elf_backend_add_symbol_hook \
53325796c8dcSSimon Schubert   elf_vxworks_add_symbol_hook
53335796c8dcSSimon Schubert #undef elf_backend_link_output_symbol_hook
53345796c8dcSSimon Schubert #define elf_backend_link_output_symbol_hook \
53355796c8dcSSimon Schubert   elf_vxworks_link_output_symbol_hook
53365796c8dcSSimon Schubert #undef elf_backend_emit_relocs
53375796c8dcSSimon Schubert #define elf_backend_emit_relocs			elf_vxworks_emit_relocs
53385796c8dcSSimon Schubert #undef elf_backend_final_write_processing
53395796c8dcSSimon Schubert #define elf_backend_final_write_processing \
53405796c8dcSSimon Schubert   elf_vxworks_final_write_processing
5341c50c785cSJohn Marino #undef elf_backend_static_tls_alignment
53425796c8dcSSimon Schubert 
53435796c8dcSSimon Schubert /* On VxWorks, we emit relocations against _PROCEDURE_LINKAGE_TABLE_, so
53445796c8dcSSimon Schubert    define it.  */
53455796c8dcSSimon Schubert #undef elf_backend_want_plt_sym
53465796c8dcSSimon Schubert #define elf_backend_want_plt_sym	1
53475796c8dcSSimon Schubert 
53485796c8dcSSimon Schubert #undef	elf32_bed
53495796c8dcSSimon Schubert #define elf32_bed				elf32_i386_vxworks_bed
53505796c8dcSSimon Schubert 
53515796c8dcSSimon Schubert #include "elf32-target.h"
5352