Home | History | Annotate | Line # | Download | only in bfd
      1   1.1     skrll /* Intel 80386/80486-specific support for 32-bit ELF
      2  1.17  christos    Copyright (C) 1993-2026 Free Software Foundation, Inc.
      3   1.1     skrll 
      4   1.1     skrll    This file is part of BFD, the Binary File Descriptor library.
      5   1.1     skrll 
      6   1.1     skrll    This program is free software; you can redistribute it and/or modify
      7   1.1     skrll    it under the terms of the GNU General Public License as published by
      8   1.1     skrll    the Free Software Foundation; either version 3 of the License, or
      9   1.1     skrll    (at your option) any later version.
     10   1.1     skrll 
     11   1.1     skrll    This program is distributed in the hope that it will be useful,
     12   1.1     skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   1.1     skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14   1.1     skrll    GNU General Public License for more details.
     15   1.1     skrll 
     16   1.1     skrll    You should have received a copy of the GNU General Public License
     17   1.1     skrll    along with this program; if not, write to the Free Software
     18   1.1     skrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19   1.1     skrll    MA 02110-1301, USA.  */
     20   1.1     skrll 
     21  1.10  christos #include "elfxx-x86.h"
     22   1.1     skrll #include "elf-vxworks.h"
     23   1.5  christos #include "dwarf2.h"
     24   1.6  christos #include "opcode/i386.h"
     25   1.1     skrll 
     26   1.1     skrll /* 386 uses REL relocations instead of RELA.  */
     27   1.1     skrll #define USE_REL	1
     28   1.1     skrll 
     29   1.1     skrll static reloc_howto_type elf_howto_table[]=
     30   1.1     skrll {
     31  1.13  christos   HOWTO(R_386_NONE, 0, 0, 0, false, 0, complain_overflow_dont,
     32   1.1     skrll 	bfd_elf_generic_reloc, "R_386_NONE",
     33  1.13  christos 	true, 0x00000000, 0x00000000, false),
     34  1.13  christos   HOWTO(R_386_32, 0, 4, 32, false, 0, complain_overflow_dont,
     35   1.1     skrll 	bfd_elf_generic_reloc, "R_386_32",
     36  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
     37  1.13  christos   HOWTO(R_386_PC32, 0, 4, 32, true, 0, complain_overflow_dont,
     38   1.1     skrll 	bfd_elf_generic_reloc, "R_386_PC32",
     39  1.13  christos 	true, 0xffffffff, 0xffffffff, true),
     40  1.13  christos   HOWTO(R_386_GOT32, 0, 4, 32, false, 0, complain_overflow_dont,
     41   1.1     skrll 	bfd_elf_generic_reloc, "R_386_GOT32",
     42  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
     43  1.13  christos   HOWTO(R_386_PLT32, 0, 4, 32, true, 0, complain_overflow_dont,
     44   1.1     skrll 	bfd_elf_generic_reloc, "R_386_PLT32",
     45  1.13  christos 	true, 0xffffffff, 0xffffffff, true),
     46  1.13  christos   HOWTO(R_386_COPY, 0, 4, 32, false, 0, complain_overflow_dont,
     47   1.1     skrll 	bfd_elf_generic_reloc, "R_386_COPY",
     48  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
     49  1.13  christos   HOWTO(R_386_GLOB_DAT, 0, 4, 32, false, 0, complain_overflow_dont,
     50   1.1     skrll 	bfd_elf_generic_reloc, "R_386_GLOB_DAT",
     51  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
     52  1.13  christos   HOWTO(R_386_JUMP_SLOT, 0, 4, 32, false, 0, complain_overflow_dont,
     53   1.1     skrll 	bfd_elf_generic_reloc, "R_386_JUMP_SLOT",
     54  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
     55  1.13  christos   HOWTO(R_386_RELATIVE, 0, 4, 32, false, 0, complain_overflow_dont,
     56   1.1     skrll 	bfd_elf_generic_reloc, "R_386_RELATIVE",
     57  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
     58  1.13  christos   HOWTO(R_386_GOTOFF, 0, 4, 32, false, 0, complain_overflow_dont,
     59   1.1     skrll 	bfd_elf_generic_reloc, "R_386_GOTOFF",
     60  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
     61  1.13  christos   HOWTO(R_386_GOTPC, 0, 4, 32, true, 0, complain_overflow_dont,
     62   1.1     skrll 	bfd_elf_generic_reloc, "R_386_GOTPC",
     63  1.13  christos 	true, 0xffffffff, 0xffffffff, true),
     64   1.1     skrll 
     65   1.1     skrll   /* We have a gap in the reloc numbers here.
     66   1.1     skrll      R_386_standard counts the number up to this point, and
     67   1.1     skrll      R_386_ext_offset is the value to subtract from a reloc type of
     68   1.1     skrll      R_386_16 thru R_386_PC8 to form an index into this table.  */
     69   1.1     skrll #define R_386_standard (R_386_GOTPC + 1)
     70   1.1     skrll #define R_386_ext_offset (R_386_TLS_TPOFF - R_386_standard)
     71   1.1     skrll 
     72   1.1     skrll   /* These relocs are a GNU extension.  */
     73  1.13  christos   HOWTO(R_386_TLS_TPOFF, 0, 4, 32, false, 0, complain_overflow_dont,
     74   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_TPOFF",
     75  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
     76  1.13  christos   HOWTO(R_386_TLS_IE, 0, 4, 32, false, 0, complain_overflow_dont,
     77   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_IE",
     78  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
     79  1.13  christos   HOWTO(R_386_TLS_GOTIE, 0, 4, 32, false, 0, complain_overflow_dont,
     80   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_GOTIE",
     81  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
     82  1.13  christos   HOWTO(R_386_TLS_LE, 0, 4, 32, false, 0, complain_overflow_dont,
     83   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_LE",
     84  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
     85  1.13  christos   HOWTO(R_386_TLS_GD, 0, 4, 32, false, 0, complain_overflow_dont,
     86   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_GD",
     87  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
     88  1.13  christos   HOWTO(R_386_TLS_LDM, 0, 4, 32, false, 0, complain_overflow_dont,
     89   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_LDM",
     90  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
     91  1.13  christos   HOWTO(R_386_16, 0, 2, 16, false, 0, complain_overflow_bitfield,
     92   1.1     skrll 	bfd_elf_generic_reloc, "R_386_16",
     93  1.13  christos 	true, 0xffff, 0xffff, false),
     94  1.13  christos   HOWTO(R_386_PC16, 0, 2, 16, true, 0, complain_overflow_bitfield,
     95   1.1     skrll 	bfd_elf_generic_reloc, "R_386_PC16",
     96  1.13  christos 	true, 0xffff, 0xffff, true),
     97  1.13  christos   HOWTO(R_386_8, 0, 1, 8, false, 0, complain_overflow_bitfield,
     98   1.1     skrll 	bfd_elf_generic_reloc, "R_386_8",
     99  1.13  christos 	true, 0xff, 0xff, false),
    100  1.13  christos   HOWTO(R_386_PC8, 0, 1, 8, true, 0, complain_overflow_signed,
    101   1.1     skrll 	bfd_elf_generic_reloc, "R_386_PC8",
    102  1.13  christos 	true, 0xff, 0xff, true),
    103   1.1     skrll 
    104   1.1     skrll #define R_386_ext (R_386_PC8 + 1 - R_386_ext_offset)
    105   1.1     skrll #define R_386_tls_offset (R_386_TLS_LDO_32 - R_386_ext)
    106   1.1     skrll   /* These are common with Solaris TLS implementation.  */
    107  1.13  christos   HOWTO(R_386_TLS_LDO_32, 0, 4, 32, false, 0, complain_overflow_dont,
    108   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_LDO_32",
    109  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
    110  1.13  christos   HOWTO(R_386_TLS_IE_32, 0, 4, 32, false, 0, complain_overflow_dont,
    111   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_IE_32",
    112  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
    113  1.13  christos   HOWTO(R_386_TLS_LE_32, 0, 4, 32, false, 0, complain_overflow_dont,
    114   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_LE_32",
    115  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
    116  1.13  christos   HOWTO(R_386_TLS_DTPMOD32, 0, 4, 32, false, 0, complain_overflow_dont,
    117   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_DTPMOD32",
    118  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
    119  1.13  christos   HOWTO(R_386_TLS_DTPOFF32, 0, 4, 32, false, 0, complain_overflow_dont,
    120   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_DTPOFF32",
    121  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
    122  1.13  christos   HOWTO(R_386_TLS_TPOFF32, 0, 4, 32, false, 0, complain_overflow_dont,
    123   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_TPOFF32",
    124  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
    125  1.13  christos   HOWTO(R_386_SIZE32, 0, 4, 32, false, 0, complain_overflow_dont,
    126   1.6  christos 	bfd_elf_generic_reloc, "R_386_SIZE32",
    127  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
    128  1.13  christos   HOWTO(R_386_TLS_GOTDESC, 0, 4, 32, false, 0, complain_overflow_dont,
    129   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_GOTDESC",
    130  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
    131  1.13  christos   HOWTO(R_386_TLS_DESC_CALL, 0, 0, 0, false, 0, complain_overflow_dont,
    132   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_DESC_CALL",
    133  1.13  christos 	false, 0, 0, false),
    134  1.13  christos   HOWTO(R_386_TLS_DESC, 0, 4, 32, false, 0, complain_overflow_dont,
    135   1.1     skrll 	bfd_elf_generic_reloc, "R_386_TLS_DESC",
    136  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
    137  1.13  christos   HOWTO(R_386_IRELATIVE, 0, 4, 32, false, 0, complain_overflow_dont,
    138   1.4  christos 	bfd_elf_generic_reloc, "R_386_IRELATIVE",
    139  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
    140  1.13  christos   HOWTO(R_386_GOT32X, 0, 4, 32, false, 0, complain_overflow_dont,
    141   1.6  christos 	bfd_elf_generic_reloc, "R_386_GOT32X",
    142  1.13  christos 	true, 0xffffffff, 0xffffffff, false),
    143   1.1     skrll 
    144   1.1     skrll   /* Another gap.  */
    145   1.6  christos #define R_386_ext2 (R_386_GOT32X + 1 - R_386_tls_offset)
    146   1.6  christos #define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_ext2)
    147   1.1     skrll 
    148   1.1     skrll /* GNU extension to record C++ vtable hierarchy.  */
    149   1.1     skrll   HOWTO (R_386_GNU_VTINHERIT,	/* type */
    150   1.1     skrll 	 0,			/* rightshift */
    151  1.13  christos 	 4,			/* size */
    152   1.1     skrll 	 0,			/* bitsize */
    153  1.13  christos 	 false,			/* pc_relative */
    154   1.1     skrll 	 0,			/* bitpos */
    155   1.1     skrll 	 complain_overflow_dont, /* complain_on_overflow */
    156   1.1     skrll 	 NULL,			/* special_function */
    157   1.1     skrll 	 "R_386_GNU_VTINHERIT",	/* name */
    158  1.13  christos 	 false,			/* partial_inplace */
    159   1.1     skrll 	 0,			/* src_mask */
    160   1.1     skrll 	 0,			/* dst_mask */
    161  1.13  christos 	 false),		/* pcrel_offset */
    162   1.1     skrll 
    163   1.1     skrll /* GNU extension to record C++ vtable member usage.  */
    164   1.1     skrll   HOWTO (R_386_GNU_VTENTRY,	/* type */
    165   1.1     skrll 	 0,			/* rightshift */
    166  1.13  christos 	 4,			/* size */
    167   1.1     skrll 	 0,			/* bitsize */
    168  1.13  christos 	 false,			/* pc_relative */
    169   1.1     skrll 	 0,			/* bitpos */
    170   1.1     skrll 	 complain_overflow_dont, /* complain_on_overflow */
    171   1.1     skrll 	 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
    172   1.1     skrll 	 "R_386_GNU_VTENTRY",	/* name */
    173  1.13  christos 	 false,			/* partial_inplace */
    174   1.1     skrll 	 0,			/* src_mask */
    175   1.1     skrll 	 0,			/* dst_mask */
    176  1.13  christos 	 false)			/* pcrel_offset */
    177   1.1     skrll 
    178   1.1     skrll #define R_386_vt (R_386_GNU_VTENTRY + 1 - R_386_vt_offset)
    179   1.1     skrll 
    180   1.1     skrll };
    181   1.1     skrll 
    182   1.1     skrll #ifdef DEBUG_GEN_RELOC
    183   1.1     skrll #define TRACE(str) \
    184   1.1     skrll   fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str)
    185   1.1     skrll #else
    186   1.1     skrll #define TRACE(str)
    187   1.1     skrll #endif
    188   1.1     skrll 
    189   1.1     skrll static reloc_howto_type *
    190  1.11  christos elf_i386_reloc_type_lookup (bfd *abfd,
    191   1.1     skrll 			    bfd_reloc_code_real_type code)
    192   1.1     skrll {
    193   1.1     skrll   switch (code)
    194   1.1     skrll     {
    195   1.1     skrll     case BFD_RELOC_NONE:
    196   1.1     skrll       TRACE ("BFD_RELOC_NONE");
    197   1.1     skrll       return &elf_howto_table[R_386_NONE];
    198   1.1     skrll 
    199   1.1     skrll     case BFD_RELOC_32:
    200   1.1     skrll       TRACE ("BFD_RELOC_32");
    201   1.1     skrll       return &elf_howto_table[R_386_32];
    202   1.1     skrll 
    203   1.1     skrll     case BFD_RELOC_CTOR:
    204   1.1     skrll       TRACE ("BFD_RELOC_CTOR");
    205   1.1     skrll       return &elf_howto_table[R_386_32];
    206   1.1     skrll 
    207   1.1     skrll     case BFD_RELOC_32_PCREL:
    208   1.1     skrll       TRACE ("BFD_RELOC_PC32");
    209   1.1     skrll       return &elf_howto_table[R_386_PC32];
    210   1.1     skrll 
    211   1.1     skrll     case BFD_RELOC_386_GOT32:
    212   1.1     skrll       TRACE ("BFD_RELOC_386_GOT32");
    213   1.1     skrll       return &elf_howto_table[R_386_GOT32];
    214   1.1     skrll 
    215   1.1     skrll     case BFD_RELOC_386_PLT32:
    216   1.1     skrll       TRACE ("BFD_RELOC_386_PLT32");
    217   1.1     skrll       return &elf_howto_table[R_386_PLT32];
    218   1.1     skrll 
    219  1.17  christos     case BFD_RELOC_COPY:
    220  1.17  christos       TRACE ("BFD_RELOC_COPY");
    221   1.1     skrll       return &elf_howto_table[R_386_COPY];
    222   1.1     skrll 
    223  1.17  christos     case BFD_RELOC_GLOB_DAT:
    224  1.17  christos       TRACE ("BFD_RELOC_GLOB_DAT");
    225   1.1     skrll       return &elf_howto_table[R_386_GLOB_DAT];
    226   1.1     skrll 
    227  1.17  christos     case BFD_RELOC_JMP_SLOT:
    228  1.17  christos       TRACE ("BFD_RELOC_JMP_SLOT");
    229   1.1     skrll       return &elf_howto_table[R_386_JUMP_SLOT];
    230   1.1     skrll 
    231  1.17  christos     case BFD_RELOC_RELATIVE:
    232  1.17  christos       TRACE ("BFD_RELOC_RELATIVE");
    233   1.1     skrll       return &elf_howto_table[R_386_RELATIVE];
    234   1.1     skrll 
    235   1.1     skrll     case BFD_RELOC_386_GOTOFF:
    236   1.1     skrll       TRACE ("BFD_RELOC_386_GOTOFF");
    237   1.1     skrll       return &elf_howto_table[R_386_GOTOFF];
    238   1.1     skrll 
    239   1.1     skrll     case BFD_RELOC_386_GOTPC:
    240   1.1     skrll       TRACE ("BFD_RELOC_386_GOTPC");
    241   1.1     skrll       return &elf_howto_table[R_386_GOTPC];
    242   1.1     skrll 
    243   1.1     skrll       /* These relocs are a GNU extension.  */
    244   1.1     skrll     case BFD_RELOC_386_TLS_TPOFF:
    245   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_TPOFF");
    246   1.1     skrll       return &elf_howto_table[R_386_TLS_TPOFF - R_386_ext_offset];
    247   1.1     skrll 
    248   1.1     skrll     case BFD_RELOC_386_TLS_IE:
    249   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_IE");
    250   1.1     skrll       return &elf_howto_table[R_386_TLS_IE - R_386_ext_offset];
    251   1.1     skrll 
    252   1.1     skrll     case BFD_RELOC_386_TLS_GOTIE:
    253   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_GOTIE");
    254   1.1     skrll       return &elf_howto_table[R_386_TLS_GOTIE - R_386_ext_offset];
    255   1.1     skrll 
    256   1.1     skrll     case BFD_RELOC_386_TLS_LE:
    257   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_LE");
    258   1.1     skrll       return &elf_howto_table[R_386_TLS_LE - R_386_ext_offset];
    259   1.1     skrll 
    260   1.1     skrll     case BFD_RELOC_386_TLS_GD:
    261   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_GD");
    262   1.1     skrll       return &elf_howto_table[R_386_TLS_GD - R_386_ext_offset];
    263   1.1     skrll 
    264   1.1     skrll     case BFD_RELOC_386_TLS_LDM:
    265   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_LDM");
    266   1.1     skrll       return &elf_howto_table[R_386_TLS_LDM - R_386_ext_offset];
    267   1.1     skrll 
    268   1.1     skrll     case BFD_RELOC_16:
    269   1.1     skrll       TRACE ("BFD_RELOC_16");
    270   1.1     skrll       return &elf_howto_table[R_386_16 - R_386_ext_offset];
    271   1.1     skrll 
    272   1.1     skrll     case BFD_RELOC_16_PCREL:
    273   1.1     skrll       TRACE ("BFD_RELOC_16_PCREL");
    274   1.1     skrll       return &elf_howto_table[R_386_PC16 - R_386_ext_offset];
    275   1.1     skrll 
    276   1.1     skrll     case BFD_RELOC_8:
    277   1.1     skrll       TRACE ("BFD_RELOC_8");
    278   1.1     skrll       return &elf_howto_table[R_386_8 - R_386_ext_offset];
    279   1.1     skrll 
    280   1.1     skrll     case BFD_RELOC_8_PCREL:
    281   1.1     skrll       TRACE ("BFD_RELOC_8_PCREL");
    282   1.1     skrll       return &elf_howto_table[R_386_PC8 - R_386_ext_offset];
    283   1.1     skrll 
    284   1.1     skrll     /* Common with Sun TLS implementation.  */
    285   1.1     skrll     case BFD_RELOC_386_TLS_LDO_32:
    286   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_LDO_32");
    287   1.1     skrll       return &elf_howto_table[R_386_TLS_LDO_32 - R_386_tls_offset];
    288   1.1     skrll 
    289   1.1     skrll     case BFD_RELOC_386_TLS_IE_32:
    290   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_IE_32");
    291   1.1     skrll       return &elf_howto_table[R_386_TLS_IE_32 - R_386_tls_offset];
    292   1.1     skrll 
    293   1.1     skrll     case BFD_RELOC_386_TLS_LE_32:
    294   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_LE_32");
    295   1.1     skrll       return &elf_howto_table[R_386_TLS_LE_32 - R_386_tls_offset];
    296   1.1     skrll 
    297   1.1     skrll     case BFD_RELOC_386_TLS_DTPMOD32:
    298   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_DTPMOD32");
    299   1.1     skrll       return &elf_howto_table[R_386_TLS_DTPMOD32 - R_386_tls_offset];
    300   1.1     skrll 
    301   1.1     skrll     case BFD_RELOC_386_TLS_DTPOFF32:
    302   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_DTPOFF32");
    303   1.1     skrll       return &elf_howto_table[R_386_TLS_DTPOFF32 - R_386_tls_offset];
    304   1.1     skrll 
    305   1.1     skrll     case BFD_RELOC_386_TLS_TPOFF32:
    306   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_TPOFF32");
    307   1.1     skrll       return &elf_howto_table[R_386_TLS_TPOFF32 - R_386_tls_offset];
    308   1.1     skrll 
    309   1.6  christos     case BFD_RELOC_SIZE32:
    310   1.6  christos       TRACE ("BFD_RELOC_SIZE32");
    311   1.6  christos       return &elf_howto_table[R_386_SIZE32 - R_386_tls_offset];
    312   1.6  christos 
    313   1.1     skrll     case BFD_RELOC_386_TLS_GOTDESC:
    314   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_GOTDESC");
    315   1.1     skrll       return &elf_howto_table[R_386_TLS_GOTDESC - R_386_tls_offset];
    316   1.1     skrll 
    317   1.1     skrll     case BFD_RELOC_386_TLS_DESC_CALL:
    318   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_DESC_CALL");
    319   1.1     skrll       return &elf_howto_table[R_386_TLS_DESC_CALL - R_386_tls_offset];
    320   1.1     skrll 
    321   1.1     skrll     case BFD_RELOC_386_TLS_DESC:
    322   1.1     skrll       TRACE ("BFD_RELOC_386_TLS_DESC");
    323   1.1     skrll       return &elf_howto_table[R_386_TLS_DESC - R_386_tls_offset];
    324   1.1     skrll 
    325  1.17  christos     case BFD_RELOC_IRELATIVE:
    326  1.17  christos       TRACE ("BFD_RELOC_IRELATIVE");
    327   1.5  christos       return &elf_howto_table[R_386_IRELATIVE - R_386_tls_offset];
    328   1.4  christos 
    329   1.6  christos     case BFD_RELOC_386_GOT32X:
    330   1.6  christos       TRACE ("BFD_RELOC_386_GOT32X");
    331   1.6  christos       return &elf_howto_table[R_386_GOT32X - R_386_tls_offset];
    332   1.6  christos 
    333   1.1     skrll     case BFD_RELOC_VTABLE_INHERIT:
    334   1.1     skrll       TRACE ("BFD_RELOC_VTABLE_INHERIT");
    335   1.1     skrll       return &elf_howto_table[R_386_GNU_VTINHERIT - R_386_vt_offset];
    336   1.1     skrll 
    337   1.1     skrll     case BFD_RELOC_VTABLE_ENTRY:
    338   1.1     skrll       TRACE ("BFD_RELOC_VTABLE_ENTRY");
    339   1.1     skrll       return &elf_howto_table[R_386_GNU_VTENTRY - R_386_vt_offset];
    340   1.1     skrll 
    341   1.1     skrll     default:
    342  1.11  christos       TRACE ("Unknown");
    343  1.11  christos       /* xgettext:c-format */
    344  1.11  christos       _bfd_error_handler (_("%pB: unsupported relocation type: %#x"),
    345  1.11  christos 			  abfd, (int) code);
    346  1.11  christos       bfd_set_error (bfd_error_bad_value);
    347  1.11  christos       return NULL;
    348   1.1     skrll     }
    349   1.1     skrll }
    350   1.1     skrll 
    351   1.1     skrll static reloc_howto_type *
    352   1.1     skrll elf_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    353   1.1     skrll 			    const char *r_name)
    354   1.1     skrll {
    355   1.1     skrll   unsigned int i;
    356   1.1     skrll 
    357   1.1     skrll   for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
    358   1.1     skrll     if (elf_howto_table[i].name != NULL
    359   1.1     skrll 	&& strcasecmp (elf_howto_table[i].name, r_name) == 0)
    360   1.1     skrll       return &elf_howto_table[i];
    361   1.1     skrll 
    362   1.1     skrll   return NULL;
    363   1.1     skrll }
    364   1.1     skrll 
    365   1.1     skrll static reloc_howto_type *
    366  1.12  christos elf_i386_rtype_to_howto (unsigned r_type)
    367   1.1     skrll {
    368   1.1     skrll   unsigned int indx;
    369   1.1     skrll 
    370   1.1     skrll   if ((indx = r_type) >= R_386_standard
    371   1.1     skrll       && ((indx = r_type - R_386_ext_offset) - R_386_standard
    372   1.1     skrll 	  >= R_386_ext - R_386_standard)
    373   1.1     skrll       && ((indx = r_type - R_386_tls_offset) - R_386_ext
    374   1.6  christos 	  >= R_386_ext2 - R_386_ext)
    375   1.6  christos       && ((indx = r_type - R_386_vt_offset) - R_386_ext2
    376   1.6  christos 	  >= R_386_vt - R_386_ext2))
    377  1.11  christos       return NULL;
    378   1.6  christos   /* PR 17512: file: 0f67f69d.  */
    379   1.6  christos   if (elf_howto_table [indx].type != r_type)
    380   1.6  christos     return NULL;
    381   1.1     skrll   return &elf_howto_table[indx];
    382   1.1     skrll }
    383   1.1     skrll 
    384  1.13  christos static bool
    385  1.11  christos elf_i386_info_to_howto_rel (bfd *abfd,
    386   1.1     skrll 			    arelent *cache_ptr,
    387   1.1     skrll 			    Elf_Internal_Rela *dst)
    388   1.1     skrll {
    389   1.1     skrll   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
    390  1.11  christos 
    391  1.12  christos   if ((cache_ptr->howto = elf_i386_rtype_to_howto (r_type)) == NULL)
    392  1.11  christos     {
    393  1.11  christos       /* xgettext:c-format */
    394  1.11  christos       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    395  1.11  christos 			  abfd, r_type);
    396  1.11  christos       bfd_set_error (bfd_error_bad_value);
    397  1.13  christos       return false;
    398  1.11  christos     }
    399  1.11  christos 
    400  1.13  christos   return true;
    401   1.1     skrll }
    402   1.1     skrll 
    403   1.1     skrll /* Return whether a symbol name implies a local label.  The UnixWare
    404   1.1     skrll    2.1 cc generates temporary symbols that start with .X, so we
    405   1.1     skrll    recognize them here.  FIXME: do other SVR4 compilers also use .X?.
    406   1.1     skrll    If so, we should move the .X recognition into
    407   1.1     skrll    _bfd_elf_is_local_label_name.  */
    408   1.1     skrll 
    409  1.13  christos static bool
    410   1.1     skrll elf_i386_is_local_label_name (bfd *abfd, const char *name)
    411   1.1     skrll {
    412   1.1     skrll   if (name[0] == '.' && name[1] == 'X')
    413  1.13  christos     return true;
    414   1.1     skrll 
    415   1.1     skrll   return _bfd_elf_is_local_label_name (abfd, name);
    416   1.1     skrll }
    417   1.1     skrll 
    418   1.1     skrll /* Support for core dump NOTE sections.  */
    420  1.13  christos 
    421   1.1     skrll static bool
    422   1.1     skrll elf_i386_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
    423   1.1     skrll {
    424   1.1     skrll   int offset;
    425   1.1     skrll   size_t size;
    426   1.1     skrll 
    427   1.1     skrll   if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0)
    428   1.1     skrll     {
    429   1.1     skrll       int pr_version = bfd_get_32 (abfd, note->descdata);
    430   1.1     skrll 
    431  1.13  christos       if (pr_version != 1)
    432   1.1     skrll 	return false;
    433   1.1     skrll 
    434   1.6  christos       /* pr_cursig */
    435   1.1     skrll       elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 20);
    436   1.1     skrll 
    437   1.6  christos       /* pr_pid */
    438   1.1     skrll       elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
    439   1.1     skrll 
    440   1.1     skrll       /* pr_reg */
    441   1.1     skrll       offset = 28;
    442   1.1     skrll       size = bfd_get_32 (abfd, note->descdata + 8);
    443   1.1     skrll     }
    444   1.1     skrll   else
    445   1.1     skrll     {
    446   1.1     skrll       switch (note->descsz)
    447   1.1     skrll 	{
    448  1.13  christos 	default:
    449   1.1     skrll 	  return false;
    450   1.1     skrll 
    451   1.1     skrll 	case 144:		/* Linux/i386 */
    452   1.6  christos 	  /* pr_cursig */
    453   1.1     skrll 	  elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
    454   1.1     skrll 
    455   1.6  christos 	  /* pr_pid */
    456   1.1     skrll 	  elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
    457   1.1     skrll 
    458   1.1     skrll 	  /* pr_reg */
    459   1.1     skrll 	  offset = 72;
    460   1.1     skrll 	  size = 68;
    461   1.1     skrll 
    462   1.1     skrll 	  break;
    463   1.1     skrll 	}
    464   1.1     skrll     }
    465   1.1     skrll 
    466   1.1     skrll   /* Make a ".reg/999" section.  */
    467   1.1     skrll   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
    468   1.1     skrll 					  size, note->descpos + offset);
    469   1.1     skrll }
    470  1.13  christos 
    471   1.1     skrll static bool
    472   1.1     skrll elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
    473   1.1     skrll {
    474   1.1     skrll   if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0)
    475   1.1     skrll     {
    476   1.1     skrll       int pr_version = bfd_get_32 (abfd, note->descdata);
    477   1.1     skrll 
    478  1.13  christos       if (pr_version != 1)
    479   1.1     skrll 	return false;
    480   1.6  christos 
    481   1.1     skrll       elf_tdata (abfd)->core->program
    482   1.6  christos 	= _bfd_elfcore_strndup (abfd, note->descdata + 8, 17);
    483   1.1     skrll       elf_tdata (abfd)->core->command
    484   1.1     skrll 	= _bfd_elfcore_strndup (abfd, note->descdata + 25, 81);
    485   1.1     skrll     }
    486   1.1     skrll   else
    487   1.1     skrll     {
    488   1.1     skrll       switch (note->descsz)
    489   1.1     skrll 	{
    490  1.13  christos 	default:
    491   1.1     skrll 	  return false;
    492   1.1     skrll 
    493   1.6  christos 	case 124:		/* Linux/i386 elf_prpsinfo.  */
    494   1.4  christos 	  elf_tdata (abfd)->core->pid
    495   1.6  christos 	    = bfd_get_32 (abfd, note->descdata + 12);
    496   1.1     skrll 	  elf_tdata (abfd)->core->program
    497   1.6  christos 	    = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
    498   1.1     skrll 	  elf_tdata (abfd)->core->command
    499   1.1     skrll 	    = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
    500   1.1     skrll 	}
    501   1.1     skrll     }
    502   1.1     skrll 
    503   1.1     skrll   /* Note that for some reason, a spurious space is tacked
    504   1.1     skrll      onto the end of the args in some (at least one anyway)
    505   1.1     skrll      implementations, so strip it off if it exists.  */
    506   1.6  christos   {
    507   1.1     skrll     char *command = elf_tdata (abfd)->core->command;
    508   1.1     skrll     int n = strlen (command);
    509   1.1     skrll 
    510   1.1     skrll     if (0 < n && command[n - 1] == ' ')
    511   1.1     skrll       command[n - 1] = '\0';
    512   1.1     skrll   }
    513  1.13  christos 
    514   1.1     skrll   return true;
    515   1.1     skrll }
    516   1.1     skrll 
    517   1.1     skrll /* Functions for the i386 ELF linker.
    519   1.1     skrll 
    520   1.1     skrll    In order to gain some understanding of code in this file without
    521   1.1     skrll    knowing all the intricate details of the linker, note the
    522   1.1     skrll    following:
    523   1.1     skrll 
    524   1.1     skrll    Functions named elf_i386_* are called by external routines, other
    525  1.13  christos    functions are only called locally.  elf_i386_* functions appear
    526   1.1     skrll    in this file more or less in the order in which they are called
    527   1.1     skrll    from external routines.  eg. elf_i386_scan_relocs is called
    528   1.1     skrll    early in the link process, elf_i386_finish_dynamic_sections is
    529  1.10  christos    one of the last functions.  */
    530  1.14       rin 
    531  1.10  christos /* The size in bytes of an entry in the lazy procedure linkage table.  */
    532   1.1     skrll 
    533   1.1     skrll #define LAZY_PLT_ENTRY_SIZE 16
    534   1.1     skrll 
    535   1.1     skrll /* The name of the dynamic interpreter.  This is put in the .interp
    536   1.3  drochner    section.  */
    537   1.1     skrll 
    538   1.1     skrll #define ELF_DYNAMIC_INTERPRETER "/libexec/ld.elf_so"
    539  1.10  christos 
    540  1.10  christos 
    541   1.1     skrll /* The size in bytes of an entry in the non-lazy procedure linkage
    542  1.10  christos    table.  */
    543   1.1     skrll 
    544  1.10  christos #define NON_LAZY_PLT_ENTRY_SIZE 8
    545  1.10  christos 
    546  1.10  christos /* The first entry in an absolute lazy procedure linkage table looks
    547   1.1     skrll    like this.  See the SVR4 ABI i386 supplement to see how this works.
    548  1.10  christos    Will be padded to LAZY_PLT_ENTRY_SIZE with lazy_plt->plt0_pad_byte.  */
    549   1.1     skrll 
    550   1.1     skrll static const bfd_byte elf_i386_lazy_plt0_entry[12] =
    551   1.1     skrll {
    552   1.1     skrll   0xff, 0x35,	/* pushl contents of address */
    553   1.1     skrll   0, 0, 0, 0,	/* replaced with address of .got + 4.  */
    554   1.1     skrll   0xff, 0x25,	/* jmp indirect */
    555   1.1     skrll   0, 0, 0, 0	/* replaced with address of .got + 8.  */
    556  1.10  christos };
    557  1.10  christos 
    558   1.1     skrll /* Subsequent entries in an absolute lazy procedure linkage table look
    559  1.10  christos    like this.  */
    560   1.1     skrll 
    561   1.1     skrll static const bfd_byte elf_i386_lazy_plt_entry[LAZY_PLT_ENTRY_SIZE] =
    562   1.1     skrll {
    563   1.1     skrll   0xff, 0x25,	/* jmp indirect */
    564   1.1     skrll   0, 0, 0, 0,	/* replaced with address of this symbol in .got.  */
    565   1.1     skrll   0x68,		/* pushl immediate */
    566   1.1     skrll   0, 0, 0, 0,	/* replaced with offset into relocation table.  */
    567   1.1     skrll   0xe9,		/* jmp relative */
    568   1.1     skrll   0, 0, 0, 0	/* replaced with offset to start of .plt.  */
    569  1.10  christos };
    570  1.10  christos 
    571  1.10  christos /* The first entry in a PIC lazy procedure linkage table look like
    572   1.1     skrll    this.  Will be padded to LAZY_PLT_ENTRY_SIZE with
    573  1.10  christos    lazy_plt->plt0_pad_byte.  */
    574   1.1     skrll 
    575   1.1     skrll static const bfd_byte elf_i386_pic_lazy_plt0_entry[12] =
    576   1.1     skrll {
    577   1.1     skrll   0xff, 0xb3, 4, 0, 0, 0,	/* pushl 4(%ebx) */
    578   1.1     skrll   0xff, 0xa3, 8, 0, 0, 0	/* jmp *8(%ebx) */
    579  1.10  christos };
    580  1.10  christos 
    581   1.1     skrll /* Subsequent entries in a PIC lazy procedure linkage table look like
    582  1.10  christos    this.  */
    583   1.1     skrll 
    584   1.1     skrll static const bfd_byte elf_i386_pic_lazy_plt_entry[LAZY_PLT_ENTRY_SIZE] =
    585   1.1     skrll {
    586   1.1     skrll   0xff, 0xa3,	/* jmp *offset(%ebx) */
    587   1.1     skrll   0, 0, 0, 0,	/* replaced with offset of this symbol in .got.  */
    588   1.1     skrll   0x68,		/* pushl immediate */
    589   1.1     skrll   0, 0, 0, 0,	/* replaced with offset into relocation table.  */
    590   1.1     skrll   0xe9,		/* jmp relative */
    591   1.1     skrll   0, 0, 0, 0	/* replaced with offset to start of .plt.  */
    592  1.10  christos };
    593   1.6  christos 
    594  1.10  christos /* Entries in the non-lazy procedure linkage table look like this.  */
    595   1.6  christos 
    596   1.6  christos static const bfd_byte elf_i386_non_lazy_plt_entry[NON_LAZY_PLT_ENTRY_SIZE] =
    597   1.6  christos {
    598   1.6  christos   0xff, 0x25,	/* jmp indirect */
    599   1.6  christos   0, 0, 0, 0,	/* replaced with offset of this symbol in .got.  */
    600   1.6  christos   0x66, 0x90	/* xchg %ax,%ax  */
    601  1.10  christos };
    602  1.10  christos 
    603   1.6  christos /* Entries in the PIC non-lazy procedure linkage table look like
    604  1.10  christos    this.  */
    605   1.6  christos 
    606   1.6  christos static const bfd_byte elf_i386_pic_non_lazy_plt_entry[NON_LAZY_PLT_ENTRY_SIZE] =
    607   1.6  christos {
    608   1.6  christos   0xff, 0xa3,	/* jmp *offset(%ebx)  */
    609   1.6  christos   0, 0, 0, 0,	/* replaced with offset of this symbol in .got.  */
    610   1.6  christos   0x66, 0x90	/* xchg %ax,%ax  */
    611  1.10  christos };
    612  1.10  christos 
    613  1.10  christos /* The first entry in an absolute IBT-enabled lazy procedure linkage
    614  1.10  christos    table looks like this.  */
    615  1.10  christos 
    616  1.10  christos static const bfd_byte elf_i386_lazy_ibt_plt0_entry[LAZY_PLT_ENTRY_SIZE] =
    617  1.10  christos {
    618  1.10  christos   0xff, 0x35, 0, 0, 0, 0,	/* pushl GOT[1]	      */
    619  1.10  christos   0xff, 0x25, 0, 0, 0, 0,	/* jmp *GOT[2]	      */
    620  1.10  christos   0x0f, 0x1f, 0x40, 0x00	/* nopl 0(%rax)	      */
    621  1.10  christos };
    622  1.10  christos 
    623  1.10  christos /* Subsequent entries for an absolute IBT-enabled lazy procedure linkage
    624  1.10  christos    table look like this.  Subsequent entries for a PIC IBT-enabled lazy
    625  1.10  christos    procedure linkage table are the same.  */
    626  1.10  christos 
    627  1.10  christos static const bfd_byte elf_i386_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
    628  1.10  christos {
    629  1.10  christos   0xf3, 0x0f, 0x1e, 0xfb,	/* endbr32		      */
    630  1.10  christos   0x68, 0, 0, 0, 0,		/* pushl immediate	      */
    631  1.10  christos   0xe9, 0, 0, 0, 0,		/* jmp relative		      */
    632  1.10  christos   0x66, 0x90			/* xchg %ax,%ax		      */
    633  1.10  christos };
    634  1.10  christos 
    635  1.10  christos /* The first entry in a PIC IBT-enabled lazy procedure linkage table
    636  1.10  christos    look like.  */
    637  1.10  christos 
    638  1.10  christos static const bfd_byte elf_i386_pic_lazy_ibt_plt0_entry[LAZY_PLT_ENTRY_SIZE] =
    639  1.10  christos {
    640  1.10  christos   0xff, 0xb3, 4, 0, 0, 0,	/* pushl 4(%ebx)      */
    641  1.10  christos   0xff, 0xa3, 8, 0, 0, 0,	/* jmp *8(%ebx)	      */
    642  1.10  christos   0x0f, 0x1f, 0x40, 0x00	/* nopl 0(%rax)	      */
    643  1.10  christos };
    644  1.10  christos 
    645  1.10  christos /* Entries for branches with IBT-enabled in the absolute non-lazey
    646  1.10  christos    procedure linkage table look like this.  They have the same size
    647  1.10  christos    as the lazy PLT entry.  */
    648  1.10  christos 
    649  1.10  christos static const bfd_byte elf_i386_non_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
    650  1.10  christos {
    651  1.10  christos   0xf3, 0x0f, 0x1e, 0xfb,	     /* endbr32		      */
    652  1.10  christos   0xff, 0x25, 0, 0, 0, 0,	     /* jmp *name@GOT	      */
    653  1.10  christos   0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
    654  1.10  christos };
    655  1.10  christos 
    656  1.10  christos /* Entries for branches with IBT-enabled in the PIC non-lazey procedure
    657  1.10  christos    linkage table look like this.  They have the same size as the lazy
    658  1.10  christos    PLT entry.  */
    659  1.10  christos 
    660  1.10  christos static const bfd_byte elf_i386_pic_non_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
    661  1.10  christos {
    662  1.10  christos   0xf3, 0x0f, 0x1e, 0xfb,	     /* endbr32		      */
    663  1.10  christos   0xff, 0xa3, 0, 0, 0, 0,	     /* jmp *name@GOT(%ebx)   */
    664  1.10  christos   0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
    665  1.10  christos };
    666   1.5  christos 
    667  1.10  christos /* .eh_frame covering the lazy .plt section.  */
    668   1.5  christos 
    669   1.5  christos static const bfd_byte elf_i386_eh_frame_lazy_plt[] =
    670   1.5  christos {
    671   1.5  christos   PLT_CIE_LENGTH, 0, 0, 0,	/* CIE length */
    672   1.5  christos   0, 0, 0, 0,			/* CIE ID */
    673   1.5  christos   1,				/* CIE version */
    674   1.5  christos   'z', 'R', 0,			/* Augmentation string */
    675   1.5  christos   1,				/* Code alignment factor */
    676   1.5  christos   0x7c,				/* Data alignment factor */
    677   1.5  christos   8,				/* Return address column */
    678   1.5  christos   1,				/* Augmentation size */
    679   1.5  christos   DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
    680   1.5  christos   DW_CFA_def_cfa, 4, 4,		/* DW_CFA_def_cfa: r4 (esp) ofs 4 */
    681   1.5  christos   DW_CFA_offset + 8, 1,		/* DW_CFA_offset: r8 (eip) at cfa-4 */
    682   1.5  christos   DW_CFA_nop, DW_CFA_nop,
    683   1.5  christos 
    684   1.5  christos   PLT_FDE_LENGTH, 0, 0, 0,	/* FDE length */
    685   1.5  christos   PLT_CIE_LENGTH + 8, 0, 0, 0,	/* CIE pointer */
    686   1.5  christos   0, 0, 0, 0,			/* R_386_PC32 .plt goes here */
    687   1.5  christos   0, 0, 0, 0,			/* .plt size goes here */
    688   1.5  christos   0,				/* Augmentation size */
    689   1.5  christos   DW_CFA_def_cfa_offset, 8,	/* DW_CFA_def_cfa_offset: 8 */
    690   1.5  christos   DW_CFA_advance_loc + 6,	/* DW_CFA_advance_loc: 6 to __PLT__+6 */
    691   1.5  christos   DW_CFA_def_cfa_offset, 12,	/* DW_CFA_def_cfa_offset: 12 */
    692   1.5  christos   DW_CFA_advance_loc + 10,	/* DW_CFA_advance_loc: 10 to __PLT__+16 */
    693   1.5  christos   DW_CFA_def_cfa_expression,	/* DW_CFA_def_cfa_expression */
    694   1.5  christos   11,				/* Block length */
    695   1.5  christos   DW_OP_breg4, 4,		/* DW_OP_breg4 (esp): 4 */
    696   1.5  christos   DW_OP_breg8, 0,		/* DW_OP_breg8 (eip): 0 */
    697   1.5  christos   DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge,
    698   1.5  christos   DW_OP_lit2, DW_OP_shl, DW_OP_plus,
    699   1.5  christos   DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
    700  1.10  christos };
    701  1.10  christos 
    702  1.10  christos /* .eh_frame covering the lazy .plt section with IBT-enabled.  */
    703   1.5  christos 
    704  1.10  christos static const bfd_byte elf_i386_eh_frame_lazy_ibt_plt[] =
    705  1.10  christos {
    706  1.10  christos   PLT_CIE_LENGTH, 0, 0, 0,	/* CIE length */
    707  1.10  christos   0, 0, 0, 0,			/* CIE ID */
    708  1.10  christos   1,				/* CIE version */
    709  1.10  christos   'z', 'R', 0,			/* Augmentation string */
    710  1.10  christos   1,				/* Code alignment factor */
    711  1.10  christos   0x7c,				/* Data alignment factor */
    712  1.10  christos   8,				/* Return address column */
    713  1.10  christos   1,				/* Augmentation size */
    714  1.10  christos   DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
    715  1.10  christos   DW_CFA_def_cfa, 4, 4,		/* DW_CFA_def_cfa: r4 (esp) ofs 4 */
    716   1.5  christos   DW_CFA_offset + 8, 1,		/* DW_CFA_offset: r8 (eip) at cfa-4 */
    717  1.10  christos   DW_CFA_nop, DW_CFA_nop,
    718  1.10  christos 
    719  1.10  christos   PLT_FDE_LENGTH, 0, 0, 0,	/* FDE length */
    720  1.10  christos   PLT_CIE_LENGTH + 8, 0, 0, 0,	/* CIE pointer */
    721  1.10  christos   0, 0, 0, 0,			/* R_386_PC32 .plt goes here */
    722  1.10  christos   0, 0, 0, 0,			/* .plt size goes here */
    723  1.10  christos   0,				/* Augmentation size */
    724  1.10  christos   DW_CFA_def_cfa_offset, 8,	/* DW_CFA_def_cfa_offset: 8 */
    725  1.10  christos   DW_CFA_advance_loc + 6,	/* DW_CFA_advance_loc: 6 to __PLT__+6 */
    726  1.10  christos   DW_CFA_def_cfa_offset, 12,	/* DW_CFA_def_cfa_offset: 12 */
    727  1.10  christos   DW_CFA_advance_loc + 10,	/* DW_CFA_advance_loc: 10 to __PLT__+16 */
    728  1.10  christos   DW_CFA_def_cfa_expression,	/* DW_CFA_def_cfa_expression */
    729  1.10  christos   11,				/* Block length */
    730  1.10  christos   DW_OP_breg4, 4,		/* DW_OP_breg4 (esp): 4 */
    731  1.10  christos   DW_OP_breg8, 0,		/* DW_OP_breg8 (eip): 0 */
    732  1.10  christos   DW_OP_lit15, DW_OP_and, DW_OP_lit9, DW_OP_ge,
    733  1.10  christos   DW_OP_lit2, DW_OP_shl, DW_OP_plus,
    734   1.5  christos   DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
    735  1.10  christos };
    736   1.5  christos 
    737  1.10  christos /* .eh_frame covering the non-lazy .plt section.  */
    738  1.10  christos 
    739  1.10  christos static const bfd_byte elf_i386_eh_frame_non_lazy_plt[] =
    740  1.10  christos {
    741  1.10  christos #define PLT_GOT_FDE_LENGTH		16
    742  1.10  christos   PLT_CIE_LENGTH, 0, 0, 0,	/* CIE length */
    743  1.10  christos   0, 0, 0, 0,			/* CIE ID */
    744  1.10  christos   1,				/* CIE version */
    745  1.10  christos   'z', 'R', 0,			/* Augmentation string */
    746  1.10  christos   1,				/* Code alignment factor */
    747  1.10  christos   0x7c,				/* Data alignment factor */
    748  1.10  christos   8,				/* Return address column */
    749  1.10  christos   1,				/* Augmentation size */
    750  1.10  christos   DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
    751  1.10  christos   DW_CFA_def_cfa, 4, 4,		/* DW_CFA_def_cfa: r4 (esp) ofs 4 */
    752   1.5  christos   DW_CFA_offset + 8, 1,		/* DW_CFA_offset: r8 (eip) at cfa-4 */
    753  1.10  christos   DW_CFA_nop, DW_CFA_nop,
    754  1.10  christos 
    755  1.10  christos   PLT_GOT_FDE_LENGTH, 0, 0, 0,	/* FDE length */
    756  1.10  christos   PLT_CIE_LENGTH + 8, 0, 0, 0,	/* CIE pointer */
    757  1.10  christos   0, 0, 0, 0,			/* the start of non-lazy .plt goes here */
    758  1.10  christos   0, 0, 0, 0,			/* non-lazy .plt size goes here */
    759  1.10  christos   0,				/* Augmentation size */
    760   1.5  christos   DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
    761  1.10  christos };
    762  1.10  christos 
    763  1.10  christos /* These are the standard parameters.  */
    764  1.10  christos static const struct elf_x86_lazy_plt_layout elf_i386_lazy_plt =
    765  1.10  christos   {
    766  1.10  christos     elf_i386_lazy_plt0_entry,		/* plt0_entry */
    767  1.10  christos     sizeof (elf_i386_lazy_plt0_entry),	/* plt0_entry_size */
    768  1.11  christos     elf_i386_lazy_plt_entry,		/* plt_entry */
    769  1.11  christos     LAZY_PLT_ENTRY_SIZE,		/* plt_entry_size */
    770  1.11  christos     NULL,				/* plt_tlsdesc_entry */
    771  1.11  christos     0,					/* plt_tlsdesc_entry_size*/
    772  1.11  christos     0,					/* plt_tlsdesc_got1_offset */
    773  1.11  christos     0,					/* plt_tlsdesc_got2_offset */
    774  1.10  christos     0,					/* plt_tlsdesc_got1_insn_end */
    775  1.10  christos     0,					/* plt_tlsdesc_got2_insn_end */
    776  1.10  christos     2,					/* plt0_got1_offset */
    777  1.10  christos     8,					/* plt0_got2_offset */
    778  1.10  christos     0,					/* plt0_got2_insn_end */
    779  1.10  christos     2,					/* plt_got_offset */
    780  1.10  christos     7,					/* plt_reloc_offset */
    781  1.10  christos     12,					/* plt_plt_offset */
    782  1.10  christos     0,					/* plt_got_insn_size */
    783  1.10  christos     0,					/* plt_plt_insn_end */
    784  1.10  christos     6,					/* plt_lazy_offset */
    785  1.10  christos     elf_i386_pic_lazy_plt0_entry,	/* pic_plt0_entry */
    786  1.10  christos     elf_i386_pic_lazy_plt_entry,	/* pic_plt_entry */
    787  1.10  christos     elf_i386_eh_frame_lazy_plt,		/* eh_frame_plt */
    788   1.5  christos     sizeof (elf_i386_eh_frame_lazy_plt) /* eh_frame_plt_size */
    789  1.10  christos   };
    790  1.10  christos 
    791  1.10  christos static const struct elf_x86_non_lazy_plt_layout elf_i386_non_lazy_plt =
    792  1.10  christos   {
    793  1.10  christos     elf_i386_non_lazy_plt_entry,	/* plt_entry */
    794  1.10  christos     elf_i386_pic_non_lazy_plt_entry,	/* pic_plt_entry */
    795  1.10  christos     NON_LAZY_PLT_ENTRY_SIZE,		/* plt_entry_size */
    796  1.10  christos     2,					/* plt_got_offset */
    797  1.10  christos     0,					/* plt_got_insn_size */
    798  1.10  christos     elf_i386_eh_frame_non_lazy_plt,	/* eh_frame_plt */
    799   1.5  christos     sizeof (elf_i386_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
    800  1.10  christos   };
    801  1.10  christos 
    802  1.10  christos static const struct elf_x86_lazy_plt_layout elf_i386_lazy_ibt_plt =
    803  1.10  christos   {
    804  1.10  christos     elf_i386_lazy_ibt_plt0_entry,	/* plt0_entry */
    805  1.10  christos     sizeof (elf_i386_lazy_ibt_plt0_entry), /* plt0_entry_size */
    806  1.11  christos     elf_i386_lazy_ibt_plt_entry,	/* plt_entry */
    807  1.11  christos     LAZY_PLT_ENTRY_SIZE,		/* plt_entry_size */
    808  1.11  christos     NULL,				/* plt_tlsdesc_entry */
    809  1.11  christos     0,					/* plt_tlsdesc_entry_size*/
    810  1.11  christos     0,					/* plt_tlsdesc_got1_offset */
    811  1.11  christos     0,					/* plt_tlsdesc_got2_offset */
    812  1.10  christos     0,					/* plt_tlsdesc_got1_insn_end */
    813  1.10  christos     0,					/* plt_tlsdesc_got2_insn_end */
    814  1.10  christos     2,					/* plt0_got1_offset */
    815  1.10  christos     8,					/* plt0_got2_offset */
    816  1.10  christos     0,					/* plt0_got2_insn_end */
    817  1.10  christos     4+2,				/* plt_got_offset */
    818  1.10  christos     4+1,				/* plt_reloc_offset */
    819  1.10  christos     4+6,				/* plt_plt_offset */
    820  1.10  christos     0,					/* plt_got_insn_size */
    821  1.10  christos     0,					/* plt_plt_insn_end */
    822  1.10  christos     0,					/* plt_lazy_offset */
    823  1.10  christos     elf_i386_pic_lazy_ibt_plt0_entry,	/* pic_plt0_entry */
    824  1.10  christos     elf_i386_lazy_ibt_plt_entry,	/* pic_plt_entry */
    825  1.10  christos     elf_i386_eh_frame_lazy_ibt_plt,	/* eh_frame_plt */
    826   1.5  christos     sizeof (elf_i386_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */
    827  1.10  christos   };
    828   1.5  christos 
    829  1.10  christos static const struct elf_x86_non_lazy_plt_layout elf_i386_non_lazy_ibt_plt =
    830  1.10  christos   {
    831  1.10  christos     elf_i386_non_lazy_ibt_plt_entry,	/* plt_entry */
    832  1.10  christos     elf_i386_pic_non_lazy_ibt_plt_entry,/* pic_plt_entry */
    833  1.10  christos     LAZY_PLT_ENTRY_SIZE,		/* plt_entry_size */
    834  1.10  christos     4+2,				/* plt_got_offset */
    835  1.10  christos     0,					/* plt_got_insn_size */
    836   1.5  christos     elf_i386_eh_frame_non_lazy_plt,	/* eh_frame_plt */
    837   1.5  christos     sizeof (elf_i386_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
    838   1.5  christos   };
    839   1.1     skrll 
    840   1.1     skrll 
    842   1.1     skrll /* On VxWorks, the .rel.plt.unloaded section has absolute relocations
    843   1.1     skrll    for the PLTResolve stub and then for each PLT entry.  */
    844   1.1     skrll #define PLTRESOLVE_RELOCS_SHLIB 0
    845   1.1     skrll #define PLTRESOLVE_RELOCS 2
    846   1.1     skrll #define PLT_NON_JUMP_SLOT_RELOCS 2
    847   1.1     skrll 
    848  1.16  christos /* Return TRUE if the TLS access code sequence support transition
    849   1.9  christos    from R_TYPE.  */
    850   1.1     skrll 
    851   1.1     skrll static enum elf_x86_tls_error_type
    852   1.1     skrll elf_i386_check_tls_transition (asection *sec,
    853   1.1     skrll 			       bfd_byte *contents,
    854   1.1     skrll 			       Elf_Internal_Shdr *symtab_hdr,
    855   1.1     skrll 			       struct elf_link_hash_entry **sym_hashes,
    856   1.1     skrll 			       unsigned int r_type,
    857   1.9  christos 			       const Elf_Internal_Rela *rel,
    858   1.1     skrll 			       const Elf_Internal_Rela *relend)
    859   1.1     skrll {
    860   1.1     skrll   unsigned int val, type, reg;
    861   1.9  christos   unsigned long r_symndx;
    862  1.13  christos   struct elf_link_hash_entry *h;
    863   1.1     skrll   bfd_vma offset;
    864   1.1     skrll   bfd_byte *call;
    865   1.1     skrll   bool indirect_call;
    866   1.1     skrll 
    867   1.1     skrll   offset = rel->r_offset;
    868   1.1     skrll   switch (r_type)
    869   1.1     skrll     {
    870  1.16  christos     case R_386_TLS_GD:
    871   1.1     skrll     case R_386_TLS_LDM:
    872  1.13  christos       if (offset < 2 || (rel + 1) >= relend)
    873   1.9  christos 	return elf_x86_tls_error_yes;
    874   1.9  christos 
    875   1.9  christos       indirect_call = false;
    876   1.1     skrll       call = contents + offset + 4;
    877   1.1     skrll       val = *(call - 5);
    878   1.4  christos       type = *(call - 6);
    879   1.9  christos       if (r_type == R_386_TLS_GD)
    880   1.9  christos 	{
    881   1.9  christos 	  /* Check transition from GD access model.  Only
    882   1.9  christos 		leal foo@tlsgd(,%ebx,1), %eax
    883   1.9  christos 		call ___tls_get_addr@PLT
    884   1.9  christos 	     or
    885   1.9  christos 		leal foo@tlsgd(%ebx) %eax
    886   1.9  christos 		call ___tls_get_addr@PLT
    887   1.9  christos 		nop
    888   1.9  christos 	     or
    889   1.9  christos 		leal foo@tlsgd(%reg), %eax
    890   1.1     skrll 		call *___tls_get_addr@GOT(%reg)
    891   1.9  christos 		which may be converted to
    892   1.9  christos 		addr32 call ___tls_get_addr
    893  1.16  christos 	     can transit to different access model.  */
    894   1.1     skrll 	  if ((offset + 10) > sec->size
    895   1.1     skrll 	      || (type != 0x8d && type != 0x04))
    896   1.1     skrll 	    return elf_x86_tls_error_yes;
    897   1.9  christos 
    898   1.9  christos 	  if (type == 0x04)
    899   1.1     skrll 	    {
    900  1.16  christos 	      /* leal foo@tlsgd(,%ebx,1), %eax
    901   1.1     skrll 		 call ___tls_get_addr@PLT  */
    902   1.9  christos 	      if (offset < 3)
    903   1.9  christos 		return elf_x86_tls_error_yes;
    904   1.9  christos 
    905  1.16  christos 	      if (*(call - 7) != 0x8d
    906   1.1     skrll 		  || val != 0x1d
    907   1.1     skrll 		  || call[0] != 0xe8)
    908   1.1     skrll 		return elf_x86_tls_error_yes;
    909   1.9  christos 	    }
    910   1.9  christos 	  else
    911   1.9  christos 	    {
    912   1.9  christos 	      /* This must be
    913   1.9  christos 			leal foo@tlsgd(%ebx), %eax
    914   1.9  christos 			call ___tls_get_addr@PLT
    915   1.9  christos 			nop
    916   1.9  christos 		 or
    917   1.9  christos 			leal foo@tlsgd(%reg), %eax
    918   1.9  christos 			call *___tls_get_addr@GOT(%reg)
    919   1.9  christos 			which may be converted to
    920   1.9  christos 			addr32 call ___tls_get_addr
    921   1.9  christos 
    922   1.9  christos 		 %eax can't be used as the GOT base register since it
    923  1.16  christos 		 is used to pass parameter to ___tls_get_addr.  */
    924   1.1     skrll 	      reg = val & 7;
    925   1.9  christos 	      if ((val & 0xf8) != 0x80 || reg == 4 || reg == 0)
    926   1.9  christos 		return elf_x86_tls_error_yes;
    927   1.9  christos 
    928   1.9  christos 	      indirect_call = call[0] == 0xff;
    929   1.9  christos 	      if (!(reg == 3 && call[0] == 0xe8 && call[5] == 0x90)
    930   1.9  christos 		  && !(call[0] == 0x67 && call[1] == 0xe8)
    931  1.16  christos 		  && !(indirect_call
    932   1.1     skrll 		       && (call[1] & 0xf8) == 0x90
    933   1.1     skrll 		       && (call[1] & 0x7) == reg))
    934   1.1     skrll 		return elf_x86_tls_error_yes;
    935   1.1     skrll 	    }
    936   1.1     skrll 	}
    937   1.9  christos       else
    938   1.9  christos 	{
    939   1.9  christos 	  /* Check transition from LD access model.  Only
    940   1.9  christos 		leal foo@tlsldm(%ebx), %eax
    941   1.9  christos 		call ___tls_get_addr@PLT
    942   1.9  christos 	     or
    943   1.9  christos 		leal foo@tlsldm(%reg), %eax
    944   1.1     skrll 		call *___tls_get_addr@GOT(%reg)
    945   1.1     skrll 		which may be converted to
    946  1.16  christos 		addr32 call ___tls_get_addr
    947   1.1     skrll 	     can transit to different access model.  */
    948   1.9  christos 	  if (type != 0x8d || (offset + 9) > sec->size)
    949   1.9  christos 	    return elf_x86_tls_error_yes;
    950   1.9  christos 
    951   1.9  christos 	  /* %eax can't be used as the GOT base register since it is
    952  1.16  christos 	     used to pass parameter to ___tls_get_addr.  */
    953   1.9  christos 	  reg = val & 7;
    954   1.9  christos 	  if ((val & 0xf8) != 0x80 || reg == 4 || reg == 0)
    955   1.9  christos 	    return elf_x86_tls_error_yes;
    956   1.9  christos 
    957   1.9  christos 	  indirect_call = call[0] == 0xff;
    958   1.9  christos 	  if (!(reg == 3 && call[0] == 0xe8)
    959   1.9  christos 	      && !(call[0] == 0x67 && call[1] == 0xe8)
    960  1.16  christos 	      && !(indirect_call
    961   1.1     skrll 		   && (call[1] & 0xf8) == 0x90
    962   1.1     skrll 		   && (call[1] & 0x7) == reg))
    963   1.1     skrll 	    return elf_x86_tls_error_yes;
    964   1.1     skrll 	}
    965  1.16  christos 
    966   1.1     skrll       r_symndx = ELF32_R_SYM (rel[1].r_info);
    967   1.1     skrll       if (r_symndx < symtab_hdr->sh_info)
    968  1.10  christos 	return elf_x86_tls_error_yes;
    969  1.10  christos 
    970  1.16  christos       h = sym_hashes[r_symndx - symtab_hdr->sh_info];
    971   1.9  christos       if (h == NULL
    972  1.16  christos 	  || !((struct elf_x86_link_hash_entry *) h)->tls_get_addr)
    973  1.16  christos 	return elf_x86_tls_error_yes;
    974  1.16  christos       else if (indirect_call)
    975  1.16  christos 	return ((ELF32_R_TYPE (rel[1].r_info) == R_386_GOT32X
    976   1.9  christos 		 || ELF32_R_TYPE (rel[1].r_info) == R_386_GOT32)
    977  1.16  christos 		? elf_x86_tls_error_none
    978  1.16  christos 		: elf_x86_tls_error_yes);
    979  1.16  christos       else
    980  1.16  christos 	return ((ELF32_R_TYPE (rel[1].r_info) == R_386_PC32
    981   1.1     skrll 		|| ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32)
    982   1.1     skrll 		? elf_x86_tls_error_none
    983   1.1     skrll 		: elf_x86_tls_error_yes);
    984  1.16  christos 
    985  1.16  christos     case R_386_TLS_IE:
    986  1.16  christos       /* Check transition from IE access model:
    987   1.1     skrll 		movl foo@indntpoff, %eax
    988   1.1     skrll 		movl foo@indntpoff, %reg
    989   1.1     skrll 		addl foo@indntpoff, %reg
    990  1.16  christos        */
    991   1.1     skrll 
    992  1.16  christos       if (offset < 1 || (offset + 4) > sec->size)
    993   1.1     skrll 	return elf_x86_tls_error_yes;
    994   1.1     skrll 
    995  1.16  christos       /* Check "movl foo@indntpoff, %eax" first.  */
    996   1.1     skrll       val = bfd_get_8 (abfd, contents + offset - 1);
    997   1.1     skrll       if (val == 0xa1)
    998  1.16  christos 	return elf_x86_tls_error_none;
    999   1.1     skrll 
   1000  1.16  christos       if (offset < 2)
   1001   1.1     skrll 	return elf_x86_tls_error_yes;
   1002  1.16  christos 
   1003  1.16  christos       /* Check movl|addl foo@indntpoff, %reg.   */
   1004  1.16  christos       type = bfd_get_8 (abfd, contents + offset - 2);
   1005  1.16  christos       if (type != 0x8b && type != 0x03)
   1006  1.16  christos 	return elf_x86_tls_error_add_mov;
   1007   1.1     skrll       return ((val & 0xc7) == 0x05
   1008   1.1     skrll 	      ? elf_x86_tls_error_none
   1009   1.1     skrll 	      : elf_x86_tls_error_yes);
   1010   1.1     skrll 
   1011   1.1     skrll     case R_386_TLS_GOTIE:
   1012   1.1     skrll     case R_386_TLS_IE_32:
   1013   1.1     skrll       /* Check transition from {IE_32,GOTIE} access model:
   1014   1.1     skrll 		subl foo@{tpoff,gontoff}(%reg1), %reg2
   1015   1.1     skrll 		movl foo@{tpoff,gontoff}(%reg1), %reg2
   1016   1.1     skrll 		addl foo@{tpoff,gontoff}(%reg1), %reg2
   1017  1.16  christos        */
   1018   1.1     skrll 
   1019   1.1     skrll       if (offset < 2 || (offset + 4) > sec->size)
   1020   1.1     skrll 	return elf_x86_tls_error_yes;
   1021  1.16  christos 
   1022   1.1     skrll       val = bfd_get_8 (abfd, contents + offset - 1);
   1023   1.1     skrll       if ((val & 0xc0) != 0x80 || (val & 7) == 4)
   1024  1.16  christos 	return elf_x86_tls_error_yes;
   1025  1.16  christos 
   1026  1.16  christos       type = bfd_get_8 (abfd, contents + offset - 2);
   1027   1.1     skrll       return (type == 0x8b || type == 0x2b || type == 0x03
   1028   1.1     skrll 	      ? elf_x86_tls_error_none
   1029   1.1     skrll 	      : elf_x86_tls_error_add_sub_mov);
   1030   1.1     skrll 
   1031   1.1     skrll     case R_386_TLS_GOTDESC:
   1032   1.1     skrll       /* Check transition from GDesc access model:
   1033   1.1     skrll 		leal x@tlsdesc(%ebx), %eax
   1034   1.1     skrll 
   1035   1.1     skrll 	 Make sure it's a leal adding ebx to a 32-bit offset
   1036   1.1     skrll 	 into any register, although it's probably almost always
   1037  1.16  christos 	 going to be eax.  */
   1038   1.1     skrll 
   1039   1.1     skrll       if (offset < 2 || (offset + 4) > sec->size)
   1040  1.16  christos 	return elf_x86_tls_error_yes;
   1041   1.1     skrll 
   1042   1.1     skrll       if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d)
   1043  1.16  christos 	return elf_x86_tls_error_lea;
   1044  1.16  christos 
   1045  1.16  christos       val = bfd_get_8 (abfd, contents + offset - 1);
   1046   1.1     skrll       return ((val & 0xc7) == 0x83
   1047   1.1     skrll 	      ? elf_x86_tls_error_none
   1048  1.16  christos 	      : elf_x86_tls_error_yes);
   1049  1.16  christos 
   1050   1.1     skrll     case R_386_TLS_DESC_CALL:
   1051   1.1     skrll       /* It has been checked in elf_i386_tls_transition.  */
   1052   1.1     skrll       return elf_x86_tls_error_none;
   1053   1.1     skrll 
   1054   1.1     skrll     default:
   1055   1.1     skrll       abort ();
   1056   1.1     skrll     }
   1057   1.1     skrll }
   1058   1.1     skrll 
   1059  1.13  christos /* Return TRUE if the TLS access transition is OK or no transition
   1060   1.1     skrll    will be performed.  Update R_TYPE if there is a transition.  */
   1061   1.1     skrll 
   1062   1.1     skrll static bool
   1063   1.1     skrll elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd,
   1064   1.1     skrll 			 asection *sec, bfd_byte *contents,
   1065   1.1     skrll 			 Elf_Internal_Shdr *symtab_hdr,
   1066   1.1     skrll 			 struct elf_link_hash_entry **sym_hashes,
   1067   1.4  christos 			 unsigned int *r_type, int tls_type,
   1068  1.16  christos 			 const Elf_Internal_Rela *rel,
   1069  1.13  christos 			 const Elf_Internal_Rela *relend,
   1070   1.1     skrll 			 struct elf_link_hash_entry *h,
   1071   1.1     skrll 			 Elf_Internal_Sym *sym,
   1072   1.1     skrll 			 bool from_relocate_section)
   1073  1.13  christos {
   1074  1.15  christos   unsigned int from_type = *r_type;
   1075  1.16  christos   unsigned int to_type = from_type;
   1076  1.16  christos   bool check = true;
   1077   1.1     skrll   unsigned int to_le_type, to_ie_type;
   1078   1.4  christos   bfd_vma offset;
   1079   1.4  christos   bfd_byte *call;
   1080   1.4  christos 
   1081   1.4  christos   /* Skip TLS transition for functions.  */
   1082  1.13  christos   if (h != NULL
   1083   1.4  christos       && (h->type == STT_FUNC
   1084  1.15  christos 	  || h->type == STT_GNU_IFUNC))
   1085  1.15  christos     return true;
   1086  1.15  christos 
   1087  1.15  christos   if (get_elf_backend_data (abfd)->target_os == is_solaris)
   1088  1.15  christos     {
   1089  1.15  christos       /* NB: Solaris only supports R_386_TLS_LE and R_386_TLS_IE.  */
   1090  1.15  christos       to_le_type = R_386_TLS_LE;
   1091  1.15  christos       to_ie_type = R_386_TLS_IE;
   1092  1.15  christos     }
   1093  1.15  christos   else
   1094  1.15  christos     {
   1095  1.15  christos       to_le_type = R_386_TLS_LE_32;
   1096   1.1     skrll       to_ie_type = R_386_TLS_IE_32;
   1097   1.1     skrll     }
   1098  1.16  christos 
   1099  1.16  christos   switch (from_type)
   1100  1.16  christos     {
   1101  1.16  christos     case R_386_TLS_DESC_CALL:
   1102  1.16  christos       /* Check valid GDesc call:
   1103  1.16  christos 		call *x@tlscall(%eax)
   1104  1.16  christos        */
   1105  1.16  christos       offset = rel->r_offset;
   1106  1.16  christos       call = NULL;
   1107  1.16  christos       if (offset + 2 <= sec->size)
   1108  1.16  christos 	{
   1109  1.16  christos 	  /* Make sure that it's a call *x@tlscall(%eax).  */
   1110  1.16  christos 	  call = contents + offset;
   1111  1.16  christos 	  if (call[0] != 0xff || call[1] != 0x10)
   1112  1.16  christos 	    call = NULL;
   1113  1.16  christos 	}
   1114  1.16  christos 
   1115  1.16  christos       if (call == NULL)
   1116  1.16  christos 	{
   1117  1.16  christos 	  _bfd_x86_elf_link_report_tls_transition_error
   1118  1.16  christos 	    (info, abfd, sec, symtab_hdr, h, sym, rel,
   1119  1.16  christos 	     "R_386_TLS_DESC_CALL", NULL,
   1120  1.16  christos 	     elf_x86_tls_error_indirect_call);
   1121  1.16  christos 
   1122  1.16  christos 	  return false;
   1123  1.16  christos 	}
   1124   1.1     skrll 
   1125   1.1     skrll       /* Fall through.  */
   1126   1.1     skrll 
   1127   1.1     skrll     case R_386_TLS_GD:
   1128   1.1     skrll     case R_386_TLS_GOTDESC:
   1129   1.6  christos     case R_386_TLS_IE_32:
   1130   1.1     skrll     case R_386_TLS_IE:
   1131   1.1     skrll     case R_386_TLS_GOTIE:
   1132  1.15  christos       if (bfd_link_executable (info))
   1133   1.1     skrll 	{
   1134   1.1     skrll 	  if (h == NULL)
   1135  1.15  christos 	    to_type = to_le_type;
   1136   1.1     skrll 	  else if (from_type != R_386_TLS_IE
   1137   1.1     skrll 		   && from_type != R_386_TLS_GOTIE)
   1138   1.9  christos 	    to_type = to_ie_type;
   1139   1.9  christos 	}
   1140   1.9  christos 
   1141   1.1     skrll       /* When we are called from elf_i386_relocate_section, there may
   1142   1.1     skrll 	 be additional transitions based on TLS_TYPE.  */
   1143   1.1     skrll       if (from_relocate_section)
   1144  1.10  christos 	{
   1145  1.15  christos 	  unsigned int new_to_type = to_type;
   1146   1.1     skrll 
   1147   1.1     skrll 	  if (TLS_TRANSITION_IE_TO_LE_P (info, h, tls_type))
   1148   1.1     skrll 	    new_to_type = to_le_type;
   1149   1.1     skrll 
   1150   1.1     skrll 	  if (to_type == R_386_TLS_GD
   1151   1.1     skrll 	      || to_type == R_386_TLS_GOTDESC
   1152   1.1     skrll 	      || to_type == R_386_TLS_DESC_CALL)
   1153   1.1     skrll 	    {
   1154  1.15  christos 	      if (tls_type == GOT_TLS_IE_POS)
   1155   1.1     skrll 		new_to_type = R_386_TLS_GOTIE;
   1156   1.1     skrll 	      else if (tls_type & GOT_TLS_IE)
   1157   1.1     skrll 		new_to_type = to_ie_type;
   1158  1.13  christos 	    }
   1159   1.1     skrll 
   1160   1.1     skrll 	  /* We checked the transition before when we were called from
   1161   1.1     skrll 	     elf_i386_scan_relocs.  We only want to check the new
   1162   1.1     skrll 	     transition which hasn't been checked before.  */
   1163   1.1     skrll 	  check = new_to_type != to_type && from_type == to_type;
   1164   1.1     skrll 	  to_type = new_to_type;
   1165   1.1     skrll 	}
   1166   1.1     skrll 
   1167   1.6  christos       break;
   1168  1.15  christos 
   1169   1.1     skrll     case R_386_TLS_LDM:
   1170   1.1     skrll       if (bfd_link_executable (info))
   1171   1.1     skrll 	to_type = to_le_type;
   1172  1.13  christos       break;
   1173   1.1     skrll 
   1174   1.1     skrll     default:
   1175  1.17  christos       return true;
   1176  1.17  christos     }
   1177  1.17  christos 
   1178  1.17  christos   if ((elf_section_type (sec) != SHT_PROGBITS
   1179  1.17  christos        || (sec->flags & SEC_CODE) == 0))
   1180  1.17  christos     {
   1181  1.17  christos       reloc_howto_type *howto = elf_i386_rtype_to_howto (from_type);
   1182  1.17  christos       _bfd_x86_elf_link_report_tls_invalid_section_error
   1183  1.17  christos 	(abfd, sec, symtab_hdr, h, sym, howto);
   1184   1.1     skrll       return false;
   1185   1.1     skrll     }
   1186  1.13  christos 
   1187   1.1     skrll   /* Return TRUE if there is no transition.  */
   1188   1.1     skrll   if (from_type == to_type)
   1189  1.16  christos     return true;
   1190   1.1     skrll 
   1191  1.16  christos   /* Check if the transition can be performed.  */
   1192  1.16  christos   enum elf_x86_tls_error_type tls_error;
   1193  1.16  christos   if (check
   1194  1.16  christos       && ((tls_error = elf_i386_check_tls_transition (sec, contents,
   1195  1.16  christos 						      symtab_hdr,
   1196  1.16  christos 						      sym_hashes,
   1197   1.1     skrll 						      from_type, rel,
   1198   1.1     skrll 						      relend))
   1199   1.1     skrll 	  != elf_x86_tls_error_none))
   1200  1.12  christos     {
   1201  1.12  christos       reloc_howto_type *from, *to;
   1202   1.1     skrll 
   1203  1.16  christos       from = elf_i386_rtype_to_howto (from_type);
   1204  1.16  christos       to = elf_i386_rtype_to_howto (to_type);
   1205  1.16  christos 
   1206   1.4  christos       _bfd_x86_elf_link_report_tls_transition_error
   1207  1.13  christos 	(info, abfd, sec, symtab_hdr, h, sym, rel, from->name,
   1208   1.1     skrll 	 to->name, tls_error);
   1209   1.1     skrll 
   1210   1.1     skrll       return false;
   1211  1.13  christos     }
   1212   1.1     skrll 
   1213   1.1     skrll   *r_type = to_type;
   1214   1.9  christos   return true;
   1215   1.9  christos }
   1216   1.9  christos 
   1217   1.9  christos /* With the local symbol, foo, we convert
   1218   1.9  christos    mov foo@GOT[(%reg1)], %reg2
   1219   1.9  christos    to
   1220   1.9  christos    lea foo[@GOTOFF(%reg1)], %reg2
   1221   1.9  christos    and convert
   1222   1.9  christos    call/jmp *foo@GOT[(%reg)]
   1223   1.9  christos    to
   1224   1.9  christos    nop call foo/jmp foo nop
   1225   1.9  christos    When PIC is false, convert
   1226   1.9  christos    test %reg1, foo@GOT[(%reg2)]
   1227  1.16  christos    to
   1228  1.16  christos    test $foo, %reg1
   1229  1.16  christos    and convert
   1230  1.16  christos    push foo@GOT[(%reg)]
   1231   1.9  christos    to
   1232   1.9  christos    push $foo
   1233   1.9  christos    and convert
   1234   1.9  christos    binop foo@GOT[(%reg1)], %reg2
   1235   1.9  christos    to
   1236   1.9  christos    binop $foo, %reg2
   1237   1.9  christos    where binop is one of adc, add, and, cmp, or, sbb, sub, xor
   1238  1.13  christos    instructions.  */
   1239   1.9  christos 
   1240   1.9  christos static
   1241  1.10  christos bool
   1242   1.9  christos elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
   1243   1.9  christos 			     bfd_byte *contents,
   1244  1.13  christos 			     unsigned int *r_type_p,
   1245   1.9  christos 			     Elf_Internal_Rela *irel,
   1246   1.9  christos 			     struct elf_link_hash_entry *h,
   1247  1.10  christos 			     bool *converted,
   1248   1.9  christos 			     struct bfd_link_info *link_info)
   1249   1.9  christos {
   1250  1.13  christos   struct elf_x86_link_hash_table *htab;
   1251   1.9  christos   unsigned int opcode;
   1252   1.9  christos   unsigned int modrm;
   1253   1.9  christos   bool baseless;
   1254   1.9  christos   Elf_Internal_Sym *isym;
   1255  1.16  christos   unsigned int addend;
   1256  1.13  christos   unsigned int nop;
   1257  1.13  christos   bfd_vma nop_offset;
   1258   1.9  christos   bool is_pic, is_branch = false;
   1259   1.9  christos   bool to_reloc_32;
   1260   1.9  christos   bool abs_symbol;
   1261  1.13  christos   unsigned int r_type;
   1262  1.10  christos   unsigned int r_symndx;
   1263   1.9  christos   bfd_vma roff = irel->r_offset;
   1264   1.9  christos   bool local_ref;
   1265  1.13  christos   struct elf_x86_link_hash_entry *eh;
   1266   1.9  christos 
   1267   1.9  christos   if (roff < 2)
   1268   1.9  christos     return true;
   1269   1.9  christos 
   1270  1.13  christos   /* Addend for R_386_GOT32X relocations must be 0.  */
   1271   1.9  christos   addend = bfd_get_32 (abfd, contents + roff);
   1272  1.10  christos   if (addend != 0)
   1273  1.15  christos     return true;
   1274  1.15  christos 
   1275  1.15  christos   htab = elf_x86_hash_table (link_info, I386_ELF_DATA);
   1276  1.15  christos   if (htab == NULL || ! is_x86_elf (abfd, htab))
   1277  1.15  christos     {
   1278  1.15  christos       bfd_set_error (bfd_error_wrong_format);
   1279   1.9  christos       return false;
   1280   1.9  christos     }
   1281  1.10  christos 
   1282   1.9  christos   is_pic = bfd_link_pic (link_info);
   1283   1.9  christos 
   1284   1.9  christos   r_type = *r_type_p;
   1285   1.9  christos   r_symndx = ELF32_R_SYM (irel->r_info);
   1286   1.9  christos 
   1287  1.13  christos   modrm = bfd_get_8 (abfd, contents + roff - 1);
   1288  1.13  christos   baseless = (modrm & 0xc7) == 0x5;
   1289  1.13  christos 
   1290  1.13  christos   if (h)
   1291  1.13  christos     {
   1292  1.13  christos       /* NB: Also set linker_def via SYMBOL_REFERENCES_LOCAL_P.  */
   1293  1.13  christos       local_ref = SYMBOL_REFERENCES_LOCAL_P (link_info, h);
   1294  1.13  christos       isym = NULL;
   1295  1.13  christos       abs_symbol = ABS_SYMBOL_P (h);
   1296  1.13  christos     }
   1297  1.13  christos   else
   1298  1.13  christos     {
   1299  1.13  christos       local_ref = true;
   1300  1.13  christos       isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd,
   1301  1.13  christos 				    r_symndx);
   1302   1.9  christos       abs_symbol = isym->st_shndx == SHN_ABS;
   1303   1.9  christos     }
   1304   1.9  christos 
   1305   1.9  christos   if (baseless && is_pic)
   1306   1.9  christos     {
   1307   1.9  christos       /* For PIC, disallow R_386_GOT32X without a base register
   1308   1.9  christos 	 since we don't know what the GOT base is.  */
   1309  1.13  christos       const char *name;
   1310   1.9  christos 
   1311   1.9  christos       if (h == NULL)
   1312   1.9  christos 	name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
   1313  1.10  christos       else
   1314  1.10  christos 	name = h->root.root.string;
   1315  1.11  christos 
   1316  1.10  christos       _bfd_error_handler
   1317   1.9  christos 	/* xgettext:c-format */
   1318  1.13  christos 	(_("%pB: direct GOT relocation R_386_GOT32X against `%s' without base"
   1319   1.9  christos 	   " register can not be used when making a shared object"),
   1320   1.9  christos 	 abfd, name);
   1321   1.9  christos       return false;
   1322   1.9  christos     }
   1323  1.16  christos 
   1324  1.16  christos   opcode = bfd_get_8 (abfd, contents + roff - 2);
   1325  1.16  christos 
   1326  1.16  christos   if (opcode == 0xff)
   1327  1.16  christos     {
   1328  1.16  christos       switch (modrm & 0x38)
   1329  1.16  christos 	{
   1330  1.16  christos 	case 0x10: /* CALL */
   1331  1.16  christos 	case 0x20: /* JMP */
   1332  1.16  christos 	  is_branch = true;
   1333  1.16  christos 	  break;
   1334  1.16  christos 
   1335  1.16  christos 	case 0x30: /* PUSH */
   1336  1.16  christos 	  break;
   1337  1.16  christos 
   1338  1.16  christos 	default:
   1339  1.16  christos 	  return true;
   1340  1.16  christos 	}
   1341  1.16  christos     }
   1342  1.16  christos 
   1343   1.9  christos   /* Convert to R_386_32 if PIC is false (if PIC is true we already know
   1344  1.10  christos      there is a base register).  */
   1345  1.10  christos   to_reloc_32 = !is_pic;
   1346   1.9  christos 
   1347   1.9  christos   eh = elf_x86_hash_entry (h);
   1348   1.9  christos 
   1349   1.9  christos   /* Try to convert R_386_GOT32X.  Get the symbol referred to by the
   1350  1.16  christos      reloc.  */
   1351   1.9  christos   if (h == NULL)
   1352   1.9  christos     {
   1353   1.9  christos       if (is_branch)
   1354   1.9  christos 	/* Convert "call/jmp *foo@GOT[(%reg)]".  */
   1355   1.9  christos 	goto convert_branch;
   1356   1.9  christos       else
   1357   1.9  christos 	/* Convert "mov foo@GOT[(%reg1)], %reg2",
   1358   1.9  christos 	   "test %reg1, foo@GOT(%reg2)" and
   1359   1.9  christos 	   "binop foo@GOT[(%reg1)], %reg2". */
   1360   1.9  christos 	goto convert_load;
   1361   1.9  christos     }
   1362  1.10  christos 
   1363  1.10  christos   /* Undefined weak symbol is only bound locally in executable
   1364  1.10  christos      and its reference is resolved as 0.  */
   1365   1.9  christos   if (h->root.type == bfd_link_hash_undefweak
   1366  1.16  christos       && !eh->linker_def
   1367   1.9  christos       && local_ref)
   1368   1.9  christos     {
   1369   1.9  christos       if (is_branch)
   1370  1.13  christos 	{
   1371   1.9  christos 	  /* No direct branch to 0 for PIC.  */
   1372   1.9  christos 	  if (is_pic)
   1373   1.9  christos 	    return true;
   1374   1.9  christos 	  else
   1375   1.9  christos 	    goto convert_branch;
   1376   1.9  christos 	}
   1377  1.13  christos       else
   1378   1.9  christos 	{
   1379   1.9  christos 	  /* We can convert load of address 0 to R_386_32.  */
   1380   1.9  christos 	  to_reloc_32 = true;
   1381   1.9  christos 	  goto convert_load;
   1382  1.16  christos 	}
   1383   1.9  christos     }
   1384   1.9  christos 
   1385   1.9  christos   if (is_branch)
   1386   1.9  christos     {
   1387  1.10  christos       /* We have "call/jmp *foo@GOT[(%reg)]".  */
   1388   1.9  christos       if ((h->root.type == bfd_link_hash_defined
   1389   1.9  christos 	   || h->root.type == bfd_link_hash_defweak)
   1390  1.13  christos 	  && local_ref)
   1391   1.9  christos 	{
   1392   1.9  christos 	  /* The function is locally defined.   */
   1393   1.9  christos 	convert_branch:
   1394   1.9  christos 	  /* Convert R_386_GOT32X to R_386_PC32.  */
   1395   1.9  christos 	  if (modrm == 0x15 || (modrm & 0xf8) == 0x90)
   1396   1.9  christos 	    {
   1397   1.9  christos 	      /* Convert to "nop call foo".  ADDR_PREFIX_OPCODE
   1398   1.9  christos 		 is a nop prefix.  */
   1399  1.10  christos 	      modrm = 0xe8;
   1400   1.9  christos 	      /* To support TLS optimization, always use addr32 prefix
   1401   1.9  christos 		 for "call *___tls_get_addr@GOT(%reg)".  */
   1402   1.9  christos 	      if (eh && eh->tls_get_addr)
   1403   1.9  christos 		{
   1404   1.9  christos 		  nop = 0x67;
   1405   1.9  christos 		  nop_offset = irel->r_offset - 2;
   1406  1.12  christos 		}
   1407  1.12  christos 	      else
   1408   1.9  christos 		{
   1409   1.9  christos 		  nop = htab->params->call_nop_byte;
   1410   1.9  christos 		  if (htab->params->call_nop_as_suffix)
   1411   1.9  christos 		    {
   1412   1.9  christos 		      nop_offset = roff + 3;
   1413   1.9  christos 		      irel->r_offset -= 1;
   1414   1.9  christos 		    }
   1415   1.9  christos 		  else
   1416   1.9  christos 		    nop_offset = roff - 2;
   1417   1.9  christos 		}
   1418   1.9  christos 	    }
   1419   1.9  christos 	  else
   1420   1.9  christos 	    {
   1421   1.9  christos 	      /* Convert to "jmp foo nop".  */
   1422   1.9  christos 	      modrm = 0xe9;
   1423   1.9  christos 	      nop = NOP_OPCODE;
   1424   1.9  christos 	      nop_offset = roff + 3;
   1425   1.9  christos 	      irel->r_offset -= 1;
   1426   1.9  christos 	    }
   1427   1.9  christos 
   1428   1.9  christos 	  bfd_put_8 (abfd, nop, contents + nop_offset);
   1429   1.9  christos 	  bfd_put_8 (abfd, modrm, contents + irel->r_offset - 1);
   1430   1.9  christos 	  /* When converting to PC-relative relocation, we
   1431  1.10  christos 	     need to adjust addend by -4.  */
   1432  1.13  christos 	  bfd_put_32 (abfd, -4, contents + irel->r_offset);
   1433   1.9  christos 	  irel->r_info = ELF32_R_INFO (r_symndx, R_386_PC32);
   1434   1.9  christos 	  *r_type_p = R_386_PC32;
   1435   1.9  christos 	  *converted = true;
   1436   1.9  christos 	}
   1437   1.9  christos     }
   1438  1.16  christos   else
   1439  1.16  christos     {
   1440   1.9  christos       /* We have "mov foo@GOT[(%re1g)], %reg2",
   1441   1.9  christos 	 "test %reg1, foo@GOT(%reg2)",
   1442   1.9  christos 	 "push foo@GOT[(%reg)]", or
   1443   1.9  christos 	 "binop foo@GOT[(%reg1)], %reg2".
   1444   1.9  christos 
   1445  1.13  christos 	 Avoid optimizing _DYNAMIC since ld.so may use its
   1446   1.9  christos 	 link-time address.  */
   1447   1.9  christos       if (h == htab->elf.hdynamic)
   1448  1.10  christos 	return true;
   1449  1.10  christos 
   1450  1.10  christos       /* def_regular is set by an assignment in a linker script in
   1451  1.10  christos 	 bfd_elf_record_link_assignment.  start_stop is set on
   1452  1.10  christos 	 __start_SECNAME/__stop_SECNAME which mark section SECNAME.  */
   1453  1.10  christos       if (h->start_stop
   1454  1.10  christos 	  || eh->linker_def
   1455  1.10  christos 	  || ((h->def_regular
   1456   1.9  christos 	       || h->root.type == bfd_link_hash_defined
   1457  1.13  christos 	       || h->root.type == bfd_link_hash_defweak)
   1458   1.9  christos 	      && local_ref))
   1459   1.9  christos 	{
   1460  1.13  christos 	convert_load:
   1461  1.13  christos 	  if (opcode == 0x8b)
   1462  1.13  christos 	    {
   1463   1.9  christos 	      if (abs_symbol && local_ref)
   1464   1.9  christos 		to_reloc_32 = true;
   1465   1.9  christos 
   1466   1.9  christos 	      if (to_reloc_32)
   1467   1.9  christos 		{
   1468   1.9  christos 		  /* Convert "mov foo@GOT[(%reg1)], %reg2" to
   1469   1.9  christos 		     "mov $foo, %reg2" with R_386_32.  */
   1470   1.9  christos 		  r_type = R_386_32;
   1471   1.9  christos 		  modrm = 0xc0 | (modrm & 0x38) >> 3;
   1472   1.9  christos 		  bfd_put_8 (abfd, modrm, contents + roff - 1);
   1473   1.9  christos 		  opcode = 0xc7;
   1474   1.9  christos 		}
   1475   1.9  christos 	      else
   1476   1.9  christos 		{
   1477   1.9  christos 		  /* Convert "mov foo@GOT(%reg1), %reg2" to
   1478   1.9  christos 		     "lea foo@GOTOFF(%reg1), %reg2".  */
   1479   1.9  christos 		  r_type = R_386_GOTOFF;
   1480   1.9  christos 		  opcode = 0x8d;
   1481   1.9  christos 		}
   1482   1.9  christos 	    }
   1483   1.9  christos 	  else
   1484  1.13  christos 	    {
   1485   1.9  christos 	      /* Only R_386_32 is supported.  */
   1486   1.9  christos 	      if (!to_reloc_32)
   1487   1.9  christos 		return true;
   1488   1.9  christos 
   1489   1.9  christos 	      if (opcode == 0x85)
   1490   1.9  christos 		{
   1491   1.9  christos 		  /* Convert "test %reg1, foo@GOT(%reg2)" to
   1492   1.9  christos 		     "test $foo, %reg1".  */
   1493  1.16  christos 		  modrm = 0xc0 | (modrm & 0x38) >> 3;
   1494   1.9  christos 		  opcode = 0xf7;
   1495   1.9  christos 		}
   1496   1.9  christos 	      else if ((opcode | 0x38) == 0x3b)
   1497  1.16  christos 		{
   1498   1.9  christos 		  /* Convert "binop foo@GOT(%reg1), %reg2" to
   1499   1.9  christos 		     "binop $foo, %reg2".  */
   1500  1.16  christos 		  modrm = 0xc0 | ((modrm & 0x38) >> 3) | (opcode & 0x38);
   1501  1.16  christos 		  opcode = 0x81;
   1502  1.16  christos 		}
   1503  1.16  christos 	      else if (opcode == 0xff)
   1504  1.16  christos 		{
   1505  1.16  christos 		  /* Convert "push foo@GOT(%reg)" to
   1506  1.16  christos 		     "push $foo".  */
   1507  1.16  christos 		  modrm = 0x68; /* Really the opcode.  */
   1508  1.16  christos 		  opcode = 0x2e; /* Really a meaningless %cs: prefix.  */
   1509  1.16  christos 		}
   1510   1.9  christos 	      else
   1511   1.9  christos 		return true;
   1512   1.9  christos 
   1513   1.9  christos 	      bfd_put_8 (abfd, modrm, contents + roff - 1);
   1514   1.9  christos 	      r_type = R_386_32;
   1515   1.9  christos 	    }
   1516  1.10  christos 
   1517  1.13  christos 	  bfd_put_8 (abfd, opcode, contents + roff - 2);
   1518   1.9  christos 	  irel->r_info = ELF32_R_INFO (r_symndx, r_type);
   1519   1.9  christos 	  *r_type_p = r_type;
   1520   1.9  christos 	  *converted = true;
   1521  1.13  christos 	}
   1522   1.9  christos     }
   1523   1.9  christos 
   1524   1.1     skrll   return true;
   1525  1.13  christos }
   1526  1.13  christos 
   1527   1.1     skrll /* Look through the relocs for a section during the first phase, and
   1528  1.13  christos    calculate needed space in the global offset table, and procedure
   1529  1.13  christos    linkage table.  */
   1530  1.13  christos 
   1531  1.13  christos static bool
   1532  1.13  christos elf_i386_scan_relocs (bfd *abfd,
   1533   1.1     skrll 		      struct bfd_link_info *info,
   1534  1.10  christos 		      asection *sec,
   1535   1.1     skrll 		      const Elf_Internal_Rela *relocs)
   1536   1.1     skrll {
   1537   1.1     skrll   struct elf_x86_link_hash_table *htab;
   1538   1.1     skrll   Elf_Internal_Shdr *symtab_hdr;
   1539   1.9  christos   struct elf_link_hash_entry **sym_hashes;
   1540  1.13  christos   const Elf_Internal_Rela *rel;
   1541   1.1     skrll   const Elf_Internal_Rela *rel_end;
   1542   1.6  christos   bfd_byte *contents;
   1543  1.13  christos   bool converted;
   1544   1.9  christos 
   1545  1.10  christos   if (bfd_link_relocatable (info))
   1546   1.4  christos     return true;
   1547   1.9  christos 
   1548   1.9  christos   htab = elf_x86_hash_table (info, I386_ELF_DATA);
   1549  1.13  christos   if (htab == NULL)
   1550   1.9  christos     {
   1551   1.9  christos       sec->check_relocs_failed = 1;
   1552  1.10  christos       return false;
   1553  1.10  christos     }
   1554   1.9  christos 
   1555   1.9  christos   BFD_ASSERT (is_x86_elf (abfd, htab));
   1556   1.9  christos 
   1557  1.16  christos   /* Get the section contents.  */
   1558   1.9  christos   if (elf_section_data (sec)->this_hdr.contents != NULL)
   1559   1.9  christos     contents = elf_section_data (sec)->this_hdr.contents;
   1560  1.13  christos   else if (!_bfd_elf_mmap_section_contents (abfd, sec, &contents))
   1561   1.9  christos     {
   1562   1.4  christos       sec->check_relocs_failed = 1;
   1563   1.1     skrll       return false;
   1564   1.1     skrll     }
   1565   1.1     skrll 
   1566  1.13  christos   symtab_hdr = &elf_symtab_hdr (abfd);
   1567   1.1     skrll   sym_hashes = elf_sym_hashes (abfd);
   1568   1.1     skrll 
   1569   1.1     skrll   converted = false;
   1570   1.1     skrll 
   1571   1.1     skrll   rel_end = relocs + sec->reloc_count;
   1572  1.10  christos   for (rel = relocs; rel < rel_end; rel++)
   1573   1.1     skrll     {
   1574  1.10  christos       unsigned int r_type;
   1575   1.4  christos       unsigned int r_symndx;
   1576   1.4  christos       struct elf_link_hash_entry *h;
   1577  1.13  christos       struct elf_x86_link_hash_entry *eh;
   1578  1.13  christos       Elf_Internal_Sym *isym;
   1579  1.16  christos       const char *name;
   1580   1.1     skrll       bool size_reloc;
   1581   1.1     skrll       bool no_dynreloc;
   1582   1.1     skrll       reloc_howto_type *howto;
   1583   1.1     skrll 
   1584  1.15  christos       r_symndx = ELF32_R_SYM (rel->r_info);
   1585  1.15  christos       r_type = ELF32_R_TYPE (rel->r_info);
   1586  1.15  christos 
   1587  1.15  christos       /* Don't check R_386_NONE.  */
   1588   1.1     skrll       if (r_type == R_386_NONE)
   1589   1.1     skrll 	continue;
   1590  1.10  christos 
   1591  1.11  christos       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
   1592  1.10  christos 	{
   1593   1.9  christos 	  /* xgettext:c-format */
   1594   1.1     skrll 	  _bfd_error_handler (_("%pB: bad symbol index: %d"),
   1595   1.1     skrll 			      abfd, r_symndx);
   1596  1.16  christos 	  goto error_return;
   1597  1.16  christos 	}
   1598  1.16  christos 
   1599  1.16  christos       howto = elf_i386_rtype_to_howto (r_type);
   1600  1.16  christos       if (rel->r_offset + bfd_get_reloc_size (howto) > sec->size)
   1601  1.16  christos 	{
   1602  1.16  christos 	  /* xgettext:c-format */
   1603  1.16  christos 	  _bfd_error_handler
   1604  1.16  christos 	    (_("%pB: bad reloc offset (%#" PRIx32 " > %#" PRIx32 ") for"
   1605  1.16  christos 	       " section `%pA'"), abfd, (uint32_t) rel->r_offset,
   1606  1.16  christos 	     (uint32_t) sec->size, sec);
   1607   1.1     skrll 	  goto error_return;
   1608   1.4  christos 	}
   1609   1.4  christos 
   1610  1.13  christos       if (r_symndx < symtab_hdr->sh_info)
   1611   1.4  christos 	{
   1612   1.4  christos 	  /* A local symbol.  */
   1613   1.9  christos 	  isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
   1614   1.4  christos 					abfd, r_symndx);
   1615   1.4  christos 	  if (isym == NULL)
   1616   1.4  christos 	    goto error_return;
   1617   1.4  christos 
   1618  1.13  christos 	  /* Check relocation against local STT_GNU_IFUNC symbol.  */
   1619   1.4  christos 	  if (ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
   1620   1.9  christos 	    {
   1621   1.4  christos 	      h = _bfd_elf_x86_get_local_sym_hash (htab, abfd, rel, true);
   1622   1.4  christos 	      if (h == NULL)
   1623  1.10  christos 		goto error_return;
   1624  1.10  christos 
   1625  1.17  christos 	      /* Fake a STT_GNU_IFUNC symbol.  */
   1626  1.17  christos 	      h->root.root.string = bfd_elf_sym_name (abfd, symtab_hdr,
   1627   1.4  christos 						      isym, NULL);
   1628   1.4  christos 	      if (h->root.root.string == bfd_symbol_error_name)
   1629   1.4  christos 		goto error_return;
   1630   1.4  christos 	      h->type = STT_GNU_IFUNC;
   1631   1.4  christos 	      h->def_regular = 1;
   1632   1.4  christos 	      h->ref_regular = 1;
   1633   1.4  christos 	      h->forced_local = 1;
   1634   1.4  christos 	      h->root.type = bfd_link_hash_defined;
   1635   1.4  christos 	    }
   1636   1.1     skrll 	  else
   1637   1.1     skrll 	    h = NULL;
   1638   1.4  christos 	}
   1639   1.1     skrll       else
   1640   1.1     skrll 	{
   1641   1.1     skrll 	  isym = NULL;
   1642   1.1     skrll 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
   1643   1.1     skrll 	  while (h->root.type == bfd_link_hash_indirect
   1644   1.1     skrll 		 || h->root.type == bfd_link_hash_warning)
   1645  1.10  christos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   1646   1.4  christos 	}
   1647   1.4  christos 
   1648  1.10  christos       eh = (struct elf_x86_link_hash_entry *) h;
   1649  1.10  christos       if (h != NULL)
   1650  1.10  christos 	{
   1651  1.10  christos 	  if (r_type == R_386_GOTOFF)
   1652  1.10  christos 	    eh->gotoff_ref = 1;
   1653   1.4  christos 
   1654   1.4  christos 	  /* It is referenced by a non-shared object. */
   1655  1.10  christos 	  h->ref_regular = 1;
   1656  1.10  christos 	}
   1657  1.10  christos 
   1658  1.10  christos       if (r_type == R_386_GOT32X
   1659  1.10  christos 	  && (h == NULL || h->type != STT_GNU_IFUNC))
   1660  1.10  christos 	{
   1661  1.10  christos 	  Elf_Internal_Rela *irel = (Elf_Internal_Rela *) rel;
   1662  1.10  christos 	  if (!elf_i386_convert_load_reloc (abfd, symtab_hdr, contents,
   1663  1.10  christos 					    &r_type, irel, h,
   1664  1.10  christos 					    &converted, info))
   1665  1.13  christos 	    goto error_return;
   1666  1.13  christos 	}
   1667  1.13  christos 
   1668  1.13  christos       if (!_bfd_elf_x86_valid_reloc_p (sec, info, htab, rel, h, isym,
   1669   1.9  christos 				       symtab_hdr, &no_dynreloc))
   1670   1.1     skrll 	return false;
   1671   1.1     skrll 
   1672  1.16  christos       if (! elf_i386_tls_transition (info, abfd, sec, contents,
   1673   1.9  christos 				     symtab_hdr, sym_hashes,
   1674   1.1     skrll 				     &r_type, GOT_UNKNOWN,
   1675  1.11  christos 				     rel, rel_end, h, isym, false))
   1676  1.11  christos 	goto error_return;
   1677  1.13  christos 
   1678  1.11  christos       /* Check if _GLOBAL_OFFSET_TABLE_ is referenced.  */
   1679   1.1     skrll       if (h == htab->elf.hgot)
   1680   1.1     skrll 	htab->got_referenced = true;
   1681   1.1     skrll 
   1682  1.10  christos       switch (r_type)
   1683   1.1     skrll 	{
   1684   1.1     skrll 	case R_386_TLS_LDM:
   1685   1.1     skrll 	  htab->tls_ld_or_ldm_got.refcount = 1;
   1686   1.1     skrll 	  goto create_got;
   1687   1.1     skrll 
   1688   1.1     skrll 	case R_386_PLT32:
   1689   1.1     skrll 	  /* This symbol requires a procedure linkage table entry.  We
   1690   1.1     skrll 	     actually build the entry in adjust_dynamic_symbol,
   1691   1.1     skrll 	     because this might be a case of linking PIC code which is
   1692   1.1     skrll 	     never referenced by a dynamic object, in which case we
   1693   1.1     skrll 	     don't need to generate a procedure linkage table entry
   1694   1.1     skrll 	     after all.  */
   1695   1.1     skrll 
   1696   1.1     skrll 	  /* If this is a local symbol, we resolve it directly without
   1697   1.1     skrll 	     creating a procedure linkage table entry.  */
   1698  1.10  christos 	  if (h == NULL)
   1699   1.1     skrll 	    continue;
   1700  1.10  christos 
   1701   1.1     skrll 	  eh->zero_undefweak &= 0x2;
   1702   1.1     skrll 	  h->needs_plt = 1;
   1703   1.6  christos 	  h->plt.refcount = 1;
   1704  1.13  christos 	  break;
   1705   1.6  christos 
   1706   1.6  christos 	case R_386_SIZE32:
   1707  1.17  christos 	  size_reloc = true;
   1708  1.17  christos 	  goto do_size;
   1709  1.17  christos 
   1710  1.17  christos 	case R_386_TLS_DESC_CALL:
   1711   1.1     skrll 	  htab->has_tls_desc_call = 1;
   1712   1.1     skrll 	  goto need_got;
   1713   1.1     skrll 
   1714   1.6  christos 	case R_386_TLS_IE_32:
   1715   1.1     skrll 	case R_386_TLS_IE:
   1716   1.1     skrll 	case R_386_TLS_GOTIE:
   1717   1.1     skrll 	  if (!bfd_link_executable (info))
   1718   1.1     skrll 	    info->flags |= DF_STATIC_TLS;
   1719   1.6  christos 	  /* Fall through */
   1720   1.1     skrll 
   1721   1.1     skrll 	case R_386_GOT32:
   1722  1.17  christos 	case R_386_GOT32X:
   1723   1.1     skrll 	case R_386_TLS_GD:
   1724   1.1     skrll 	case R_386_TLS_GOTDESC:
   1725   1.1     skrll  need_got:
   1726   1.1     skrll 	  /* This symbol requires a global offset table entry.  */
   1727   1.1     skrll 	  {
   1728   1.1     skrll 	    int tls_type, old_tls_type;
   1729   1.1     skrll 
   1730   1.6  christos 	    switch (r_type)
   1731   1.6  christos 	      {
   1732   1.6  christos 	      default:
   1733   1.6  christos 	      case R_386_GOT32:
   1734   1.1     skrll 	      case R_386_GOT32X:
   1735   1.1     skrll 		tls_type = GOT_NORMAL;
   1736   1.1     skrll 		break;
   1737   1.1     skrll 	      case R_386_TLS_GD: tls_type = GOT_TLS_GD; break;
   1738   1.1     skrll 	      case R_386_TLS_GOTDESC:
   1739   1.1     skrll 	      case R_386_TLS_DESC_CALL:
   1740   1.1     skrll 		tls_type = GOT_TLS_GDESC; break;
   1741   1.1     skrll 	      case R_386_TLS_IE_32:
   1742   1.1     skrll 		if (ELF32_R_TYPE (rel->r_info) == r_type)
   1743   1.1     skrll 		  tls_type = GOT_TLS_IE_NEG;
   1744   1.1     skrll 		else
   1745   1.1     skrll 		  /* If this is a GD->IE transition, we may use either of
   1746   1.1     skrll 		     R_386_TLS_TPOFF and R_386_TLS_TPOFF32.  */
   1747   1.1     skrll 		  tls_type = GOT_TLS_IE;
   1748   1.1     skrll 		break;
   1749   1.1     skrll 	      case R_386_TLS_IE:
   1750   1.1     skrll 	      case R_386_TLS_GOTIE:
   1751  1.17  christos 		tls_type = GOT_TLS_IE_POS; break;
   1752  1.17  christos 	      }
   1753  1.17  christos 
   1754  1.17  christos 	    if (tls_type >= GOT_TLS_GD
   1755  1.17  christos 		&& tls_type <= GOT_TLS_GDESC
   1756  1.17  christos 		&& (elf_section_type (sec) != SHT_PROGBITS
   1757  1.17  christos 		    || (sec->flags & SEC_CODE) == 0))
   1758  1.17  christos 	      {
   1759  1.17  christos 		_bfd_x86_elf_link_report_tls_invalid_section_error
   1760  1.17  christos 		  (abfd, sec, symtab_hdr, h, isym, howto);
   1761   1.1     skrll 		goto error_return;
   1762   1.1     skrll 	      }
   1763  1.10  christos 
   1764  1.10  christos 	    if (h != NULL)
   1765   1.1     skrll 	      {
   1766   1.1     skrll 		h->got.refcount = 1;
   1767   1.1     skrll 		old_tls_type = elf_x86_hash_entry (h)->tls_type;
   1768   1.1     skrll 	      }
   1769   1.1     skrll 	    else
   1770  1.13  christos 	      {
   1771  1.13  christos 		bfd_signed_vma *local_got_refcounts;
   1772  1.13  christos 
   1773  1.13  christos 		if (!elf_x86_allocate_local_got_info (abfd,
   1774   1.1     skrll 						      symtab_hdr->sh_info))
   1775   1.1     skrll 		      goto error_return;
   1776  1.10  christos 
   1777  1.10  christos 		/* This is a global offset table entry for a local symbol.  */
   1778   1.1     skrll 		local_got_refcounts = elf_local_got_refcounts (abfd);
   1779   1.1     skrll 		local_got_refcounts[r_symndx] = 1;
   1780   1.1     skrll 		old_tls_type = elf_x86_local_got_tls_type (abfd) [r_symndx];
   1781   1.1     skrll 	      }
   1782   1.1     skrll 
   1783   1.1     skrll 	    if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_IE))
   1784   1.1     skrll 	      tls_type |= old_tls_type;
   1785   1.1     skrll 	    /* If a TLS symbol is accessed using IE at least once,
   1786   1.1     skrll 	       there is no point to use dynamic model for it.  */
   1787   1.1     skrll 	    else if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
   1788   1.1     skrll 		     && (! GOT_TLS_GD_ANY_P (old_tls_type)
   1789   1.1     skrll 			 || (tls_type & GOT_TLS_IE) == 0))
   1790   1.1     skrll 	      {
   1791   1.1     skrll 		if ((old_tls_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (tls_type))
   1792   1.1     skrll 		  tls_type = old_tls_type;
   1793   1.1     skrll 		else if (GOT_TLS_GD_ANY_P (old_tls_type)
   1794   1.1     skrll 			 && GOT_TLS_GD_ANY_P (tls_type))
   1795   1.4  christos 		  tls_type |= old_tls_type;
   1796   1.4  christos 		else
   1797   1.4  christos 		  {
   1798   1.4  christos 		    if (h)
   1799  1.16  christos 		      name = h->root.root.string;
   1800  1.10  christos 		    else
   1801  1.10  christos 		      name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
   1802  1.11  christos 					       NULL);
   1803   1.1     skrll 		    _bfd_error_handler
   1804   1.4  christos 		      /* xgettext:c-format */
   1805   1.6  christos 		      (_("%pB: `%s' accessed both as normal and "
   1806   1.9  christos 			 "thread local symbol"),
   1807   1.1     skrll 		       abfd, name);
   1808   1.1     skrll 		    bfd_set_error (bfd_error_bad_value);
   1809   1.1     skrll 		    goto error_return;
   1810   1.1     skrll 		  }
   1811   1.1     skrll 	      }
   1812   1.1     skrll 
   1813  1.10  christos 	    if (old_tls_type != tls_type)
   1814   1.1     skrll 	      {
   1815  1.10  christos 		if (h != NULL)
   1816   1.1     skrll 		  elf_x86_hash_entry (h)->tls_type = tls_type;
   1817   1.1     skrll 		else
   1818   1.1     skrll 		  elf_x86_local_got_tls_type (abfd) [r_symndx] = tls_type;
   1819   1.1     skrll 	      }
   1820   1.1     skrll 	  }
   1821   1.1     skrll 	  /* Fall through */
   1822  1.13  christos 
   1823   1.1     skrll 	case R_386_GOTOFF:
   1824   1.9  christos 	case R_386_GOTPC:
   1825   1.9  christos 	create_got:
   1826  1.11  christos 	  if (r_type != R_386_TLS_IE)
   1827  1.11  christos 	    {
   1828  1.11  christos 	      if (eh != NULL)
   1829  1.11  christos 		{
   1830  1.11  christos 		  eh->zero_undefweak &= 0x2;
   1831  1.11  christos 
   1832  1.11  christos 		  /* Need GOT to resolve undefined weak symbol to 0.  */
   1833  1.13  christos 		  if (r_type == R_386_GOTOFF
   1834  1.11  christos 		      && h->root.type == bfd_link_hash_undefweak
   1835   1.9  christos 		      && bfd_link_executable (info))
   1836   1.9  christos 		    htab->got_referenced = true;
   1837   1.1     skrll 		}
   1838   1.1     skrll 	      break;
   1839   1.1     skrll 	    }
   1840   1.1     skrll 	  /* Fall through */
   1841   1.9  christos 
   1842  1.10  christos 	case R_386_TLS_LE_32:
   1843   1.6  christos 	case R_386_TLS_LE:
   1844   1.1     skrll 	  if (eh != NULL)
   1845   1.1     skrll 	    eh->zero_undefweak &= 0x2;
   1846   1.9  christos 	  if (bfd_link_executable (info))
   1847   1.1     skrll 	    break;
   1848   1.1     skrll 	  info->flags |= DF_STATIC_TLS;
   1849   1.1     skrll 	  goto do_relocation;
   1850   1.9  christos 
   1851  1.10  christos 	case R_386_32:
   1852  1.13  christos 	case R_386_PC32:
   1853   1.9  christos 	  if (eh != NULL && (sec->flags & SEC_CODE) != 0)
   1854   1.9  christos 	    eh->zero_undefweak |= 0x2;
   1855   1.9  christos 	do_relocation:
   1856   1.9  christos 	  /* We are called after all symbols have been resolved.  Only
   1857   1.9  christos 	     relocation against STT_GNU_IFUNC symbol must go through
   1858   1.9  christos 	     PLT.  */
   1859   1.1     skrll 	  if (h != NULL
   1860  1.13  christos 	      && (bfd_link_executable (info)
   1861   1.9  christos 		  || h->type == STT_GNU_IFUNC))
   1862   1.6  christos 	    {
   1863   1.6  christos 	      bool func_pointer_ref = false;
   1864   1.6  christos 
   1865   1.6  christos 	      if (r_type == R_386_PC32)
   1866   1.6  christos 		{
   1867   1.6  christos 		  /* Since something like ".long foo - ." may be used
   1868   1.6  christos 		     as pointer, make sure that PLT is used if foo is
   1869  1.10  christos 		     a function defined in a shared library.  */
   1870  1.10  christos 		  if ((sec->flags & SEC_CODE) == 0)
   1871  1.10  christos 		    h->pointer_equality_needed = 1;
   1872  1.10  christos 		  else if (h->type == STT_GNU_IFUNC
   1873  1.10  christos 			   && bfd_link_pic (info))
   1874  1.11  christos 		    {
   1875  1.10  christos 		      _bfd_error_handler
   1876  1.10  christos 			/* xgettext:c-format */
   1877  1.10  christos 			(_("%pB: unsupported non-PIC call to IFUNC `%s'"),
   1878  1.10  christos 			 abfd, h->root.root.string);
   1879   1.6  christos 		      bfd_set_error (bfd_error_bad_value);
   1880   1.6  christos 		      goto error_return;
   1881   1.6  christos 		    }
   1882  1.13  christos 		}
   1883  1.13  christos 	      else
   1884  1.13  christos 		{
   1885   1.6  christos 		  /* R_386_32 can be resolved at run-time.  Function
   1886   1.6  christos 		     pointer reference doesn't need PLT for pointer
   1887  1.13  christos 		     equality.  */
   1888  1.13  christos 		  if (r_type == R_386_32
   1889  1.13  christos 		      && (sec->flags & SEC_READONLY) == 0)
   1890  1.13  christos 		    func_pointer_ref = true;
   1891  1.13  christos 
   1892  1.13  christos 		  /* IFUNC symbol needs pointer equality in PDE so that
   1893  1.13  christos 		     function pointer reference will be resolved to its
   1894  1.13  christos 		     PLT entry directly.  */
   1895  1.13  christos 		  if (!func_pointer_ref
   1896  1.10  christos 		      || (bfd_link_pde (info)
   1897  1.10  christos 			  && h->type == STT_GNU_IFUNC))
   1898  1.10  christos 		    h->pointer_equality_needed = 1;
   1899  1.10  christos 		}
   1900  1.10  christos 
   1901  1.10  christos 	      if (!func_pointer_ref)
   1902  1.10  christos 		{
   1903  1.10  christos 		  /* If this reloc is in a read-only section, we might
   1904  1.10  christos 		     need a copy reloc.  We can't check reliably at this
   1905  1.10  christos 		     stage whether the section is read-only, as input
   1906  1.10  christos 		     sections have not yet been mapped to output sections.
   1907  1.10  christos 		     Tentatively set the flag for now, and correct in
   1908  1.13  christos 		     adjust_dynamic_symbol.  */
   1909  1.13  christos 		  h->non_got_ref = 1;
   1910  1.13  christos 
   1911  1.10  christos 		  if (!elf_has_indirect_extern_access (sec->owner))
   1912  1.10  christos 		    eh->non_got_ref_without_indirect_extern_access = 1;
   1913  1.10  christos 
   1914  1.10  christos 		  /* We may need a .plt entry if the symbol is a function
   1915  1.10  christos 		     defined in a shared lib or is a function referenced
   1916  1.10  christos 		     from the code or read-only section.  */
   1917  1.13  christos 		  if (!h->def_regular
   1918  1.15  christos 		      || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
   1919  1.15  christos 		    h->plt.refcount = 1;
   1920  1.13  christos 
   1921  1.13  christos 		  if (htab->elf.target_os != is_solaris
   1922  1.13  christos 		      && h->pointer_equality_needed
   1923  1.13  christos 		      && h->type == STT_FUNC
   1924  1.13  christos 		      && eh->def_protected
   1925  1.13  christos 		      && !SYMBOL_DEFINED_NON_SHARED_P (h)
   1926  1.13  christos 		      && h->def_dynamic)
   1927  1.13  christos 		    {
   1928  1.13  christos 		      /* Disallow non-canonical reference to canonical
   1929  1.13  christos 			 protected function.  */
   1930  1.13  christos 		      _bfd_error_handler
   1931  1.13  christos 			/* xgettext:c-format */
   1932  1.13  christos 			(_("%pB: non-canonical reference to canonical "
   1933  1.13  christos 			   "protected function `%s' in %pB"),
   1934  1.13  christos 			 abfd, h->root.root.string,
   1935  1.13  christos 			 h->root.u.def.section->owner);
   1936   1.6  christos 		      bfd_set_error (bfd_error_bad_value);
   1937   1.1     skrll 		      goto error_return;
   1938   1.1     skrll 		    }
   1939  1.13  christos 		}
   1940  1.13  christos 	    }
   1941  1.13  christos 
   1942  1.13  christos 	  size_reloc = false;
   1943  1.13  christos 	do_size:
   1944   1.1     skrll 	  if (!no_dynreloc
   1945   1.4  christos 	      && NEED_DYNAMIC_RELOCATION_P (false, info, false, h, sec,
   1946   1.4  christos 					    r_type, R_386_32))
   1947   1.1     skrll 	    {
   1948   1.1     skrll 	      struct elf_dyn_relocs *p;
   1949   1.1     skrll 	      struct elf_dyn_relocs **head;
   1950   1.1     skrll 
   1951   1.1     skrll 	      /* If this is a global symbol, we count the number of
   1952  1.13  christos 		 relocations we need for this symbol.  */
   1953   1.1     skrll 	      if (h != NULL)
   1954   1.1     skrll 		{
   1955   1.1     skrll 		  head = &h->dyn_relocs;
   1956   1.1     skrll 		}
   1957   1.1     skrll 	      else
   1958   1.1     skrll 		{
   1959   1.4  christos 		  /* Track dynamic relocs needed for local syms too.
   1960   1.4  christos 		     We really need local syms available to do this
   1961   1.4  christos 		     easily.  Oh well.  */
   1962  1.13  christos 		  void **vpp;
   1963   1.4  christos 		  asection *s;
   1964   1.4  christos 
   1965   1.9  christos 		  isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
   1966   1.1     skrll 						abfd, r_symndx);
   1967   1.4  christos 		  if (isym == NULL)
   1968   1.1     skrll 		    goto error_return;
   1969   1.4  christos 
   1970   1.1     skrll 		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
   1971   1.1     skrll 		  if (s == NULL)
   1972   1.4  christos 		    s = sec;
   1973   1.1     skrll 
   1974   1.1     skrll 		  vpp = &elf_section_data (s)->local_dynrel;
   1975   1.1     skrll 		  head = (struct elf_dyn_relocs **)vpp;
   1976   1.1     skrll 		}
   1977   1.1     skrll 
   1978  1.13  christos 	      p = *head;
   1979   1.4  christos 	      if (p == NULL || p->sec != sec)
   1980  1.10  christos 		{
   1981   1.1     skrll 		  size_t amt = sizeof *p;
   1982   1.9  christos 		  p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj,
   1983   1.1     skrll 							   amt);
   1984   1.1     skrll 		  if (p == NULL)
   1985   1.1     skrll 		    goto error_return;
   1986   1.1     skrll 		  p->next = *head;
   1987   1.1     skrll 		  *head = p;
   1988   1.1     skrll 		  p->sec = sec;
   1989   1.1     skrll 		  p->count = 0;
   1990   1.1     skrll 		  p->pc_count = 0;
   1991   1.6  christos 		}
   1992   1.6  christos 
   1993   1.1     skrll 	      p->count += 1;
   1994   1.1     skrll 	      /* Count size relocation as PC-relative relocation.  */
   1995   1.1     skrll 	      if (r_type == R_386_PC32 || size_reloc)
   1996   1.1     skrll 		p->pc_count += 1;
   1997   1.1     skrll 	    }
   1998   1.1     skrll 	  break;
   1999   1.1     skrll 
   2000   1.1     skrll 	  /* This relocation describes the C++ object vtable hierarchy.
   2001   1.9  christos 	     Reconstruct it for later use during GC.  */
   2002   1.1     skrll 	case R_386_GNU_VTINHERIT:
   2003   1.1     skrll 	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
   2004   1.1     skrll 	    goto error_return;
   2005   1.1     skrll 	  break;
   2006   1.1     skrll 
   2007  1.12  christos 	  /* This relocation describes which C++ vtable entries are actually
   2008   1.9  christos 	     used.  Record for later use during GC.  */
   2009   1.1     skrll 	case R_386_GNU_VTENTRY:
   2010   1.1     skrll 	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
   2011   1.1     skrll 	    goto error_return;
   2012   1.1     skrll 	  break;
   2013   1.1     skrll 
   2014   1.9  christos 	default:
   2015   1.9  christos 	  break;
   2016   1.9  christos 	}
   2017   1.1     skrll     }
   2018  1.16  christos 
   2019  1.16  christos   if (elf_section_data (sec)->this_hdr.contents != contents)
   2020   1.6  christos     {
   2021   1.6  christos       if (!converted)
   2022  1.10  christos 	_bfd_elf_munmap_section_contents (sec, contents);
   2023  1.10  christos       else
   2024   1.6  christos 	{
   2025  1.13  christos 	  /* Cache the section contents for elf_link_input_bfd if any
   2026   1.6  christos 	     load is converted or --no-keep-memory isn't used.  */
   2027   1.6  christos 	  elf_section_data (sec)->this_hdr.contents = contents;
   2028   1.6  christos 	  info->cache_size += sec->size;
   2029  1.10  christos 	}
   2030  1.10  christos     }
   2031  1.10  christos 
   2032  1.10  christos   /* Cache relocations if any load is converted.  */
   2033  1.13  christos   if (elf_section_data (sec)->relocs != relocs && converted)
   2034  1.10  christos     elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs;
   2035  1.13  christos 
   2036  1.10  christos   return true;
   2037  1.16  christos 
   2038  1.10  christos  error_return:
   2039  1.13  christos   if (elf_section_data (sec)->this_hdr.contents != contents)
   2040  1.13  christos     _bfd_elf_munmap_section_contents (sec, contents);
   2041  1.13  christos   sec->check_relocs_failed = 1;
   2042  1.13  christos   return false;
   2043  1.16  christos }
   2044  1.13  christos 
   2045  1.13  christos static bool
   2046  1.13  christos elf_i386_early_size_sections (bfd *output_bfd, struct bfd_link_info *info)
   2047  1.13  christos {
   2048  1.13  christos   bfd *abfd;
   2049  1.13  christos 
   2050  1.13  christos   /* Scan relocations after rel_from_abs has been set on __ehdr_start.  */
   2051  1.13  christos   for (abfd = info->input_bfds;
   2052  1.13  christos        abfd != (bfd *) NULL;
   2053  1.13  christos        abfd = abfd->link.next)
   2054  1.13  christos     if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
   2055  1.13  christos 	&& !_bfd_elf_link_iterate_on_relocs (abfd, info,
   2056  1.16  christos 					     elf_i386_scan_relocs))
   2057   1.1     skrll       return false;
   2058   1.1     skrll 
   2059   1.1     skrll   return _bfd_x86_elf_early_size_sections (output_bfd, info);
   2060   1.1     skrll }
   2061   1.1     skrll 
   2062  1.13  christos /* Set the correct type for an x86 ELF section.  We do this by the
   2063   1.1     skrll    section name, which is a hack, but ought to work.  */
   2064   1.1     skrll 
   2065   1.1     skrll static bool
   2066   1.1     skrll elf_i386_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
   2067   1.4  christos 			Elf_Internal_Shdr *hdr,
   2068   1.1     skrll 			asection *sec)
   2069  1.12  christos {
   2070   1.1     skrll   const char *name;
   2071   1.1     skrll 
   2072   1.1     skrll   name = bfd_section_name (sec);
   2073   1.1     skrll 
   2074   1.1     skrll   /* This is an ugly, but unfortunately necessary hack that is
   2075   1.1     skrll      needed when producing EFI binaries on x86. It tells
   2076   1.1     skrll      elf.c:elf_fake_sections() not to consider ".reloc" as a section
   2077   1.1     skrll      containing ELF relocation info.  We need this hack in order to
   2078   1.1     skrll      be able to generate ELF binaries that can be translated into
   2079   1.1     skrll      EFI applications (which are essentially COFF objects).  Those
   2080   1.1     skrll      files contain a COFF ".reloc" section inside an ELFNN object,
   2081   1.1     skrll      which would normally cause BFD to segfault because it would
   2082   1.1     skrll      attempt to interpret this section as containing relocation
   2083   1.1     skrll      entries for section "oc".  With this hack enabled, ".reloc"
   2084   1.1     skrll      will be treated as a normal data section, which will avoid the
   2085   1.1     skrll      segfault.  However, you won't be able to create an ELFNN binary
   2086   1.1     skrll      with a section named "oc" that needs relocations, but that's
   2087   1.1     skrll      the kind of ugly side-effects you get when detecting section
   2088   1.1     skrll      types based on their names...  In practice, this limitation is
   2089   1.1     skrll      unlikely to bite.  */
   2090  1.13  christos   if (strcmp (name, ".reloc") == 0)
   2091   1.1     skrll     hdr->sh_type = SHT_PROGBITS;
   2092   1.1     skrll 
   2093   1.1     skrll   return true;
   2094   1.1     skrll }
   2095   1.1     skrll 
   2096   1.1     skrll /* Return the relocation value for @tpoff relocation
   2097   1.4  christos    if STT_TLS virtual address is ADDRESS.  */
   2098   1.1     skrll 
   2099   1.1     skrll static bfd_vma
   2100  1.17  christos elf_i386_tpoff (struct bfd_link_info *info, bfd_vma address)
   2101   1.4  christos {
   2102   1.1     skrll   struct elf_link_hash_table *htab = elf_hash_table (info);
   2103   1.1     skrll   elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
   2104   1.1     skrll   bfd_vma static_tls_size;
   2105   1.1     skrll 
   2106   1.4  christos   /* If tls_sec is NULL, we should have signalled an error already.  */
   2107   1.4  christos   if (htab->tls_sec == NULL)
   2108   1.4  christos     return 0;
   2109   1.4  christos 
   2110   1.1     skrll   /* Consider special static TLS alignment requirements.  */
   2111   1.1     skrll   static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment);
   2112   1.1     skrll   return static_tls_size + htab->tls_sec->vma - address;
   2113   1.1     skrll }
   2114  1.13  christos 
   2115   1.1     skrll /* Relocate an i386 ELF section.  */
   2116   1.1     skrll 
   2117   1.1     skrll static int
   2118   1.1     skrll elf_i386_relocate_section (bfd *output_bfd,
   2119   1.1     skrll 			   struct bfd_link_info *info,
   2120   1.1     skrll 			   bfd *input_bfd,
   2121   1.1     skrll 			   asection *input_section,
   2122   1.1     skrll 			   bfd_byte *contents,
   2123   1.1     skrll 			   Elf_Internal_Rela *relocs,
   2124  1.10  christos 			   Elf_Internal_Sym *local_syms,
   2125   1.1     skrll 			   asection **local_sections)
   2126   1.1     skrll {
   2127   1.1     skrll   struct elf_x86_link_hash_table *htab;
   2128   1.1     skrll   Elf_Internal_Shdr *symtab_hdr;
   2129   1.1     skrll   struct elf_link_hash_entry **sym_hashes;
   2130   1.6  christos   bfd_vma *local_got_offsets;
   2131   1.1     skrll   bfd_vma *local_tlsdesc_gotents;
   2132  1.13  christos   Elf_Internal_Rela *rel;
   2133  1.15  christos   Elf_Internal_Rela *wrel;
   2134   1.5  christos   Elf_Internal_Rela *relend;
   2135   1.1     skrll   bool is_vxworks_tls;
   2136  1.13  christos   unsigned expected_tls_le;
   2137   1.9  christos   unsigned plt_entry_size;
   2138  1.13  christos 
   2139   1.9  christos   /* Skip if check_relocs or scan_relocs failed.  */
   2140  1.10  christos   if (input_section->check_relocs_failed)
   2141   1.4  christos     return false;
   2142  1.13  christos 
   2143  1.10  christos   htab = elf_x86_hash_table (info, I386_ELF_DATA);
   2144  1.12  christos   if (htab == NULL)
   2145  1.12  christos     return false;
   2146  1.12  christos 
   2147  1.13  christos   if (!is_x86_elf (input_bfd, htab))
   2148  1.12  christos     {
   2149  1.10  christos       bfd_set_error (bfd_error_wrong_format);
   2150   1.1     skrll       return false;
   2151   1.1     skrll     }
   2152   1.1     skrll 
   2153  1.10  christos   symtab_hdr = &elf_symtab_hdr (input_bfd);
   2154   1.1     skrll   sym_hashes = elf_sym_hashes (input_bfd);
   2155   1.1     skrll   local_got_offsets = elf_local_got_offsets (input_bfd);
   2156  1.13  christos   local_tlsdesc_gotents = elf_x86_local_tlsdesc_gotent (input_bfd);
   2157  1.10  christos   /* We have to handle relocations in vxworks .tls_vars sections
   2158   1.1     skrll      specially, because the dynamic loader is 'weird'.  */
   2159   1.1     skrll   is_vxworks_tls = (htab->elf.target_os == is_vxworks
   2160   1.1     skrll 		    && bfd_link_pic (info)
   2161  1.10  christos 		    && !strcmp (input_section->output_section->name,
   2162   1.1     skrll 				".tls_vars"));
   2163  1.10  christos 
   2164   1.5  christos   _bfd_x86_elf_set_tls_module_base (info);
   2165   1.6  christos 
   2166   1.1     skrll   plt_entry_size = htab->plt.plt_entry_size;
   2167   1.6  christos 
   2168   1.1     skrll   rel = wrel = relocs;
   2169  1.10  christos   relend = relocs + input_section->reloc_count;
   2170   1.1     skrll   for (; rel < relend; wrel++, rel++)
   2171   1.1     skrll     {
   2172   1.1     skrll       unsigned int r_type, r_type_tls;
   2173  1.10  christos       reloc_howto_type *howto;
   2174   1.1     skrll       unsigned long r_symndx;
   2175   1.1     skrll       struct elf_link_hash_entry *h;
   2176   1.6  christos       struct elf_x86_link_hash_entry *eh;
   2177   1.1     skrll       Elf_Internal_Sym *sym;
   2178  1.13  christos       asection *sec;
   2179   1.1     skrll       bfd_vma off, offplt, plt_offset;
   2180   1.1     skrll       bfd_vma relocation;
   2181   1.1     skrll       bool unresolved_reloc;
   2182   1.6  christos       bfd_reloc_status_type r;
   2183   1.6  christos       unsigned int indx;
   2184  1.13  christos       int tls_type;
   2185  1.13  christos       bfd_vma st_size;
   2186   1.1     skrll       asection *resolved_plt;
   2187   1.1     skrll       bool resolved_to_zero;
   2188   1.1     skrll       bool relative_reloc;
   2189   1.1     skrll 
   2190   1.6  christos       r_type = ELF32_R_TYPE (rel->r_info);
   2191   1.6  christos       if (r_type == R_386_GNU_VTINHERIT
   2192   1.6  christos 	  || r_type == R_386_GNU_VTENTRY)
   2193   1.6  christos 	{
   2194   1.6  christos 	  if (wrel != rel)
   2195   1.1     skrll 	    *wrel = *rel;
   2196  1.12  christos 	  continue;
   2197  1.12  christos 	}
   2198  1.10  christos 
   2199  1.10  christos       howto = elf_i386_rtype_to_howto (r_type);
   2200   1.1     skrll       if (howto == NULL)
   2201   1.1     skrll 	return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
   2202   1.1     skrll 
   2203   1.1     skrll       r_symndx = ELF32_R_SYM (rel->r_info);
   2204  1.13  christos       h = NULL;
   2205   1.1     skrll       sym = NULL;
   2206   1.1     skrll       sec = NULL;
   2207   1.1     skrll       unresolved_reloc = false;
   2208   1.1     skrll       if (r_symndx < symtab_hdr->sh_info)
   2209   1.1     skrll 	{
   2210   1.1     skrll 	  sym = local_syms + r_symndx;
   2211   1.1     skrll 	  sec = local_sections[r_symndx];
   2212   1.6  christos 	  relocation = (sec->output_section->vma
   2213   1.1     skrll 			+ sec->output_offset
   2214   1.1     skrll 			+ sym->st_value);
   2215   1.1     skrll 	  st_size = sym->st_size;
   2216   1.6  christos 
   2217   1.1     skrll 	  if (ELF_ST_TYPE (sym->st_info) == STT_SECTION
   2218   1.1     skrll 	      && ((sec->flags & SEC_MERGE) != 0
   2219   1.1     skrll 		  || (bfd_link_relocatable (info)
   2220   1.1     skrll 		      && sec->output_offset != 0)))
   2221   1.1     skrll 	    {
   2222  1.13  christos 	      bfd_vma addend;
   2223   1.1     skrll 	      bfd_byte *where = contents + rel->r_offset;
   2224  1.13  christos 
   2225   1.1     skrll 	      switch (bfd_get_reloc_size (howto))
   2226   1.1     skrll 		{
   2227   1.1     skrll 		case 1:
   2228   1.1     skrll 		  addend = bfd_get_8 (input_bfd, where);
   2229   1.1     skrll 		  if (howto->pc_relative)
   2230   1.1     skrll 		    {
   2231   1.1     skrll 		      addend = (addend ^ 0x80) - 0x80;
   2232  1.13  christos 		      addend += 1;
   2233   1.1     skrll 		    }
   2234   1.1     skrll 		  break;
   2235   1.1     skrll 		case 2:
   2236   1.1     skrll 		  addend = bfd_get_16 (input_bfd, where);
   2237   1.1     skrll 		  if (howto->pc_relative)
   2238   1.1     skrll 		    {
   2239   1.1     skrll 		      addend = (addend ^ 0x8000) - 0x8000;
   2240  1.13  christos 		      addend += 2;
   2241   1.1     skrll 		    }
   2242   1.1     skrll 		  break;
   2243   1.1     skrll 		case 4:
   2244   1.1     skrll 		  addend = bfd_get_32 (input_bfd, where);
   2245   1.1     skrll 		  if (howto->pc_relative)
   2246   1.1     skrll 		    {
   2247   1.1     skrll 		      addend = (addend ^ 0x80000000) - 0x80000000;
   2248   1.1     skrll 		      addend += 4;
   2249   1.1     skrll 		    }
   2250   1.1     skrll 		  break;
   2251   1.1     skrll 		default:
   2252   1.6  christos 		  abort ();
   2253   1.1     skrll 		}
   2254   1.1     skrll 
   2255   1.1     skrll 	      if (bfd_link_relocatable (info))
   2256   1.1     skrll 		addend += sec->output_offset;
   2257   1.1     skrll 	      else
   2258   1.1     skrll 		{
   2259   1.1     skrll 		  asection *msec = sec;
   2260   1.1     skrll 		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec,
   2261   1.1     skrll 						   addend);
   2262   1.1     skrll 		  addend -= relocation;
   2263  1.13  christos 		  addend += msec->output_section->vma + msec->output_offset;
   2264   1.1     skrll 		}
   2265  1.13  christos 
   2266   1.1     skrll 	      switch (bfd_get_reloc_size (howto))
   2267   1.1     skrll 		{
   2268   1.1     skrll 		case 1:
   2269   1.1     skrll 		  /* FIXME: overflow checks.  */
   2270   1.1     skrll 		  if (howto->pc_relative)
   2271  1.13  christos 		    addend -= 1;
   2272   1.1     skrll 		  bfd_put_8 (input_bfd, addend, where);
   2273   1.1     skrll 		  break;
   2274   1.1     skrll 		case 2:
   2275   1.1     skrll 		  if (howto->pc_relative)
   2276  1.13  christos 		    addend -= 2;
   2277   1.1     skrll 		  bfd_put_16 (input_bfd, addend, where);
   2278   1.1     skrll 		  break;
   2279   1.1     skrll 		case 4:
   2280   1.1     skrll 		  if (howto->pc_relative)
   2281   1.1     skrll 		    addend -= 4;
   2282   1.1     skrll 		  bfd_put_32 (input_bfd, addend, where);
   2283   1.6  christos 		  break;
   2284   1.4  christos 		}
   2285   1.4  christos 	    }
   2286   1.4  christos 	  else if (!bfd_link_relocatable (info)
   2287  1.10  christos 		   && ELF32_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
   2288  1.13  christos 	    {
   2289   1.4  christos 	      /* Relocate against local STT_GNU_IFUNC symbol.  */
   2290   1.4  christos 	      h = _bfd_elf_x86_get_local_sym_hash (htab, input_bfd, rel,
   2291   1.4  christos 						   false);
   2292   1.5  christos 	      if (h == NULL)
   2293   1.4  christos 		abort ();
   2294   1.4  christos 
   2295   1.4  christos 	      /* Set STT_GNU_IFUNC symbol value.  */
   2296   1.1     skrll 	      h->root.u.def.value = sym->st_value;
   2297   1.1     skrll 	      h->root.u.def.section = sec;
   2298   1.1     skrll 	    }
   2299  1.13  christos 	}
   2300  1.13  christos       else
   2301   1.1     skrll 	{
   2302   1.1     skrll 	  bool warned ATTRIBUTE_UNUSED;
   2303   1.1     skrll 	  bool ignored ATTRIBUTE_UNUSED;
   2304   1.1     skrll 
   2305   1.6  christos 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
   2306   1.6  christos 				   r_symndx, symtab_hdr, sym_hashes,
   2307   1.1     skrll 				   h, sec, relocation,
   2308   1.1     skrll 				   unresolved_reloc, warned, ignored);
   2309   1.5  christos 	  st_size = h->size;
   2310   1.6  christos 	}
   2311   1.6  christos 
   2312  1.12  christos       if (sec != NULL && discarded_section (sec))
   2313   1.6  christos 	{
   2314   1.6  christos 	  _bfd_clear_contents (howto, input_bfd, input_section,
   2315   1.6  christos 			       contents, rel->r_offset);
   2316   1.6  christos 	  wrel->r_offset = rel->r_offset;
   2317   1.6  christos 	  wrel->r_info = 0;
   2318   1.6  christos 	  wrel->r_addend = 0;
   2319   1.6  christos 
   2320   1.6  christos 	  /* For ld -r, remove relocations in debug sections against
   2321   1.6  christos 	     sections defined in discarded sections.  Not done for
   2322   1.6  christos 	     eh_frame editing code expects to be present.  */
   2323   1.6  christos 	   if (bfd_link_relocatable (info)
   2324   1.6  christos 	       && (input_section->flags & SEC_DEBUGGING))
   2325   1.6  christos 	     wrel--;
   2326   1.1     skrll 
   2327   1.6  christos 	   continue;
   2328   1.6  christos 	}
   2329   1.6  christos 
   2330   1.6  christos       if (bfd_link_relocatable (info))
   2331   1.6  christos 	{
   2332   1.6  christos 	  if (wrel != rel)
   2333   1.1     skrll 	    *wrel = *rel;
   2334  1.10  christos 	  continue;
   2335  1.10  christos 	}
   2336   1.4  christos 
   2337   1.4  christos       eh = (struct elf_x86_link_hash_entry *) h;
   2338   1.4  christos 
   2339   1.4  christos       /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
   2340   1.4  christos 	 it here if it is defined in a non-shared object.  */
   2341   1.4  christos       if (h != NULL
   2342  1.10  christos 	  && h->type == STT_GNU_IFUNC
   2343   1.4  christos 	  && h->def_regular)
   2344   1.4  christos 	{
   2345   1.4  christos 	  asection *gotplt, *base_got;
   2346   1.6  christos 	  bfd_vma plt_index;
   2347   1.6  christos 	  const char *name;
   2348  1.11  christos 
   2349  1.11  christos 	  if ((input_section->flags & SEC_ALLOC) == 0)
   2350  1.11  christos 	    {
   2351  1.11  christos 	      /* If this is a SHT_NOTE section without SHF_ALLOC, treat
   2352   1.6  christos 	         STT_GNU_IFUNC symbol as STT_FUNC.  */
   2353   1.6  christos 	      if (elf_section_type (input_section) == SHT_NOTE)
   2354   1.6  christos 		goto skip_ifunc;
   2355   1.6  christos 	      /* Dynamic relocs are not propagated for SEC_DEBUGGING
   2356   1.6  christos 		 sections because such sections are not SEC_ALLOC and
   2357   1.6  christos 		 thus ld.so will not process them.  */
   2358   1.6  christos 	      if ((input_section->flags & SEC_DEBUGGING) != 0)
   2359   1.4  christos 		continue;
   2360   1.4  christos 	      abort ();
   2361   1.4  christos 	    }
   2362   1.4  christos 
   2363  1.10  christos 	  /* STT_GNU_IFUNC symbol must go through PLT.  */
   2364  1.10  christos 	  if (htab->elf.splt != NULL)
   2365  1.10  christos 	    {
   2366  1.10  christos 	      if (htab->plt_second != NULL)
   2367  1.10  christos 		{
   2368  1.10  christos 		  resolved_plt = htab->plt_second;
   2369  1.10  christos 		  plt_offset = eh->plt_second.offset;
   2370  1.10  christos 		}
   2371  1.10  christos 	      else
   2372  1.10  christos 		{
   2373   1.4  christos 		  resolved_plt = htab->elf.splt;
   2374   1.4  christos 		  plt_offset = h->plt.offset;
   2375   1.4  christos 		}
   2376   1.4  christos 	      gotplt = htab->elf.sgotplt;
   2377  1.10  christos 	    }
   2378  1.10  christos 	  else
   2379   1.4  christos 	    {
   2380   1.4  christos 	      resolved_plt = htab->elf.iplt;
   2381   1.4  christos 	      plt_offset = h->plt.offset;
   2382   1.4  christos 	      gotplt = htab->elf.igotplt;
   2383   1.4  christos 	    }
   2384   1.4  christos 
   2385   1.9  christos 	  switch (r_type)
   2386   1.4  christos 	    {
   2387   1.4  christos 	    default:
   2388   1.6  christos 	      break;
   2389   1.4  christos 
   2390   1.4  christos 	    case R_386_GOT32:
   2391   1.4  christos 	    case R_386_GOT32X:
   2392   1.4  christos 	      base_got = htab->elf.sgot;
   2393   1.4  christos 	      off = h->got.offset;
   2394   1.4  christos 
   2395   1.4  christos 	      if (base_got == NULL)
   2396   1.4  christos 		abort ();
   2397   1.4  christos 
   2398   1.4  christos 	      if (off == (bfd_vma) -1)
   2399   1.4  christos 		{
   2400   1.4  christos 		  /* We can't use h->got.offset here to save state, or
   2401   1.9  christos 		     even just remember the offset, as finish_dynamic_symbol
   2402   1.9  christos 		     would use that as offset into .got.  */
   2403   1.9  christos 
   2404   1.4  christos 		  if (h->plt.offset == (bfd_vma) -1)
   2405   1.4  christos 		    abort ();
   2406  1.10  christos 
   2407  1.10  christos 		  if (htab->elf.splt != NULL)
   2408   1.4  christos 		    {
   2409   1.4  christos 		      plt_index = (h->plt.offset / plt_entry_size
   2410   1.4  christos 				   - htab->plt.has_plt0);
   2411   1.4  christos 		      off = (plt_index + 3) * 4;
   2412   1.4  christos 		      base_got = htab->elf.sgotplt;
   2413   1.5  christos 		    }
   2414   1.4  christos 		  else
   2415   1.4  christos 		    {
   2416   1.4  christos 		      plt_index = h->plt.offset / plt_entry_size;
   2417   1.4  christos 		      off = plt_index * 4;
   2418   1.4  christos 		      base_got = htab->elf.igotplt;
   2419   1.4  christos 		    }
   2420   1.4  christos 
   2421   1.4  christos 		  if (h->dynindx == -1
   2422   1.4  christos 		      || h->forced_local
   2423   1.4  christos 		      || info->symbolic)
   2424  1.13  christos 		    {
   2425   1.4  christos 		      /* This references the local defitionion.  We must
   2426   1.4  christos 			 initialize this entry in the global offset table.
   2427   1.4  christos 			 Since the offset must always be a multiple of 4,
   2428   1.4  christos 			 we use the least significant bit to record
   2429   1.4  christos 			 whether we have initialized it already.
   2430   1.4  christos 
   2431   1.4  christos 			 When doing a dynamic link, we create a .rela.got
   2432   1.4  christos 			 relocation entry to initialize the value.  This
   2433   1.4  christos 			 is done in the finish_dynamic_symbol routine.	 */
   2434   1.4  christos 		      if ((off & 1) != 0)
   2435   1.4  christos 			off &= ~1;
   2436   1.4  christos 		      else
   2437   1.4  christos 			{
   2438   1.4  christos 			  bfd_put_32 (output_bfd, relocation,
   2439   1.4  christos 				      base_got->contents + off);
   2440   1.4  christos 			  h->got.offset |= 1;
   2441   1.4  christos 			}
   2442   1.8  christos 		    }
   2443   1.8  christos 
   2444   1.8  christos 		  relocation = off;
   2445   1.8  christos 		}
   2446   1.8  christos 	      else
   2447   1.8  christos 		relocation = (base_got->output_section->vma
   2448   1.8  christos 			      + base_got->output_offset + off
   2449  1.10  christos 			      - gotplt->output_section->vma
   2450  1.10  christos 			      - gotplt->output_offset);
   2451  1.10  christos 
   2452   1.8  christos 	      if (rel->r_offset > 1
   2453   1.8  christos 		  && (*(contents + rel->r_offset - 1) & 0xc7) == 0x5
   2454   1.8  christos 		  && *(contents + rel->r_offset - 2) != 0x8d)
   2455   1.4  christos 		{
   2456   1.8  christos 		  if (bfd_link_pic (info))
   2457   1.8  christos 		    goto disallow_got32;
   2458   1.8  christos 
   2459   1.4  christos 		  /* Add the GOT base if there is no base register.  */
   2460   1.8  christos 		  relocation += (gotplt->output_section->vma
   2461   1.4  christos 				 + gotplt->output_offset);
   2462   1.4  christos 		}
   2463   1.8  christos 	      else if (htab->elf.splt == NULL)
   2464   1.4  christos 		{
   2465   1.4  christos 		  /* Adjust for static executables.  */
   2466   1.4  christos 		  relocation += gotplt->output_offset;
   2467   1.9  christos 		}
   2468   1.9  christos 
   2469   1.9  christos 	      goto do_relocation;
   2470   1.9  christos 	    }
   2471   1.9  christos 
   2472   1.9  christos 	  if (h->plt.offset == (bfd_vma) -1)
   2473   1.9  christos 	    {
   2474   1.9  christos 	      /* Handle static pointers of STT_GNU_IFUNC symbols.  */
   2475   1.9  christos 	      if (r_type == R_386_32
   2476   1.9  christos 		  && (input_section->flags & SEC_CODE) == 0)
   2477   1.9  christos 		goto do_ifunc_pointer;
   2478  1.10  christos 	      goto bad_ifunc_reloc;
   2479  1.10  christos 	    }
   2480   1.9  christos 
   2481   1.9  christos 	  relocation = (resolved_plt->output_section->vma
   2482   1.9  christos 			+ resolved_plt->output_offset + plt_offset);
   2483   1.9  christos 
   2484  1.13  christos 	  switch (r_type)
   2485   1.9  christos 	    {
   2486   1.9  christos 	    default:
   2487   1.9  christos 	    bad_ifunc_reloc:
   2488   1.9  christos 	      if (h->root.root.string)
   2489   1.9  christos 		name = h->root.root.string;
   2490  1.10  christos 	      else
   2491  1.10  christos 		name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
   2492  1.11  christos 					 NULL);
   2493   1.9  christos 	      _bfd_error_handler
   2494   1.9  christos 		/* xgettext:c-format */
   2495   1.9  christos 		(_("%pB: relocation %s against STT_GNU_IFUNC "
   2496  1.13  christos 		   "symbol `%s' isn't supported"), input_bfd,
   2497   1.9  christos 		 howto->name, name);
   2498   1.9  christos 	      bfd_set_error (bfd_error_bad_value);
   2499   1.9  christos 	      return false;
   2500   1.9  christos 
   2501   1.9  christos 	    case R_386_32:
   2502   1.9  christos 	      /* Generate dynamic relcoation only when there is a
   2503   1.9  christos 		 non-GOT reference in a shared object.  */
   2504   1.9  christos 	      if ((bfd_link_pic (info) && h->non_got_ref)
   2505   1.9  christos 		  || h->plt.offset == (bfd_vma) -1)
   2506   1.9  christos 		{
   2507   1.9  christos 		  Elf_Internal_Rela outrel;
   2508  1.13  christos 		  asection *sreloc;
   2509   1.9  christos 		  bfd_vma offset;
   2510   1.9  christos 
   2511   1.9  christos 		do_ifunc_pointer:
   2512   1.9  christos 		  /* Need a dynamic relocation to get the real function
   2513   1.9  christos 		     adddress.  */
   2514   1.9  christos 		  offset = _bfd_elf_section_offset (output_bfd,
   2515   1.9  christos 						    info,
   2516   1.9  christos 						    input_section,
   2517   1.9  christos 						    rel->r_offset);
   2518   1.9  christos 		  if (offset == (bfd_vma) -1
   2519   1.9  christos 		      || offset == (bfd_vma) -2)
   2520   1.9  christos 		    abort ();
   2521   1.9  christos 
   2522   1.9  christos 		  outrel.r_offset = (input_section->output_section->vma
   2523  1.10  christos 				     + input_section->output_offset
   2524   1.9  christos 				     + offset);
   2525  1.11  christos 
   2526  1.10  christos 		  if (POINTER_LOCAL_IFUNC_P (info, h))
   2527  1.10  christos 		    {
   2528  1.10  christos 		      info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"),
   2529   1.9  christos 					      h->root.root.string,
   2530   1.9  christos 					      h->root.u.def.section->owner);
   2531  1.13  christos 
   2532  1.13  christos 		      /* This symbol is resolved locally.  */
   2533  1.13  christos 		      outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
   2534  1.13  christos 
   2535  1.13  christos 		      if (htab->params->report_relative_reloc)
   2536  1.13  christos 			_bfd_x86_elf_link_report_relative_reloc
   2537   1.9  christos 			  (info, input_section, h, sym,
   2538   1.9  christos 			   "R_386_IRELATIVE", &outrel);
   2539   1.9  christos 
   2540   1.9  christos 		      bfd_put_32 (output_bfd,
   2541   1.9  christos 				  (h->root.u.def.value
   2542   1.9  christos 				   + h->root.u.def.section->output_section->vma
   2543   1.9  christos 				   + h->root.u.def.section->output_offset),
   2544   1.9  christos 				  contents + offset);
   2545   1.9  christos 		    }
   2546   1.9  christos 		  else
   2547   1.9  christos 		    outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
   2548   1.9  christos 
   2549   1.9  christos 		  /* Dynamic relocations are stored in
   2550   1.9  christos 		     1. .rel.ifunc section in PIC object.
   2551   1.9  christos 		     2. .rel.got section in dynamic executable.
   2552   1.9  christos 		     3. .rel.iplt section in static executable.  */
   2553   1.9  christos 		  if (bfd_link_pic (info))
   2554   1.9  christos 		    sreloc = htab->elf.irelifunc;
   2555   1.9  christos 		  else if (htab->elf.splt != NULL)
   2556  1.17  christos 		    sreloc = htab->elf.srelgot;
   2557   1.9  christos 		  else
   2558   1.9  christos 		    sreloc = htab->elf.irelplt;
   2559   1.9  christos 		  _bfd_elf_append_rel (output_bfd, sreloc, &outrel);
   2560   1.9  christos 
   2561   1.9  christos 		  /* If this reloc is against an external symbol, we
   2562   1.9  christos 		     do not want to fiddle with the addend.  Otherwise,
   2563   1.9  christos 		     we need to include the symbol value so that it
   2564   1.9  christos 		     becomes an addend for the dynamic reloc.  For an
   2565   1.9  christos 		     internal symbol, we have updated addend.  */
   2566   1.9  christos 		  continue;
   2567   1.9  christos 		}
   2568   1.9  christos 	      /* FALLTHROUGH */
   2569   1.4  christos 	    case R_386_PC32:
   2570   1.4  christos 	    case R_386_PLT32:
   2571  1.13  christos 	      goto do_relocation;
   2572  1.13  christos 
   2573  1.13  christos 	    case R_386_GOTOFF:
   2574  1.13  christos 	      /* NB: We can't use the PLT entry as the function address
   2575  1.13  christos 		 for PIC since the PIC register may not be set up
   2576   1.4  christos 		 properly for indirect call. */
   2577   1.4  christos 	      if (bfd_link_pic (info))
   2578   1.4  christos 		goto bad_ifunc_reloc;
   2579   1.4  christos 	      relocation -= (gotplt->output_section->vma
   2580   1.4  christos 			     + gotplt->output_offset);
   2581   1.4  christos 	      goto do_relocation;
   2582  1.13  christos 	    }
   2583   1.9  christos 	}
   2584  1.10  christos 
   2585   1.9  christos     skip_ifunc:
   2586   1.1     skrll       resolved_to_zero = (eh != NULL
   2587   1.1     skrll 			  && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh));
   2588   1.6  christos 
   2589   1.1     skrll       switch (r_type)
   2590   1.1     skrll 	{
   2591   1.1     skrll 	case R_386_GOT32X:
   2592   1.4  christos 	case R_386_GOT32:
   2593   1.1     skrll 	  /* Relocation is to the entry for this symbol in the global
   2594   1.1     skrll 	     offset table.  */
   2595  1.13  christos 	  if (htab->elf.sgot == NULL)
   2596   1.1     skrll 	    abort ();
   2597   1.1     skrll 
   2598   1.1     skrll 	  relative_reloc = false;
   2599  1.10  christos 	  if (h != NULL)
   2600  1.10  christos 	    {
   2601  1.10  christos 	      off = h->got.offset;
   2602  1.10  christos 	      if (RESOLVED_LOCALLY_P (info, h, htab))
   2603  1.10  christos 		{
   2604  1.10  christos 		  /* We must initialize this entry in the global offset
   2605   1.1     skrll 		     table.  Since the offset must always be a multiple
   2606   1.1     skrll 		     of 4, we use the least significant bit to record
   2607   1.1     skrll 		     whether we have initialized it already.
   2608   1.1     skrll 
   2609   1.1     skrll 		     When doing a dynamic link, we create a .rel.got
   2610   1.1     skrll 		     relocation entry to initialize the value.  This
   2611   1.1     skrll 		     is done in the finish_dynamic_symbol routine.  */
   2612   1.1     skrll 		  if ((off & 1) != 0)
   2613   1.1     skrll 		    off &= ~1;
   2614   1.4  christos 		  else
   2615   1.1     skrll 		    {
   2616  1.13  christos 		      bfd_put_32 (output_bfd, relocation,
   2617  1.13  christos 				  htab->elf.sgot->contents + off);
   2618  1.13  christos 		      h->got.offset |= 1;
   2619  1.13  christos 		      /* NB: Don't generate relative relocation here if
   2620  1.10  christos 			 it has been generated by DT_RELR.  */
   2621  1.10  christos 		      if (!info->enable_dt_relr
   2622  1.10  christos 			  && GENERATE_RELATIVE_RELOC_P (info, h))
   2623  1.10  christos 			{
   2624  1.13  christos 			  /* PR ld/21402: If this symbol isn't dynamic
   2625  1.10  christos 			     in PIC, generate R_386_RELATIVE here.  */
   2626   1.1     skrll 			  eh->no_finish_dynamic_symbol = 1;
   2627   1.1     skrll 			  relative_reloc = true;
   2628   1.1     skrll 			}
   2629  1.13  christos 		    }
   2630   1.1     skrll 		}
   2631   1.1     skrll 	      else
   2632   1.1     skrll 		unresolved_reloc = false;
   2633   1.1     skrll 	    }
   2634   1.1     skrll 	  else
   2635   1.1     skrll 	    {
   2636   1.1     skrll 	      if (local_got_offsets == NULL)
   2637   1.1     skrll 		abort ();
   2638   1.1     skrll 
   2639   1.1     skrll 	      off = local_got_offsets[r_symndx];
   2640   1.1     skrll 
   2641   1.1     skrll 	      /* The offset must always be a multiple of 4.  We use
   2642   1.1     skrll 		 the least significant bit to record whether we have
   2643   1.1     skrll 		 already generated the necessary reloc.  */
   2644   1.1     skrll 	      if ((off & 1) != 0)
   2645   1.1     skrll 		off &= ~1;
   2646   1.4  christos 	      else
   2647  1.10  christos 		{
   2648   1.1     skrll 		  bfd_put_32 (output_bfd, relocation,
   2649  1.13  christos 			      htab->elf.sgot->contents + off);
   2650  1.13  christos 		  local_got_offsets[r_symndx] |= 1;
   2651  1.13  christos 
   2652  1.13  christos 		  /* NB: Don't generate relative relocation here if it
   2653  1.10  christos 		     has been generated by DT_RELR.  */
   2654  1.10  christos 		  if (!info->enable_dt_relr && bfd_link_pic (info))
   2655  1.10  christos 		    relative_reloc = true;
   2656  1.10  christos 		}
   2657  1.10  christos 	    }
   2658  1.10  christos 
   2659  1.10  christos 	  if (relative_reloc)
   2660   1.1     skrll 	    {
   2661  1.10  christos 	      asection *s;
   2662  1.10  christos 	      Elf_Internal_Rela outrel;
   2663  1.10  christos 
   2664   1.1     skrll 	      s = htab->elf.srelgot;
   2665  1.10  christos 	      if (s == NULL)
   2666  1.10  christos 		abort ();
   2667  1.10  christos 
   2668  1.10  christos 	      outrel.r_offset = (htab->elf.sgot->output_section->vma
   2669  1.13  christos 				 + htab->elf.sgot->output_offset
   2670  1.13  christos 				 + off);
   2671  1.13  christos 	      outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
   2672  1.13  christos 
   2673  1.13  christos 	      if (htab->params->report_relative_reloc)
   2674  1.13  christos 		_bfd_x86_elf_link_report_relative_reloc
   2675  1.17  christos 		  (info, input_section, h, sym, "R_386_RELATIVE",
   2676   1.1     skrll 		   &outrel);
   2677   1.1     skrll 
   2678   1.1     skrll 	      _bfd_elf_append_rel (output_bfd, s, &outrel);
   2679   1.1     skrll 	    }
   2680   1.1     skrll 
   2681   1.8  christos 	  if (off >= (bfd_vma) -2)
   2682   1.8  christos 	    abort ();
   2683  1.10  christos 
   2684  1.10  christos 	  relocation = (htab->elf.sgot->output_section->vma
   2685  1.10  christos 			+ htab->elf.sgot->output_offset + off);
   2686   1.8  christos 	  if (rel->r_offset > 1
   2687   1.8  christos 	      && (*(contents + rel->r_offset - 1) & 0xc7) == 0x5
   2688   1.8  christos 	      && *(contents + rel->r_offset - 2) != 0x8d)
   2689   1.8  christos 	    {
   2690  1.10  christos 	      if (bfd_link_pic (info))
   2691  1.10  christos 		{
   2692   1.8  christos 		  /* For PIC, disallow R_386_GOT32 without a base
   2693   1.8  christos 		     register, except for "lea foo@GOT, %reg", since
   2694  1.13  christos 		     we don't know what the GOT base is.  */
   2695  1.10  christos 		  const char *name;
   2696   1.8  christos 
   2697   1.8  christos 		disallow_got32:
   2698   1.8  christos 		  if (h == NULL || h->root.root.string == NULL)
   2699   1.8  christos 		    name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
   2700   1.8  christos 					     NULL);
   2701  1.10  christos 		  else
   2702  1.10  christos 		    name = h->root.root.string;
   2703  1.11  christos 
   2704  1.10  christos 		  _bfd_error_handler
   2705  1.10  christos 		    /* xgettext:c-format */
   2706   1.8  christos 		    (_("%pB: direct GOT relocation %s against `%s'"
   2707   1.8  christos 		       " without base register can not be used"
   2708  1.13  christos 		       " when making a shared object"),
   2709   1.8  christos 		     input_bfd, howto->name, name);
   2710   1.8  christos 		  bfd_set_error (bfd_error_bad_value);
   2711   1.8  christos 		  return false;
   2712   1.8  christos 		}
   2713   1.8  christos 	    }
   2714   1.8  christos 	  else
   2715   1.8  christos 	    {
   2716   1.8  christos 	      /* Subtract the .got.plt section address only with a base
   2717   1.8  christos 		 register.  */
   2718   1.8  christos 	      relocation -= (htab->elf.sgotplt->output_section->vma
   2719   1.1     skrll 			     + htab->elf.sgotplt->output_offset);
   2720   1.1     skrll 	    }
   2721   1.1     skrll 
   2722   1.1     skrll 	  break;
   2723   1.1     skrll 
   2724   1.1     skrll 	case R_386_GOTOFF:
   2725   1.6  christos 	  /* Relocation is relative to the start of the global offset
   2726   1.6  christos 	     table.  */
   2727   1.6  christos 
   2728   1.6  christos 	  /* Check to make sure it isn't a protected function or data
   2729   1.6  christos 	     symbol for shared library since it may not be local when
   2730   1.1     skrll 	     used as function address or with copy relocation.  We also
   2731   1.1     skrll 	     need to make sure that a symbol is referenced locally.  */
   2732   1.1     skrll 	  if (!bfd_link_executable (info) && h)
   2733   1.1     skrll 	    {
   2734   1.1     skrll 	      if (!h->def_regular)
   2735   1.1     skrll 		{
   2736   1.1     skrll 		  const char *v;
   2737   1.1     skrll 
   2738   1.1     skrll 		  switch (ELF_ST_VISIBILITY (h->other))
   2739   1.1     skrll 		    {
   2740   1.1     skrll 		    case STV_HIDDEN:
   2741   1.1     skrll 		      v = _("hidden symbol");
   2742   1.1     skrll 		      break;
   2743   1.1     skrll 		    case STV_INTERNAL:
   2744   1.1     skrll 		      v = _("internal symbol");
   2745   1.1     skrll 		      break;
   2746   1.1     skrll 		    case STV_PROTECTED:
   2747   1.1     skrll 		      v = _("protected symbol");
   2748   1.1     skrll 		      break;
   2749   1.1     skrll 		    default:
   2750   1.1     skrll 		      v = _("symbol");
   2751  1.10  christos 		      break;
   2752  1.10  christos 		    }
   2753  1.11  christos 
   2754  1.10  christos 		  _bfd_error_handler
   2755   1.1     skrll 		    /* xgettext:c-format */
   2756   1.1     skrll 		    (_("%pB: relocation R_386_GOTOFF against undefined %s"
   2757  1.13  christos 		       " `%s' can not be used when making a shared object"),
   2758   1.1     skrll 		     input_bfd, v, h->root.root.string);
   2759  1.10  christos 		  bfd_set_error (bfd_error_bad_value);
   2760   1.6  christos 		  return false;
   2761   1.6  christos 		}
   2762   1.1     skrll 	      else if (!SYMBOL_REFERENCES_LOCAL_P (info, h)
   2763   1.1     skrll 		       && (h->type == STT_FUNC
   2764  1.10  christos 			   || h->type == STT_OBJECT)
   2765  1.10  christos 		       && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
   2766  1.11  christos 		{
   2767  1.10  christos 		  _bfd_error_handler
   2768   1.6  christos 		    /* xgettext:c-format */
   2769   1.6  christos 		    (_("%pB: relocation R_386_GOTOFF against protected %s"
   2770   1.6  christos 		       " `%s' can not be used when making a shared object"),
   2771   1.1     skrll 		     input_bfd,
   2772  1.13  christos 		     h->type == STT_FUNC ? "function" : "data",
   2773   1.1     skrll 		     h->root.root.string);
   2774   1.1     skrll 		  bfd_set_error (bfd_error_bad_value);
   2775   1.1     skrll 		  return false;
   2776   1.1     skrll 		}
   2777   1.1     skrll 	    }
   2778   1.1     skrll 
   2779   1.1     skrll 	  /* Note that sgot is not involved in this
   2780   1.1     skrll 	     calculation.  We always want the start of .got.plt.  If we
   2781   1.4  christos 	     defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
   2782   1.4  christos 	     permitted by the ABI, we might have to change this
   2783   1.1     skrll 	     calculation.  */
   2784   1.1     skrll 	  relocation -= htab->elf.sgotplt->output_section->vma
   2785   1.1     skrll 			+ htab->elf.sgotplt->output_offset;
   2786   1.1     skrll 	  break;
   2787   1.4  christos 
   2788   1.4  christos 	case R_386_GOTPC:
   2789  1.13  christos 	  /* Use global offset table as symbol value.  */
   2790   1.1     skrll 	  relocation = htab->elf.sgotplt->output_section->vma
   2791   1.1     skrll 		       + htab->elf.sgotplt->output_offset;
   2792   1.1     skrll 	  unresolved_reloc = false;
   2793   1.1     skrll 	  break;
   2794   1.1     skrll 
   2795   1.1     skrll 	case R_386_PLT32:
   2796   1.1     skrll 	  /* Relocation is to the entry for this symbol in the
   2797   1.1     skrll 	     procedure linkage table.  */
   2798   1.1     skrll 
   2799   1.1     skrll 	  /* Resolve a PLT32 reloc against a local symbol directly,
   2800   1.1     skrll 	     without using the procedure linkage table.  */
   2801   1.6  christos 	  if (h == NULL)
   2802   1.6  christos 	    break;
   2803   1.4  christos 
   2804   1.1     skrll 	  if ((h->plt.offset == (bfd_vma) -1
   2805   1.1     skrll 	       && eh->plt_got.offset == (bfd_vma) -1)
   2806   1.1     skrll 	      || htab->elf.splt == NULL)
   2807   1.1     skrll 	    {
   2808   1.1     skrll 	      /* We didn't make a PLT entry for this symbol.  This
   2809   1.1     skrll 		 happens when statically linking PIC code, or when
   2810   1.1     skrll 		 using -Bsymbolic.  */
   2811   1.6  christos 	      break;
   2812   1.6  christos 	    }
   2813  1.10  christos 
   2814  1.10  christos 	  if (h->plt.offset != (bfd_vma) -1)
   2815  1.10  christos 	    {
   2816  1.10  christos 	      if (htab->plt_second != NULL)
   2817  1.10  christos 		{
   2818  1.10  christos 		  resolved_plt = htab->plt_second;
   2819  1.10  christos 		  plt_offset = eh->plt_second.offset;
   2820  1.10  christos 		}
   2821  1.10  christos 	      else
   2822  1.10  christos 		{
   2823   1.6  christos 		  resolved_plt = htab->elf.splt;
   2824   1.6  christos 		  plt_offset = h->plt.offset;
   2825   1.6  christos 		}
   2826   1.6  christos 	    }
   2827   1.6  christos 	  else
   2828   1.6  christos 	    {
   2829   1.6  christos 	      resolved_plt = htab->plt_got;
   2830   1.6  christos 	      plt_offset = eh->plt_got.offset;
   2831   1.6  christos 	    }
   2832   1.6  christos 
   2833  1.13  christos 	  relocation = (resolved_plt->output_section->vma
   2834   1.1     skrll 			+ resolved_plt->output_offset
   2835   1.1     skrll 			+ plt_offset);
   2836   1.6  christos 	  unresolved_reloc = false;
   2837   1.6  christos 	  break;
   2838   1.6  christos 
   2839   1.6  christos 	case R_386_SIZE32:
   2840   1.6  christos 	  /* Set to symbol size.  */
   2841   1.1     skrll 	  relocation = st_size;
   2842   1.1     skrll 	  /* Fall through.  */
   2843   1.1     skrll 
   2844   1.1     skrll 	case R_386_32:
   2845   1.1     skrll 	case R_386_PC32:
   2846   1.1     skrll 	  if ((input_section->flags & SEC_ALLOC) == 0
   2847  1.13  christos 	      || is_vxworks_tls)
   2848  1.13  christos 	    break;
   2849  1.13  christos 
   2850  1.10  christos 	  if (GENERATE_DYNAMIC_RELOCATION_P (false, info, eh, r_type,
   2851   1.1     skrll 					     sec, false,
   2852   1.1     skrll 					     resolved_to_zero,
   2853  1.13  christos 					     (r_type == R_386_PC32)))
   2854  1.13  christos 	    {
   2855   1.1     skrll 	      Elf_Internal_Rela outrel;
   2856   1.1     skrll 	      bool skip, relocate;
   2857   1.1     skrll 	      bool generate_dynamic_reloc = true;
   2858   1.1     skrll 	      asection *sreloc;
   2859   1.1     skrll 
   2860   1.1     skrll 	      /* When generating a shared object, these relocations
   2861  1.13  christos 		 are copied into the output file to be resolved at run
   2862  1.13  christos 		 time.  */
   2863   1.1     skrll 
   2864   1.1     skrll 	      skip = false;
   2865   1.1     skrll 	      relocate = false;
   2866   1.1     skrll 
   2867   1.1     skrll 	      outrel.r_offset =
   2868  1.13  christos 		_bfd_elf_section_offset (output_bfd, info, input_section,
   2869   1.1     skrll 					 rel->r_offset);
   2870  1.13  christos 	      if (outrel.r_offset == (bfd_vma) -1)
   2871   1.1     skrll 		skip = true;
   2872   1.1     skrll 	      else if (outrel.r_offset == (bfd_vma) -2)
   2873   1.1     skrll 		skip = true, relocate = true;
   2874   1.1     skrll 	      outrel.r_offset += (input_section->output_section->vma
   2875   1.1     skrll 				  + input_section->output_offset);
   2876  1.13  christos 
   2877   1.1     skrll 	      if (skip)
   2878   1.1     skrll 		memset (&outrel, 0, sizeof outrel);
   2879   1.1     skrll 	      else if (COPY_INPUT_RELOC_P (false, info, h, r_type))
   2880   1.1     skrll 		outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
   2881  1.13  christos 	      else
   2882  1.13  christos 		{
   2883  1.13  christos 		  /* This symbol is local, or marked to become local.  */
   2884  1.13  christos 		  relocate = true;
   2885  1.13  christos 		  /* NB: Don't generate relative relocation here if it
   2886  1.13  christos 		     has been generated by DT_RELR.  */
   2887  1.13  christos 		  if (info->enable_dt_relr)
   2888  1.13  christos 		    generate_dynamic_reloc = false;
   2889  1.13  christos 		  else
   2890  1.13  christos 		    {
   2891  1.13  christos 		      outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
   2892  1.13  christos 
   2893  1.13  christos 		      if (htab->params->report_relative_reloc)
   2894  1.13  christos 			_bfd_x86_elf_link_report_relative_reloc
   2895   1.1     skrll 			  (info, input_section, h, sym, "R_386_RELATIVE",
   2896   1.1     skrll 			   &outrel);
   2897  1.13  christos 		    }
   2898  1.13  christos 		}
   2899  1.13  christos 
   2900  1.13  christos 	      if (generate_dynamic_reloc)
   2901  1.13  christos 		{
   2902  1.13  christos 		  sreloc = elf_section_data (input_section)->sreloc;
   2903  1.13  christos 
   2904  1.13  christos 		  if (sreloc == NULL || sreloc->contents == NULL)
   2905  1.13  christos 		    {
   2906   1.4  christos 		      r = bfd_reloc_notsupported;
   2907  1.17  christos 		      goto check_relocation_error;
   2908   1.5  christos 		    }
   2909   1.4  christos 
   2910   1.1     skrll 		  _bfd_elf_append_rel (output_bfd, sreloc, &outrel);
   2911   1.1     skrll 		}
   2912   1.1     skrll 
   2913   1.1     skrll 	      /* If this reloc is against an external symbol, we do
   2914   1.1     skrll 		 not want to fiddle with the addend.  Otherwise, we
   2915   1.1     skrll 		 need to include the symbol value so that it becomes
   2916   1.1     skrll 		 an addend for the dynamic reloc.  */
   2917   1.1     skrll 	      if (! relocate)
   2918   1.1     skrll 		continue;
   2919   1.1     skrll 	    }
   2920   1.6  christos 	  break;
   2921   1.1     skrll 
   2922   1.1     skrll 	case R_386_TLS_IE:
   2923   1.1     skrll 	  if (!bfd_link_executable (info))
   2924   1.1     skrll 	    {
   2925   1.1     skrll 	      Elf_Internal_Rela outrel;
   2926   1.1     skrll 	      asection *sreloc;
   2927   1.1     skrll 
   2928   1.1     skrll 	      outrel.r_offset = rel->r_offset
   2929  1.13  christos 				+ input_section->output_section->vma
   2930  1.13  christos 				+ input_section->output_offset;
   2931  1.13  christos 	      outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
   2932  1.13  christos 
   2933  1.13  christos 	      if (htab->params->report_relative_reloc)
   2934  1.13  christos 		_bfd_x86_elf_link_report_relative_reloc
   2935   1.1     skrll 		  (info, input_section, h, sym, "R_386_RELATIVE",
   2936   1.1     skrll 		   &outrel);
   2937   1.1     skrll 
   2938  1.17  christos 	      sreloc = elf_section_data (input_section)->sreloc;
   2939   1.1     skrll 	      if (sreloc == NULL)
   2940   1.1     skrll 		abort ();
   2941   1.1     skrll 	      _bfd_elf_append_rel (output_bfd, sreloc, &outrel);
   2942   1.1     skrll 	    }
   2943   1.1     skrll 	  /* Fall through */
   2944   1.1     skrll 
   2945   1.1     skrll 	case R_386_TLS_GD:
   2946   1.1     skrll 	case R_386_TLS_GOTDESC:
   2947   1.1     skrll 	case R_386_TLS_DESC_CALL:
   2948   1.1     skrll 	case R_386_TLS_IE_32:
   2949  1.10  christos 	case R_386_TLS_GOTIE:
   2950   1.1     skrll 	  tls_type = GOT_UNKNOWN;
   2951  1.10  christos 	  if (h == NULL && local_got_offsets)
   2952   1.1     skrll 	    tls_type = elf_x86_local_got_tls_type (input_bfd) [r_symndx];
   2953   1.1     skrll 	  else if (h != NULL)
   2954   1.1     skrll 	    tls_type = elf_x86_hash_entry(h)->tls_type;
   2955  1.10  christos 	  if (tls_type == GOT_TLS_IE)
   2956   1.1     skrll 	    tls_type = GOT_TLS_IE_NEG;
   2957   1.1     skrll 
   2958   1.1     skrll 	   r_type_tls = r_type;
   2959  1.10  christos 	  if (! elf_i386_tls_transition (info, input_bfd,
   2960  1.16  christos 					 input_section, contents,
   2961  1.13  christos 					 symtab_hdr, sym_hashes,
   2962   1.1     skrll 					 &r_type_tls, tls_type, rel,
   2963  1.15  christos 					 relend, h, sym, true))
   2964  1.15  christos 	    return false;
   2965  1.15  christos 
   2966  1.15  christos 	  expected_tls_le = htab->elf.target_os == is_solaris
   2967  1.15  christos 	    ? R_386_TLS_LE : R_386_TLS_LE_32;
   2968  1.15  christos 	  if (r_type_tls == expected_tls_le)
   2969  1.15  christos 	    {
   2970  1.15  christos 	      /* NB: Solaris only supports R_386_TLS_GD->R_386_TLS_LE.  */
   2971  1.15  christos 	      BFD_ASSERT (! unresolved_reloc
   2972  1.15  christos 			  && (htab->elf.target_os != is_solaris
   2973  1.15  christos 			      || (htab->elf.target_os == is_solaris
   2974  1.10  christos 				  && (r_type == R_386_TLS_GD
   2975   1.1     skrll 				      || r_type == R_386_TLS_IE
   2976   1.1     skrll 				      || r_type == R_386_TLS_GOTIE))));
   2977   1.1     skrll 	      if (r_type == R_386_TLS_GD)
   2978   1.1     skrll 		{
   2979   1.1     skrll 		  unsigned int type;
   2980   1.9  christos 		  bfd_vma roff;
   2981   1.1     skrll 
   2982   1.1     skrll 		  /* GD->LE transition.  */
   2983   1.9  christos 		  type = *(contents + rel->r_offset - 2);
   2984   1.9  christos 		  if (type == 0x04)
   2985   1.9  christos 		    {
   2986   1.9  christos 		      /* Change
   2987   1.9  christos 				leal foo@tlsgd(,%ebx,1), %eax
   2988   1.9  christos 				call ___tls_get_addr@PLT
   2989   1.1     skrll 			 into:
   2990   1.1     skrll 				movl %gs:0, %eax
   2991   1.1     skrll 				subl $foo@tpoff, %eax
   2992   1.1     skrll 			 (6 byte form of subl).  */
   2993   1.1     skrll 		      roff = rel->r_offset + 5;
   2994   1.9  christos 		    }
   2995   1.9  christos 		  else
   2996   1.9  christos 		    {
   2997   1.9  christos 		      /* Change
   2998   1.9  christos 				leal foo@tlsgd(%ebx), %eax
   2999   1.9  christos 				call ___tls_get_addr@PLT
   3000   1.9  christos 				nop
   3001   1.9  christos 			 or
   3002   1.9  christos 				leal foo@tlsgd(%reg), %eax
   3003   1.9  christos 				call *___tls_get_addr@GOT(%reg)
   3004   1.9  christos 				which may be converted to
   3005   1.1     skrll 				addr32 call ___tls_get_addr
   3006   1.1     skrll 			 into:
   3007   1.1     skrll 				movl %gs:0, %eax; subl $foo@tpoff, %eax
   3008   1.9  christos 			 (6 byte form of subl).  */
   3009   1.9  christos 		      roff = rel->r_offset + 6;
   3010   1.4  christos 		    }
   3011   1.1     skrll 		  memcpy (contents + roff - 8,
   3012   1.9  christos 			  "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
   3013   1.1     skrll 		  bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation),
   3014   1.6  christos 			      contents + roff);
   3015   1.1     skrll 		  /* Skip R_386_PC32, R_386_PLT32 and R_386_GOT32X.  */
   3016   1.1     skrll 		  rel++;
   3017  1.10  christos 		  wrel++;
   3018   1.1     skrll 		  continue;
   3019   1.1     skrll 		}
   3020   1.1     skrll 	      else if (r_type == R_386_TLS_GOTDESC)
   3021   1.1     skrll 		{
   3022   1.1     skrll 		  /* GDesc -> LE transition.
   3023   1.1     skrll 		     It's originally something like:
   3024   1.1     skrll 		     leal x@tlsdesc(%ebx), %eax
   3025   1.1     skrll 
   3026   1.1     skrll 		     leal x@ntpoff, %eax
   3027   1.1     skrll 
   3028   1.1     skrll 		     Registers other than %eax may be set up here.  */
   3029   1.1     skrll 
   3030   1.1     skrll 		  unsigned int val;
   3031   1.1     skrll 		  bfd_vma roff;
   3032   1.1     skrll 
   3033   1.1     skrll 		  roff = rel->r_offset;
   3034   1.1     skrll 		  val = bfd_get_8 (input_bfd, contents + roff - 1);
   3035   1.1     skrll 
   3036   1.1     skrll 		  /* Now modify the instruction as appropriate.  */
   3037   1.1     skrll 		  /* aoliva FIXME: remove the above and xor the byte
   3038   1.4  christos 		     below with 0x86.  */
   3039   1.1     skrll 		  bfd_put_8 (output_bfd, val ^ 0x86,
   3040   1.1     skrll 			     contents + roff - 1);
   3041   1.1     skrll 		  bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
   3042  1.10  christos 			      contents + roff);
   3043   1.1     skrll 		  continue;
   3044   1.1     skrll 		}
   3045   1.1     skrll 	      else if (r_type == R_386_TLS_DESC_CALL)
   3046   1.1     skrll 		{
   3047   1.1     skrll 		  /* GDesc -> LE transition.
   3048   1.1     skrll 		     It's originally:
   3049   1.1     skrll 		     call *(%eax)
   3050   1.1     skrll 		     Turn it into:
   3051   1.4  christos 		     xchg %ax,%ax  */
   3052   1.1     skrll 
   3053   1.1     skrll 		  bfd_vma roff;
   3054   1.1     skrll 
   3055   1.1     skrll 		  roff = rel->r_offset;
   3056   1.1     skrll 		  bfd_put_8 (output_bfd, 0x66, contents + roff);
   3057  1.10  christos 		  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
   3058   1.1     skrll 		  continue;
   3059   1.1     skrll 		}
   3060   1.1     skrll 	      else if (r_type == R_386_TLS_IE)
   3061   1.1     skrll 		{
   3062   1.1     skrll 		  unsigned int val;
   3063   1.1     skrll 
   3064   1.1     skrll 		  /* IE->LE transition:
   3065   1.1     skrll 		     Originally it can be one of:
   3066   1.1     skrll 		     movl foo, %eax
   3067   1.1     skrll 		     movl foo, %reg
   3068   1.1     skrll 		     addl foo, %reg
   3069   1.1     skrll 		     We change it into:
   3070   1.1     skrll 		     movl $foo, %eax
   3071   1.1     skrll 		     movl $foo, %reg
   3072   1.1     skrll 		     addl $foo, %reg.  */
   3073   1.1     skrll 		  val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
   3074   1.1     skrll 		  if (val == 0xa1)
   3075   1.1     skrll 		    {
   3076   1.1     skrll 		      /* movl foo, %eax.  */
   3077   1.1     skrll 		      bfd_put_8 (output_bfd, 0xb8,
   3078   1.1     skrll 				 contents + rel->r_offset - 1);
   3079   1.1     skrll 		    }
   3080   1.1     skrll 		  else
   3081   1.1     skrll 		    {
   3082   1.1     skrll 		      unsigned int type;
   3083   1.1     skrll 
   3084   1.1     skrll 		      type = bfd_get_8 (input_bfd,
   3085   1.1     skrll 					contents + rel->r_offset - 2);
   3086   1.1     skrll 		      switch (type)
   3087   1.1     skrll 			{
   3088   1.1     skrll 			case 0x8b:
   3089   1.1     skrll 			  /* movl */
   3090   1.1     skrll 			  bfd_put_8 (output_bfd, 0xc7,
   3091   1.1     skrll 				     contents + rel->r_offset - 2);
   3092   1.1     skrll 			  bfd_put_8 (output_bfd,
   3093   1.1     skrll 				     0xc0 | ((val >> 3) & 7),
   3094   1.1     skrll 				     contents + rel->r_offset - 1);
   3095   1.1     skrll 			  break;
   3096   1.1     skrll 			case 0x03:
   3097   1.1     skrll 			  /* addl */
   3098   1.1     skrll 			  bfd_put_8 (output_bfd, 0x81,
   3099   1.1     skrll 				     contents + rel->r_offset - 2);
   3100   1.1     skrll 			  bfd_put_8 (output_bfd,
   3101   1.1     skrll 				     0xc0 | ((val >> 3) & 7),
   3102   1.1     skrll 				     contents + rel->r_offset - 1);
   3103   1.1     skrll 			  break;
   3104   1.1     skrll 			default:
   3105   1.1     skrll 			  BFD_FAIL ();
   3106   1.4  christos 			  break;
   3107   1.1     skrll 			}
   3108   1.1     skrll 		    }
   3109   1.1     skrll 		  bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
   3110   1.1     skrll 			      contents + rel->r_offset);
   3111   1.1     skrll 		  continue;
   3112   1.1     skrll 		}
   3113   1.1     skrll 	      else
   3114   1.1     skrll 		{
   3115   1.1     skrll 		  unsigned int val, type;
   3116   1.1     skrll 
   3117   1.1     skrll 		  /* {IE_32,GOTIE}->LE transition:
   3118   1.1     skrll 		     Originally it can be one of:
   3119   1.1     skrll 		     subl foo(%reg1), %reg2
   3120   1.1     skrll 		     movl foo(%reg1), %reg2
   3121   1.1     skrll 		     addl foo(%reg1), %reg2
   3122   1.1     skrll 		     We change it into:
   3123   1.1     skrll 		     subl $foo, %reg2
   3124   1.1     skrll 		     movl $foo, %reg2 (6 byte form)
   3125   1.1     skrll 		     addl $foo, %reg2.  */
   3126   1.1     skrll 		  type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
   3127   1.1     skrll 		  val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
   3128   1.1     skrll 		  if (type == 0x8b)
   3129   1.1     skrll 		    {
   3130   1.1     skrll 		      /* movl */
   3131   1.1     skrll 		      bfd_put_8 (output_bfd, 0xc7,
   3132   1.1     skrll 				 contents + rel->r_offset - 2);
   3133   1.1     skrll 		      bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
   3134   1.1     skrll 				 contents + rel->r_offset - 1);
   3135   1.1     skrll 		    }
   3136   1.1     skrll 		  else if (type == 0x2b)
   3137   1.1     skrll 		    {
   3138   1.1     skrll 		      /* subl */
   3139   1.1     skrll 		      bfd_put_8 (output_bfd, 0x81,
   3140   1.1     skrll 				 contents + rel->r_offset - 2);
   3141   1.1     skrll 		      bfd_put_8 (output_bfd, 0xe8 | ((val >> 3) & 7),
   3142   1.1     skrll 				 contents + rel->r_offset - 1);
   3143   1.1     skrll 		    }
   3144   1.1     skrll 		  else if (type == 0x03)
   3145   1.1     skrll 		    {
   3146   1.1     skrll 		      /* addl */
   3147   1.1     skrll 		      bfd_put_8 (output_bfd, 0x81,
   3148   1.1     skrll 				 contents + rel->r_offset - 2);
   3149   1.1     skrll 		      bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
   3150   1.1     skrll 				 contents + rel->r_offset - 1);
   3151  1.10  christos 		    }
   3152   1.4  christos 		  else
   3153   1.1     skrll 		    BFD_FAIL ();
   3154   1.1     skrll 		  if (r_type == R_386_TLS_GOTIE)
   3155   1.4  christos 		    bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
   3156   1.1     skrll 				contents + rel->r_offset);
   3157   1.1     skrll 		  else
   3158   1.1     skrll 		    bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation),
   3159   1.1     skrll 				contents + rel->r_offset);
   3160   1.1     skrll 		  continue;
   3161   1.4  christos 		}
   3162   1.1     skrll 	    }
   3163   1.1     skrll 
   3164   1.1     skrll 	  if (htab->elf.sgot == NULL)
   3165   1.1     skrll 	    abort ();
   3166   1.1     skrll 
   3167  1.10  christos 	  if (h != NULL)
   3168   1.1     skrll 	    {
   3169   1.1     skrll 	      off = h->got.offset;
   3170   1.1     skrll 	      offplt = elf_x86_hash_entry (h)->tlsdesc_got;
   3171   1.1     skrll 	    }
   3172   1.1     skrll 	  else
   3173   1.1     skrll 	    {
   3174   1.1     skrll 	      if (local_got_offsets == NULL)
   3175   1.1     skrll 		abort ();
   3176   1.1     skrll 
   3177   1.1     skrll 	      off = local_got_offsets[r_symndx];
   3178   1.1     skrll 	      offplt = local_tlsdesc_gotents[r_symndx];
   3179   1.1     skrll 	    }
   3180   1.1     skrll 
   3181   1.1     skrll 	  if ((off & 1) != 0)
   3182   1.1     skrll 	    off &= ~1;
   3183   1.4  christos 	  else
   3184   1.1     skrll 	    {
   3185   1.1     skrll 	      Elf_Internal_Rela outrel;
   3186   1.4  christos 	      int dr_type;
   3187   1.1     skrll 	      asection *sreloc;
   3188   1.1     skrll 
   3189   1.1     skrll 	      if (htab->elf.srelgot == NULL)
   3190   1.1     skrll 		abort ();
   3191   1.1     skrll 
   3192   1.1     skrll 	      indx = h && h->dynindx != -1 ? h->dynindx : 0;
   3193   1.1     skrll 
   3194   1.1     skrll 	      if (GOT_TLS_GDESC_P (tls_type))
   3195   1.4  christos 		{
   3196   1.4  christos 		  outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_DESC);
   3197   1.4  christos 		  BFD_ASSERT (htab->sgotplt_jump_table_size + offplt + 8
   3198   1.1     skrll 			      <= htab->elf.sgotplt->size);
   3199   1.1     skrll 		  outrel.r_offset = (htab->elf.sgotplt->output_section->vma
   3200  1.17  christos 				     + htab->elf.sgotplt->output_offset
   3201  1.17  christos 				     + offplt
   3202   1.1     skrll 				     + htab->sgotplt_jump_table_size);
   3203   1.1     skrll 		  sreloc = htab->rel_tls_desc;
   3204   1.1     skrll 		  _bfd_elf_append_rel (output_bfd, sreloc, &outrel);
   3205   1.1     skrll 		  if (indx == 0)
   3206  1.10  christos 		    {
   3207   1.4  christos 		      BFD_ASSERT (! unresolved_reloc);
   3208   1.1     skrll 		      bfd_put_32 (output_bfd,
   3209   1.1     skrll 				  relocation - _bfd_x86_elf_dtpoff_base (info),
   3210   1.1     skrll 				  htab->elf.sgotplt->contents + offplt
   3211   1.1     skrll 				  + htab->sgotplt_jump_table_size + 4);
   3212   1.1     skrll 		    }
   3213   1.4  christos 		  else
   3214   1.1     skrll 		    {
   3215   1.1     skrll 		      bfd_put_32 (output_bfd, 0,
   3216   1.1     skrll 				  htab->elf.sgotplt->contents + offplt
   3217   1.1     skrll 				  + htab->sgotplt_jump_table_size + 4);
   3218   1.4  christos 		    }
   3219   1.1     skrll 		}
   3220   1.4  christos 
   3221   1.4  christos 	      sreloc = htab->elf.srelgot;
   3222   1.1     skrll 
   3223   1.1     skrll 	      outrel.r_offset = (htab->elf.sgot->output_section->vma
   3224   1.1     skrll 				 + htab->elf.sgot->output_offset + off);
   3225   1.1     skrll 
   3226   1.1     skrll 	      if (GOT_TLS_GD_P (tls_type))
   3227   1.1     skrll 		dr_type = R_386_TLS_DTPMOD32;
   3228   1.1     skrll 	      else if (GOT_TLS_GDESC_P (tls_type))
   3229   1.1     skrll 		goto dr_done;
   3230   1.1     skrll 	      else if (tls_type == GOT_TLS_IE_POS)
   3231   1.1     skrll 		dr_type = R_386_TLS_TPOFF;
   3232   1.1     skrll 	      else
   3233   1.4  christos 		dr_type = R_386_TLS_TPOFF32;
   3234  1.10  christos 
   3235   1.4  christos 	      if (dr_type == R_386_TLS_TPOFF && indx == 0)
   3236   1.1     skrll 		bfd_put_32 (output_bfd,
   3237   1.5  christos 			    relocation - _bfd_x86_elf_dtpoff_base (info),
   3238  1.10  christos 			    htab->elf.sgot->contents + off);
   3239   1.4  christos 	      else if (dr_type == R_386_TLS_TPOFF32 && indx == 0)
   3240   1.1     skrll 		bfd_put_32 (output_bfd,
   3241   1.1     skrll 			    _bfd_x86_elf_dtpoff_base (info) - relocation,
   3242   1.4  christos 			    htab->elf.sgot->contents + off);
   3243   1.1     skrll 	      else if (dr_type != R_386_TLS_DESC)
   3244   1.1     skrll 		bfd_put_32 (output_bfd, 0,
   3245  1.17  christos 			    htab->elf.sgot->contents + off);
   3246   1.1     skrll 	      outrel.r_info = ELF32_R_INFO (indx, dr_type);
   3247   1.1     skrll 
   3248   1.1     skrll 	      _bfd_elf_append_rel (output_bfd, sreloc, &outrel);
   3249   1.1     skrll 
   3250   1.1     skrll 	      if (GOT_TLS_GD_P (tls_type))
   3251  1.10  christos 		{
   3252   1.1     skrll 		  if (indx == 0)
   3253  1.10  christos 		    {
   3254   1.4  christos 		      BFD_ASSERT (! unresolved_reloc);
   3255   1.1     skrll 		      bfd_put_32 (output_bfd,
   3256   1.1     skrll 				  relocation - _bfd_x86_elf_dtpoff_base (info),
   3257   1.1     skrll 				  htab->elf.sgot->contents + off + 4);
   3258   1.1     skrll 		    }
   3259   1.4  christos 		  else
   3260   1.1     skrll 		    {
   3261   1.1     skrll 		      bfd_put_32 (output_bfd, 0,
   3262   1.1     skrll 				  htab->elf.sgot->contents + off + 4);
   3263  1.17  christos 		      outrel.r_info = ELF32_R_INFO (indx,
   3264   1.1     skrll 						    R_386_TLS_DTPOFF32);
   3265   1.1     skrll 		      outrel.r_offset += 4;
   3266   1.1     skrll 		      _bfd_elf_append_rel (output_bfd, sreloc, &outrel);
   3267   1.1     skrll 		    }
   3268   1.1     skrll 		}
   3269   1.4  christos 	      else if (tls_type == GOT_TLS_IE_BOTH)
   3270  1.10  christos 		{
   3271   1.4  christos 		  bfd_put_32 (output_bfd,
   3272   1.4  christos 			      (indx == 0
   3273   1.1     skrll 			       ? relocation - _bfd_x86_elf_dtpoff_base (info)
   3274   1.1     skrll 			       : 0),
   3275  1.17  christos 			      htab->elf.sgot->contents + off + 4);
   3276   1.1     skrll 		  outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
   3277   1.1     skrll 		  outrel.r_offset += 4;
   3278   1.1     skrll 		  _bfd_elf_append_rel (output_bfd, sreloc, &outrel);
   3279   1.1     skrll 		}
   3280   1.1     skrll 
   3281   1.1     skrll 	    dr_done:
   3282   1.1     skrll 	      if (h != NULL)
   3283   1.1     skrll 		h->got.offset |= 1;
   3284   1.1     skrll 	      else
   3285   1.1     skrll 		local_got_offsets[r_symndx] |= 1;
   3286   1.1     skrll 	    }
   3287   1.1     skrll 
   3288  1.10  christos 	  if (off >= (bfd_vma) -2
   3289  1.10  christos 	      && ! GOT_TLS_GDESC_P (tls_type))
   3290   1.1     skrll 	    abort ();
   3291   1.1     skrll 	  if (r_type_tls == R_386_TLS_GOTDESC
   3292  1.13  christos 	      || r_type_tls == R_386_TLS_DESC_CALL)
   3293   1.1     skrll 	    {
   3294  1.10  christos 	      relocation = htab->sgotplt_jump_table_size + offplt;
   3295   1.1     skrll 	      unresolved_reloc = false;
   3296   1.4  christos 	    }
   3297   1.4  christos 	  else if (r_type_tls == r_type)
   3298   1.4  christos 	    {
   3299   1.4  christos 	      bfd_vma g_o_t = htab->elf.sgotplt->output_section->vma
   3300   1.1     skrll 			      + htab->elf.sgotplt->output_offset;
   3301   1.1     skrll 	      relocation = htab->elf.sgot->output_section->vma
   3302   1.1     skrll 		+ htab->elf.sgot->output_offset + off - g_o_t;
   3303   1.1     skrll 	      if ((r_type == R_386_TLS_IE || r_type == R_386_TLS_GOTIE)
   3304   1.1     skrll 		  && tls_type == GOT_TLS_IE_BOTH)
   3305  1.13  christos 		relocation += 4;
   3306   1.1     skrll 	      if (r_type == R_386_TLS_IE)
   3307  1.10  christos 		relocation += g_o_t;
   3308   1.1     skrll 	      unresolved_reloc = false;
   3309   1.1     skrll 	    }
   3310   1.1     skrll 	  else if (r_type == R_386_TLS_GD)
   3311   1.1     skrll 	    {
   3312   1.1     skrll 	      unsigned int val, type;
   3313   1.9  christos 	      bfd_vma roff;
   3314   1.9  christos 
   3315   1.1     skrll 	      /* GD->IE transition.  */
   3316   1.1     skrll 	      type = *(contents + rel->r_offset - 2);
   3317   1.9  christos 	      val = *(contents + rel->r_offset - 1);
   3318   1.9  christos 	      if (type == 0x04)
   3319   1.9  christos 		{
   3320   1.9  christos 		  /* Change
   3321   1.9  christos 			leal foo@tlsgd(,%ebx,1), %eax
   3322   1.9  christos 			call ___tls_get_addr@PLT
   3323   1.1     skrll 		     into:
   3324   1.1     skrll 			movl %gs:0, %eax
   3325   1.1     skrll 			subl $foo@gottpoff(%ebx), %eax.  */
   3326   1.1     skrll 		  val >>= 3;
   3327   1.1     skrll 		  roff = rel->r_offset - 3;
   3328   1.9  christos 		}
   3329   1.9  christos 	      else
   3330   1.9  christos 		{
   3331   1.9  christos 		  /* Change
   3332   1.9  christos 			leal foo@tlsgd(%ebx), %eax
   3333   1.9  christos 			call ___tls_get_addr@PLT
   3334   1.9  christos 			nop
   3335   1.9  christos 		     or
   3336   1.9  christos 			leal foo@tlsgd(%reg), %eax
   3337   1.9  christos 			call *___tls_get_addr@GOT(%reg)
   3338   1.9  christos 			which may be converted to
   3339   1.9  christos 			addr32 call ___tls_get_addr
   3340   1.1     skrll 		     into:
   3341   1.1     skrll 			movl %gs:0, %eax;
   3342   1.1     skrll 			subl $foo@gottpoff(%reg), %eax.  */
   3343   1.1     skrll 		  roff = rel->r_offset - 2;
   3344   1.1     skrll 		}
   3345   1.1     skrll 	      memcpy (contents + roff,
   3346   1.1     skrll 		      "\x65\xa1\0\0\0\0\x2b\x80\0\0\0", 12);
   3347   1.1     skrll 	      contents[roff + 7] = 0x80 | (val & 7);
   3348   1.1     skrll 	      /* If foo is used only with foo@gotntpoff(%reg) and
   3349   1.1     skrll 		 foo@indntpoff, but not with foo@gottpoff(%reg), change
   3350   1.1     skrll 		 subl $foo@gottpoff(%reg), %eax
   3351   1.1     skrll 		 into:
   3352   1.1     skrll 		 addl $foo@gotntpoff(%reg), %eax.  */
   3353   1.4  christos 	      if (tls_type == GOT_TLS_IE_POS)
   3354   1.4  christos 		contents[roff + 6] = 0x03;
   3355   1.4  christos 	      bfd_put_32 (output_bfd,
   3356   1.4  christos 			  htab->elf.sgot->output_section->vma
   3357   1.1     skrll 			  + htab->elf.sgot->output_offset + off
   3358   1.9  christos 			  - htab->elf.sgotplt->output_section->vma
   3359   1.1     skrll 			  - htab->elf.sgotplt->output_offset,
   3360   1.6  christos 			  contents + roff + 8);
   3361   1.1     skrll 	      /* Skip R_386_PLT32 and R_386_GOT32X.  */
   3362   1.1     skrll 	      rel++;
   3363  1.10  christos 	      wrel++;
   3364   1.1     skrll 	      continue;
   3365   1.1     skrll 	    }
   3366   1.1     skrll 	  else if (r_type == R_386_TLS_GOTDESC)
   3367   1.1     skrll 	    {
   3368   1.1     skrll 	      /* GDesc -> IE transition.
   3369   1.1     skrll 		 It's originally something like:
   3370   1.1     skrll 		 leal x@tlsdesc(%ebx), %eax
   3371   1.1     skrll 
   3372   1.1     skrll 		 Change it to:
   3373   1.1     skrll 		 movl x@gotntpoff(%ebx), %eax # before xchg %ax,%ax
   3374   1.1     skrll 		 or:
   3375   1.1     skrll 		 movl x@gottpoff(%ebx), %eax # before negl %eax
   3376   1.1     skrll 
   3377   1.1     skrll 		 Registers other than %eax may be set up here.  */
   3378   1.1     skrll 
   3379   1.1     skrll 	      bfd_vma roff;
   3380   1.1     skrll 
   3381   1.1     skrll 	      /* First, make sure it's a leal adding ebx to a 32-bit
   3382   1.1     skrll 		 offset into any register, although it's probably
   3383   1.1     skrll 		 almost always going to be eax.  */
   3384   1.1     skrll 	      roff = rel->r_offset;
   3385   1.1     skrll 
   3386   1.1     skrll 	      /* Now modify the instruction as appropriate.  */
   3387   1.1     skrll 	      /* To turn a leal into a movl in the form we use it, it
   3388   1.1     skrll 		 suffices to change the first byte from 0x8d to 0x8b.
   3389   1.1     skrll 		 aoliva FIXME: should we decide to keep the leal, all
   3390   1.1     skrll 		 we have to do is remove the statement below, and
   3391   1.1     skrll 		 adjust the relaxation of R_386_TLS_DESC_CALL.  */
   3392   1.1     skrll 	      bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
   3393   1.1     skrll 
   3394   1.1     skrll 	      if (tls_type == GOT_TLS_IE_BOTH)
   3395   1.4  christos 		off += 4;
   3396   1.4  christos 
   3397   1.4  christos 	      bfd_put_32 (output_bfd,
   3398   1.4  christos 			  htab->elf.sgot->output_section->vma
   3399   1.1     skrll 			  + htab->elf.sgot->output_offset + off
   3400   1.1     skrll 			  - htab->elf.sgotplt->output_section->vma
   3401   1.1     skrll 			  - htab->elf.sgotplt->output_offset,
   3402  1.10  christos 			  contents + roff);
   3403   1.1     skrll 	      continue;
   3404   1.1     skrll 	    }
   3405   1.1     skrll 	  else if (r_type == R_386_TLS_DESC_CALL)
   3406   1.1     skrll 	    {
   3407   1.1     skrll 	      /* GDesc -> IE transition.
   3408   1.1     skrll 		 It's originally:
   3409   1.1     skrll 		 call *(%eax)
   3410   1.1     skrll 
   3411   1.1     skrll 		 Change it to:
   3412   1.1     skrll 		 xchg %ax,%ax
   3413   1.1     skrll 		 or
   3414   1.1     skrll 		 negl %eax
   3415   1.1     skrll 		 depending on how we transformed the TLS_GOTDESC above.
   3416   1.1     skrll 	      */
   3417   1.1     skrll 
   3418   1.1     skrll 	      bfd_vma roff;
   3419   1.1     skrll 
   3420   1.1     skrll 	      roff = rel->r_offset;
   3421   1.1     skrll 
   3422   1.1     skrll 	      /* Now modify the instruction as appropriate.  */
   3423   1.1     skrll 	      if (tls_type != GOT_TLS_IE_NEG)
   3424   1.1     skrll 		{
   3425   1.1     skrll 		  /* xchg %ax,%ax */
   3426   1.1     skrll 		  bfd_put_8 (output_bfd, 0x66, contents + roff);
   3427   1.1     skrll 		  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
   3428   1.1     skrll 		}
   3429   1.1     skrll 	      else
   3430   1.1     skrll 		{
   3431   1.1     skrll 		  /* negl %eax */
   3432   1.1     skrll 		  bfd_put_8 (output_bfd, 0xf7, contents + roff);
   3433   1.1     skrll 		  bfd_put_8 (output_bfd, 0xd8, contents + roff + 1);
   3434   1.1     skrll 		}
   3435   1.1     skrll 
   3436  1.13  christos 	      continue;
   3437   1.1     skrll 	    }
   3438   1.1     skrll 	  else
   3439   1.1     skrll 	    BFD_ASSERT (false);
   3440   1.1     skrll 	  break;
   3441   1.1     skrll 
   3442   1.1     skrll 	case R_386_TLS_LDM:
   3443   1.1     skrll 	  if (! elf_i386_tls_transition (info, input_bfd,
   3444  1.16  christos 					 input_section, contents,
   3445  1.13  christos 					 symtab_hdr, sym_hashes,
   3446   1.1     skrll 					 &r_type, GOT_UNKNOWN, rel,
   3447   1.1     skrll 					 relend, h, sym, true))
   3448   1.1     skrll 	    return false;
   3449   1.9  christos 
   3450   1.9  christos 	  if (r_type != R_386_TLS_LDM)
   3451   1.9  christos 	    {
   3452   1.9  christos 	      /* LD->LE transition.  Change
   3453   1.9  christos 			leal foo@tlsldm(%ebx) %eax
   3454   1.9  christos 			call ___tls_get_addr@PLT
   3455   1.9  christos 		 into:
   3456   1.9  christos 			movl %gs:0, %eax
   3457   1.9  christos 			nop
   3458   1.9  christos 			leal 0(%esi,1), %esi
   3459   1.9  christos 		 or change
   3460   1.9  christos 			leal foo@tlsldm(%reg) %eax
   3461   1.9  christos 			call *___tls_get_addr@GOT(%reg)
   3462   1.9  christos 			which may be converted to
   3463   1.9  christos 			addr32 call ___tls_get_addr
   3464  1.15  christos 		 into:
   3465  1.15  christos 			movl %gs:0, %eax
   3466  1.15  christos 			leal 0(%esi), %esi  */
   3467   1.9  christos 	      expected_tls_le = htab->elf.target_os == is_solaris
   3468   1.9  christos 		? R_386_TLS_LE : R_386_TLS_LE_32;
   3469   1.9  christos 	      BFD_ASSERT (r_type == expected_tls_le);
   3470   1.9  christos 	      if (*(contents + rel->r_offset + 4) == 0xff
   3471   1.9  christos 		  || *(contents + rel->r_offset + 4) == 0x67)
   3472   1.9  christos 		memcpy (contents + rel->r_offset - 2,
   3473   1.9  christos 			"\x65\xa1\0\0\0\0\x8d\xb6\0\0\0", 12);
   3474   1.1     skrll 	      else
   3475   1.1     skrll 		memcpy (contents + rel->r_offset - 2,
   3476   1.6  christos 			"\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11);
   3477   1.1     skrll 	      /* Skip R_386_PC32/R_386_PLT32.  */
   3478   1.1     skrll 	      rel++;
   3479   1.1     skrll 	      wrel++;
   3480   1.4  christos 	      continue;
   3481   1.1     skrll 	    }
   3482   1.1     skrll 
   3483  1.10  christos 	  if (htab->elf.sgot == NULL)
   3484   1.1     skrll 	    abort ();
   3485   1.1     skrll 
   3486   1.1     skrll 	  off = htab->tls_ld_or_ldm_got.offset;
   3487   1.1     skrll 	  if (off & 1)
   3488   1.1     skrll 	    off &= ~1;
   3489   1.1     skrll 	  else
   3490   1.4  christos 	    {
   3491   1.1     skrll 	      Elf_Internal_Rela outrel;
   3492   1.1     skrll 
   3493   1.4  christos 	      if (htab->elf.srelgot == NULL)
   3494   1.4  christos 		abort ();
   3495   1.1     skrll 
   3496   1.1     skrll 	      outrel.r_offset = (htab->elf.sgot->output_section->vma
   3497   1.4  christos 				 + htab->elf.sgot->output_offset + off);
   3498   1.1     skrll 
   3499   1.4  christos 	      bfd_put_32 (output_bfd, 0,
   3500   1.1     skrll 			  htab->elf.sgot->contents + off);
   3501  1.17  christos 	      bfd_put_32 (output_bfd, 0,
   3502  1.10  christos 			  htab->elf.sgot->contents + off + 4);
   3503   1.1     skrll 	      outrel.r_info = ELF32_R_INFO (0, R_386_TLS_DTPMOD32);
   3504   1.4  christos 	      _bfd_elf_append_rel (output_bfd, htab->elf.srelgot, &outrel);
   3505   1.4  christos 	      htab->tls_ld_or_ldm_got.offset |= 1;
   3506   1.4  christos 	    }
   3507   1.4  christos 	  relocation = htab->elf.sgot->output_section->vma
   3508  1.13  christos 		       + htab->elf.sgot->output_offset + off
   3509   1.1     skrll 		       - htab->elf.sgotplt->output_section->vma
   3510   1.1     skrll 		       - htab->elf.sgotplt->output_offset;
   3511   1.1     skrll 	  unresolved_reloc = false;
   3512   1.6  christos 	  break;
   3513   1.6  christos 
   3514  1.10  christos 	case R_386_TLS_LDO_32:
   3515   1.1     skrll 	  if (!bfd_link_executable (info)
   3516   1.1     skrll 	      || (input_section->flags & SEC_CODE) == 0)
   3517   1.4  christos 	    relocation -= _bfd_x86_elf_dtpoff_base (info);
   3518   1.1     skrll 	  else
   3519   1.1     skrll 	    /* When converting LDO to LE, we must negate.  */
   3520   1.1     skrll 	    relocation = -elf_i386_tpoff (info, relocation);
   3521   1.1     skrll 	  break;
   3522   1.6  christos 
   3523   1.1     skrll 	case R_386_TLS_LE_32:
   3524   1.1     skrll 	case R_386_TLS_LE:
   3525   1.1     skrll 	  if (!bfd_link_executable (info))
   3526   1.1     skrll 	    {
   3527   1.1     skrll 	      Elf_Internal_Rela outrel;
   3528   1.1     skrll 	      asection *sreloc;
   3529   1.1     skrll 
   3530   1.1     skrll 	      outrel.r_offset = rel->r_offset
   3531   1.1     skrll 				+ input_section->output_section->vma
   3532   1.1     skrll 				+ input_section->output_offset;
   3533   1.1     skrll 	      if (h != NULL && h->dynindx != -1)
   3534   1.1     skrll 		indx = h->dynindx;
   3535   1.1     skrll 	      else
   3536   1.1     skrll 		indx = 0;
   3537   1.1     skrll 	      if (r_type == R_386_TLS_LE_32)
   3538   1.1     skrll 		outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF32);
   3539   1.1     skrll 	      else
   3540   1.1     skrll 		outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
   3541  1.17  christos 	      sreloc = elf_section_data (input_section)->sreloc;
   3542   1.1     skrll 	      if (sreloc == NULL)
   3543   1.1     skrll 		abort ();
   3544   1.1     skrll 	      _bfd_elf_append_rel (output_bfd, sreloc, &outrel);
   3545  1.10  christos 	      if (indx)
   3546   1.1     skrll 		continue;
   3547  1.10  christos 	      else if (r_type == R_386_TLS_LE_32)
   3548   1.1     skrll 		relocation = _bfd_x86_elf_dtpoff_base (info) - relocation;
   3549   1.1     skrll 	      else
   3550   1.4  christos 		relocation -= _bfd_x86_elf_dtpoff_base (info);
   3551   1.1     skrll 	    }
   3552   1.4  christos 	  else if (r_type == R_386_TLS_LE_32)
   3553   1.1     skrll 	    relocation = elf_i386_tpoff (info, relocation);
   3554   1.1     skrll 	  else
   3555   1.1     skrll 	    relocation = -elf_i386_tpoff (info, relocation);
   3556   1.1     skrll 	  break;
   3557   1.1     skrll 
   3558   1.1     skrll 	default:
   3559   1.1     skrll 	  break;
   3560   1.1     skrll 	}
   3561   1.1     skrll 
   3562   1.1     skrll       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
   3563   1.1     skrll 	 because such sections are not SEC_ALLOC and thus ld.so will
   3564   1.5  christos 	 not process them.  */
   3565   1.5  christos       if (unresolved_reloc
   3566   1.5  christos 	  && !((input_section->flags & SEC_DEBUGGING) != 0
   3567   1.1     skrll 	       && h->def_dynamic)
   3568  1.10  christos 	  && _bfd_elf_section_offset (output_bfd, info, input_section,
   3569  1.10  christos 				      rel->r_offset) != (bfd_vma) -1)
   3570  1.11  christos 	{
   3571   1.1     skrll 	  _bfd_error_handler
   3572   1.1     skrll 	    /* xgettext:c-format */
   3573  1.11  christos 	    (_("%pB(%pA+%#" PRIx64 "): unresolvable %s relocation against symbol `%s'"),
   3574   1.1     skrll 	     input_bfd,
   3575   1.1     skrll 	     input_section,
   3576  1.13  christos 	     (uint64_t) rel->r_offset,
   3577   1.1     skrll 	     howto->name,
   3578   1.1     skrll 	     h->root.root.string);
   3579  1.13  christos 	  return false;
   3580   1.1     skrll 	}
   3581   1.1     skrll 
   3582   1.1     skrll     do_relocation:
   3583   1.1     skrll       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
   3584  1.13  christos 				    contents, rel->r_offset,
   3585   1.1     skrll 				    relocation, 0);
   3586   1.1     skrll 
   3587   1.1     skrll     check_relocation_error:
   3588   1.1     skrll       if (r != bfd_reloc_ok)
   3589   1.1     skrll 	{
   3590   1.1     skrll 	  const char *name;
   3591   1.1     skrll 
   3592   1.1     skrll 	  if (h != NULL)
   3593   1.1     skrll 	    name = h->root.root.string;
   3594   1.1     skrll 	  else
   3595   1.1     skrll 	    {
   3596   1.1     skrll 	      name = bfd_elf_string_from_elf_section (input_bfd,
   3597  1.13  christos 						      symtab_hdr->sh_link,
   3598   1.1     skrll 						      sym->st_name);
   3599  1.12  christos 	      if (name == NULL)
   3600   1.1     skrll 		return false;
   3601   1.1     skrll 	      if (*name == '\0')
   3602   1.1     skrll 		name = bfd_section_name (sec);
   3603   1.9  christos 	    }
   3604   1.9  christos 
   3605   1.9  christos 	  if (r == bfd_reloc_overflow)
   3606   1.1     skrll 	    (*info->callbacks->reloc_overflow)
   3607   1.1     skrll 	      (info, (h ? &h->root : NULL), name, howto->name,
   3608  1.10  christos 	       (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
   3609  1.10  christos 	  else
   3610  1.11  christos 	    {
   3611   1.1     skrll 	      _bfd_error_handler
   3612  1.11  christos 		/* xgettext:c-format */
   3613  1.13  christos 		(_("%pB(%pA+%#" PRIx64 "): reloc against `%s': error %d"),
   3614   1.1     skrll 		 input_bfd, input_section,
   3615   1.1     skrll 		 (uint64_t) rel->r_offset, name, (int) r);
   3616   1.6  christos 	      return false;
   3617   1.6  christos 	    }
   3618   1.6  christos 	}
   3619   1.6  christos 
   3620   1.6  christos       if (wrel != rel)
   3621   1.6  christos 	*wrel = *rel;
   3622   1.6  christos     }
   3623   1.6  christos 
   3624   1.6  christos   if (wrel != rel)
   3625   1.6  christos     {
   3626   1.6  christos       Elf_Internal_Shdr *rel_hdr;
   3627   1.6  christos       size_t deleted = rel - wrel;
   3628   1.6  christos 
   3629   1.6  christos       rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section);
   3630   1.6  christos       rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
   3631   1.1     skrll       rel_hdr = _bfd_elf_single_rel_hdr (input_section);
   3632   1.1     skrll       rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
   3633  1.13  christos       input_section->reloc_count -= deleted;
   3634   1.1     skrll     }
   3635   1.1     skrll 
   3636   1.1     skrll   return true;
   3637   1.1     skrll }
   3638   1.1     skrll 
   3639  1.13  christos /* Finish up dynamic symbol handling.  We set the contents of various
   3640   1.1     skrll    dynamic sections here.  */
   3641   1.1     skrll 
   3642   1.1     skrll static bool
   3643   1.1     skrll elf_i386_finish_dynamic_symbol (bfd *output_bfd,
   3644   1.1     skrll 				struct bfd_link_info *info,
   3645  1.10  christos 				struct elf_link_hash_entry *h,
   3646   1.5  christos 				Elf_Internal_Sym *sym)
   3647  1.10  christos {
   3648  1.13  christos   struct elf_x86_link_hash_table *htab;
   3649  1.13  christos   unsigned plt_entry_size;
   3650   1.1     skrll   struct elf_x86_link_hash_entry *eh;
   3651  1.10  christos   bool local_undefweak;
   3652   1.1     skrll   bool use_plt_second;
   3653  1.10  christos 
   3654  1.10  christos   htab = elf_x86_hash_table (info, I386_ELF_DATA);
   3655  1.10  christos 
   3656  1.10  christos   plt_entry_size = htab->plt.plt_entry_size;
   3657   1.5  christos 
   3658  1.10  christos   /* Use the second PLT section only if there is .plt section.  */
   3659  1.10  christos   use_plt_second = htab->elf.splt != NULL && htab->plt_second != NULL;
   3660  1.10  christos 
   3661   1.6  christos   eh = (struct elf_x86_link_hash_entry *) h;
   3662   1.9  christos   if (eh->no_finish_dynamic_symbol)
   3663   1.9  christos     abort ();
   3664   1.9  christos 
   3665  1.10  christos   /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for
   3666   1.9  christos      resolved undefined weak symbols in executable so that their
   3667   1.1     skrll      references have value 0 at run-time.  */
   3668   1.1     skrll   local_undefweak = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);
   3669  1.10  christos 
   3670   1.1     skrll   if (h->plt.offset != (bfd_vma) -1)
   3671   1.1     skrll     {
   3672   1.1     skrll       bfd_vma plt_index, plt_offset;
   3673  1.10  christos       bfd_vma got_offset;
   3674   1.4  christos       Elf_Internal_Rela rel;
   3675   1.4  christos       bfd_byte *loc;
   3676   1.4  christos       asection *plt, *resolved_plt, *gotplt, *relplt;
   3677   1.4  christos 
   3678   1.4  christos       /* When building a static executable, use .iplt, .igot.plt and
   3679   1.4  christos 	 .rel.iplt sections for STT_GNU_IFUNC symbols.  */
   3680   1.4  christos       if (htab->elf.splt != NULL)
   3681   1.4  christos 	{
   3682   1.4  christos 	  plt = htab->elf.splt;
   3683   1.4  christos 	  gotplt = htab->elf.sgotplt;
   3684   1.4  christos 	  relplt = htab->elf.srelplt;
   3685   1.4  christos 	}
   3686   1.4  christos       else
   3687   1.4  christos 	{
   3688   1.4  christos 	  plt = htab->elf.iplt;
   3689   1.1     skrll 	  gotplt = htab->elf.igotplt;
   3690  1.10  christos 	  relplt = htab->elf.irelplt;
   3691   1.1     skrll 	}
   3692   1.1     skrll 
   3693   1.1     skrll       VERIFY_PLT_ENTRY (info, h, plt, gotplt, relplt, local_undefweak)
   3694   1.1     skrll 
   3695   1.4  christos       /* Get the index in the procedure linkage table which
   3696   1.1     skrll 	 corresponds to this symbol.  This is the index of this symbol
   3697   1.4  christos 	 in all the symbols for which we are making plt entries.  The
   3698   1.1     skrll 	 first entry in the procedure linkage table is reserved.
   3699   1.4  christos 
   3700   1.4  christos 	 Get the offset into the .got table of the entry that
   3701   1.4  christos 	 corresponds to this function.  Each .got entry is 4 bytes.
   3702   1.4  christos 	 The first three are reserved.
   3703   1.4  christos 
   3704   1.4  christos 	 For static executables, we don't reserve anything.  */
   3705  1.10  christos 
   3706  1.10  christos       if (plt == htab->elf.splt)
   3707   1.5  christos 	{
   3708   1.4  christos 	  got_offset = (h->plt.offset / plt_entry_size
   3709   1.4  christos 			- htab->plt.has_plt0);
   3710   1.4  christos 	  got_offset = (got_offset + 3) * 4;
   3711   1.5  christos 	}
   3712   1.5  christos       else
   3713   1.4  christos 	{
   3714   1.1     skrll 	  got_offset = h->plt.offset / plt_entry_size;
   3715  1.10  christos 	  got_offset = got_offset * 4;
   3716  1.10  christos 	}
   3717  1.10  christos 
   3718  1.10  christos       /* Fill in the entry in the procedure linkage table and update
   3719  1.10  christos 	 the first slot.  */
   3720  1.10  christos       memcpy (plt->contents + h->plt.offset, htab->plt.plt_entry,
   3721  1.10  christos 	      plt_entry_size);
   3722  1.10  christos 
   3723  1.10  christos       if (use_plt_second)
   3724  1.10  christos 	{
   3725  1.10  christos 	  const bfd_byte *plt_entry;
   3726  1.10  christos 	  if (bfd_link_pic (info))
   3727  1.10  christos 	    plt_entry = htab->non_lazy_plt->pic_plt_entry;
   3728  1.10  christos 	  else
   3729  1.10  christos 	    plt_entry = htab->non_lazy_plt->plt_entry;
   3730  1.10  christos 	  memcpy (htab->plt_second->contents + eh->plt_second.offset,
   3731  1.10  christos 		  plt_entry, htab->non_lazy_plt->plt_entry_size);
   3732  1.10  christos 
   3733  1.10  christos 	  resolved_plt = htab->plt_second;
   3734  1.10  christos 	  plt_offset = eh->plt_second.offset;
   3735  1.10  christos 	}
   3736  1.10  christos       else
   3737  1.10  christos 	{
   3738  1.10  christos 	  resolved_plt = plt;
   3739   1.6  christos 	  plt_offset = h->plt.offset;
   3740   1.1     skrll 	}
   3741   1.1     skrll 
   3742   1.4  christos       if (! bfd_link_pic (info))
   3743   1.4  christos 	{
   3744   1.1     skrll 	  bfd_put_32 (output_bfd,
   3745  1.10  christos 		      (gotplt->output_section->vma
   3746  1.10  christos 		       + gotplt->output_offset
   3747   1.1     skrll 		       + got_offset),
   3748  1.13  christos 		      resolved_plt->contents + plt_offset
   3749   1.1     skrll 		      + htab->plt.plt_got_offset);
   3750   1.1     skrll 
   3751   1.1     skrll 	  if (htab->elf.target_os == is_vxworks)
   3752   1.1     skrll 	    {
   3753   1.1     skrll 	      int s, k, reloc_index;
   3754   1.1     skrll 
   3755   1.1     skrll 	      /* Create the R_386_32 relocation referencing the GOT
   3756  1.10  christos 		 for this PLT entry.  */
   3757  1.10  christos 
   3758   1.1     skrll 	      /* S: Current slot number (zero-based).  */
   3759   1.6  christos 	      s = ((h->plt.offset - htab->plt.plt_entry_size)
   3760   1.1     skrll 		   / htab->plt.plt_entry_size);
   3761   1.1     skrll 	      /* K: Number of relocations for PLTResolve. */
   3762   1.1     skrll 	      if (bfd_link_pic (info))
   3763   1.1     skrll 		k = PLTRESOLVE_RELOCS_SHLIB;
   3764   1.1     skrll 	      else
   3765   1.1     skrll 		k = PLTRESOLVE_RELOCS;
   3766   1.1     skrll 	      /* Skip the PLTresolve relocations, and the relocations for
   3767   1.1     skrll 		 the other PLT slots. */
   3768   1.1     skrll 	      reloc_index = k + s * PLT_NON_JUMP_SLOT_RELOCS;
   3769  1.10  christos 	      loc = (htab->srelplt2->contents + reloc_index
   3770  1.10  christos 		     * sizeof (Elf32_External_Rel));
   3771   1.1     skrll 
   3772   1.1     skrll 	      rel.r_offset = (plt->output_section->vma
   3773   1.1     skrll 			      + plt->output_offset
   3774   1.1     skrll 			      + h->plt.offset + 2),
   3775   1.1     skrll 	      rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
   3776   1.1     skrll 	      bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
   3777   1.4  christos 
   3778   1.4  christos 	      /* Create the R_386_32 relocation referencing the beginning of
   3779   1.1     skrll 		 the PLT for this GOT entry.  */
   3780   1.1     skrll 	      rel.r_offset = (htab->elf.sgotplt->output_section->vma
   3781   1.1     skrll 			      + htab->elf.sgotplt->output_offset
   3782   1.6  christos 			      + got_offset);
   3783   1.1     skrll 	      rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32);
   3784   1.1     skrll 	      bfd_elf32_swap_reloc_out (output_bfd, &rel,
   3785   1.1     skrll 					loc + sizeof (Elf32_External_Rel));
   3786   1.1     skrll 	    }
   3787   1.1     skrll 	}
   3788  1.10  christos       else
   3789  1.10  christos 	{
   3790   1.4  christos 	  bfd_put_32 (output_bfd, got_offset,
   3791   1.1     skrll 		      resolved_plt->contents + plt_offset
   3792   1.9  christos 		      + htab->plt.plt_got_offset);
   3793   1.9  christos 	}
   3794   1.9  christos 
   3795   1.9  christos       /* Fill in the entry in the global offset table.  Leave the entry
   3796   1.9  christos 	 as zero for undefined weak symbol in PIE.  No PLT relocation
   3797  1.10  christos 	 against undefined weak symbol in PIE.  */
   3798  1.10  christos       if (!local_undefweak)
   3799  1.10  christos 	{
   3800  1.10  christos 	  if (htab->plt.has_plt0)
   3801  1.10  christos 	    bfd_put_32 (output_bfd,
   3802  1.10  christos 			(plt->output_section->vma
   3803  1.10  christos 			 + plt->output_offset
   3804   1.1     skrll 			 + h->plt.offset
   3805   1.9  christos 			 + htab->lazy_plt->plt_lazy_offset),
   3806   1.9  christos 			gotplt->contents + got_offset);
   3807   1.9  christos 
   3808   1.9  christos 	  /* Fill in the entry in the .rel.plt section.  */
   3809  1.10  christos 	  rel.r_offset = (gotplt->output_section->vma
   3810   1.9  christos 			  + gotplt->output_offset
   3811  1.11  christos 			  + got_offset);
   3812  1.10  christos 	  if (PLT_LOCAL_IFUNC_P (info, h))
   3813  1.10  christos 	    {
   3814  1.10  christos 	      info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"),
   3815   1.9  christos 				      h->root.root.string,
   3816   1.9  christos 				      h->root.u.def.section->owner);
   3817   1.9  christos 
   3818   1.9  christos 	      /* If an STT_GNU_IFUNC symbol is locally defined, generate
   3819   1.9  christos 		 R_386_IRELATIVE instead of R_386_JUMP_SLOT.  Store addend
   3820   1.9  christos 		 in the .got.plt section.  */
   3821   1.9  christos 	      bfd_put_32 (output_bfd,
   3822   1.9  christos 			  (h->root.u.def.value
   3823   1.9  christos 			   + h->root.u.def.section->output_section->vma
   3824  1.13  christos 			   + h->root.u.def.section->output_offset),
   3825  1.13  christos 			  gotplt->contents + got_offset);
   3826  1.13  christos 	      rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
   3827  1.13  christos 
   3828  1.13  christos 	      if (htab->params->report_relative_reloc)
   3829   1.9  christos 		_bfd_x86_elf_link_report_relative_reloc
   3830   1.9  christos 		  (info, relplt, h, sym, "R_386_IRELATIVE", &rel);
   3831   1.9  christos 
   3832   1.9  christos 	      /* R_386_IRELATIVE comes last.  */
   3833   1.9  christos 	      plt_index = htab->next_irelative_index--;
   3834   1.9  christos 	    }
   3835   1.9  christos 	  else
   3836   1.9  christos 	    {
   3837   1.9  christos 	      rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT);
   3838   1.9  christos 	      plt_index = htab->next_jump_slot_index++;
   3839   1.9  christos 	    }
   3840   1.9  christos 
   3841  1.10  christos 	  loc = relplt->contents + plt_index * sizeof (Elf32_External_Rel);
   3842  1.10  christos 	  bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
   3843  1.10  christos 
   3844   1.9  christos 	  /* Don't fill the second and third slots in PLT entry for
   3845   1.9  christos 	     static executables nor without PLT0.  */
   3846   1.9  christos 	  if (plt == htab->elf.splt && htab->plt.has_plt0)
   3847   1.9  christos 	    {
   3848  1.10  christos 	      bfd_put_32 (output_bfd,
   3849  1.10  christos 			  plt_index * sizeof (Elf32_External_Rel),
   3850  1.10  christos 			  plt->contents + h->plt.offset
   3851  1.10  christos 			  + htab->lazy_plt->plt_reloc_offset);
   3852  1.10  christos 	      bfd_put_32 (output_bfd,
   3853  1.10  christos 			  - (h->plt.offset
   3854   1.9  christos 			     + htab->lazy_plt->plt_plt_offset + 4),
   3855   1.5  christos 			  (plt->contents + h->plt.offset
   3856   1.6  christos 			   + htab->lazy_plt->plt_plt_offset));
   3857   1.6  christos 	    }
   3858   1.6  christos 	}
   3859   1.6  christos     }
   3860   1.6  christos   else if (eh->plt_got.offset != (bfd_vma) -1)
   3861   1.6  christos     {
   3862   1.6  christos       bfd_vma got_offset, plt_offset;
   3863   1.6  christos       asection *plt, *got, *gotplt;
   3864   1.6  christos       const bfd_byte *got_plt_entry;
   3865   1.6  christos 
   3866   1.6  christos       /* Set the entry in the GOT procedure linkage table.  */
   3867   1.6  christos       plt = htab->plt_got;
   3868   1.6  christos       got = htab->elf.sgot;
   3869   1.6  christos       gotplt = htab->elf.sgotplt;
   3870   1.6  christos       got_offset = h->got.offset;
   3871   1.6  christos 
   3872   1.6  christos       if (got_offset == (bfd_vma) -1
   3873   1.6  christos 	  || plt == NULL
   3874   1.5  christos 	  || got == NULL
   3875   1.6  christos 	  || gotplt == NULL)
   3876   1.6  christos 	abort ();
   3877   1.1     skrll 
   3878  1.10  christos       /* Fill in the entry in the GOT procedure linkage table.  */
   3879   1.6  christos       if (! bfd_link_pic (info))
   3880   1.1     skrll 	{
   3881   1.6  christos 	  got_plt_entry = htab->non_lazy_plt->plt_entry;
   3882   1.6  christos 	  got_offset += got->output_section->vma + got->output_offset;
   3883  1.10  christos 	}
   3884   1.6  christos       else
   3885   1.6  christos 	{
   3886   1.6  christos 	  got_plt_entry = htab->non_lazy_plt->pic_plt_entry;
   3887   1.6  christos 	  got_offset += (got->output_section->vma
   3888   1.6  christos 			 + got->output_offset
   3889   1.6  christos 			 - gotplt->output_section->vma
   3890   1.6  christos 			 - gotplt->output_offset);
   3891   1.6  christos 	}
   3892  1.10  christos 
   3893   1.6  christos       plt_offset = eh->plt_got.offset;
   3894  1.10  christos       memcpy (plt->contents + plt_offset, got_plt_entry,
   3895  1.10  christos 	      htab->non_lazy_plt->plt_entry_size);
   3896   1.6  christos       bfd_put_32 (output_bfd, got_offset,
   3897   1.6  christos 		  (plt->contents + plt_offset
   3898   1.9  christos 		   + htab->non_lazy_plt->plt_got_offset));
   3899   1.9  christos     }
   3900   1.6  christos 
   3901   1.6  christos   if (!local_undefweak
   3902   1.6  christos       && !h->def_regular
   3903   1.6  christos       && (h->plt.offset != (bfd_vma) -1
   3904   1.6  christos 	  || eh->plt_got.offset != (bfd_vma) -1))
   3905   1.6  christos     {
   3906   1.6  christos       /* Mark the symbol as undefined, rather than as defined in
   3907   1.6  christos 	 the .plt section.  Leave the value if there were any
   3908   1.6  christos 	 relocations where pointer equality matters (this is a clue
   3909   1.6  christos 	 for the dynamic linker, to make function pointer
   3910   1.6  christos 	 comparisons work between an application and shared
   3911   1.6  christos 	 library), otherwise set it to zero.  If a function is only
   3912   1.6  christos 	 called from a binary, there is no need to slow down
   3913   1.6  christos 	 shared libraries because of that.  */
   3914   1.1     skrll       sym->st_shndx = SHN_UNDEF;
   3915   1.1     skrll       if (!h->pointer_equality_needed)
   3916  1.11  christos 	sym->st_value = 0;
   3917  1.11  christos     }
   3918   1.9  christos 
   3919   1.9  christos   _bfd_x86_elf_link_fixup_ifunc_symbol (info, htab, h, sym);
   3920   1.1     skrll 
   3921  1.10  christos   /* Don't generate dynamic GOT relocation against undefined weak
   3922  1.10  christos      symbol in executable.  */
   3923   1.9  christos   if (h->got.offset != (bfd_vma) -1
   3924   1.1     skrll       && ! GOT_TLS_GD_ANY_P (elf_x86_hash_entry(h)->tls_type)
   3925   1.1     skrll       && (elf_x86_hash_entry(h)->tls_type & GOT_TLS_IE) == 0
   3926   1.9  christos       && !local_undefweak)
   3927  1.13  christos     {
   3928  1.13  christos       Elf_Internal_Rela rel;
   3929   1.1     skrll       asection *relgot = htab->elf.srelgot;
   3930   1.1     skrll       const char *relative_reloc_name = NULL;
   3931   1.1     skrll       bool generate_dynamic_reloc = true;
   3932   1.1     skrll 
   3933   1.4  christos       /* This symbol has an entry in the global offset table.  Set it
   3934   1.1     skrll 	 up.  */
   3935   1.1     skrll 
   3936   1.4  christos       if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
   3937   1.4  christos 	abort ();
   3938   1.1     skrll 
   3939   1.1     skrll       rel.r_offset = (htab->elf.sgot->output_section->vma
   3940   1.1     skrll 		      + htab->elf.sgot->output_offset
   3941   1.1     skrll 		      + (h->got.offset & ~(bfd_vma) 1));
   3942   1.1     skrll 
   3943   1.1     skrll       /* If this is a static link, or it is a -Bsymbolic link and the
   3944   1.1     skrll 	 symbol is defined locally or was forced to be local because
   3945   1.4  christos 	 of a version file, we just want to emit a RELATIVE reloc.
   3946   1.4  christos 	 The entry in the global offset table will already have been
   3947   1.4  christos 	 initialized in the relocate_section function.  */
   3948   1.9  christos       if (h->def_regular
   3949   1.9  christos 	  && h->type == STT_GNU_IFUNC)
   3950   1.9  christos 	{
   3951   1.9  christos 	  if (h->plt.offset == (bfd_vma) -1)
   3952   1.9  christos 	    {
   3953   1.9  christos 	      /* STT_GNU_IFUNC is referenced without PLT.  */
   3954   1.9  christos 	      if (htab->elf.splt == NULL)
   3955   1.9  christos 		{
   3956   1.9  christos 		  /* use .rel[a].iplt section to store .got relocations
   3957  1.10  christos 		     in static executable.  */
   3958   1.9  christos 		  relgot = htab->elf.irelplt;
   3959  1.11  christos 		}
   3960  1.10  christos 	      if (SYMBOL_REFERENCES_LOCAL_P (info, h))
   3961  1.10  christos 		{
   3962  1.10  christos 		  info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"),
   3963   1.9  christos 					  h->root.root.string,
   3964   1.9  christos 					  h->root.u.def.section->owner);
   3965   1.9  christos 
   3966   1.9  christos 		  bfd_put_32 (output_bfd,
   3967   1.9  christos 			      (h->root.u.def.value
   3968   1.9  christos 			       + h->root.u.def.section->output_section->vma
   3969  1.13  christos 			       + h->root.u.def.section->output_offset),
   3970   1.9  christos 			      htab->elf.sgot->contents + h->got.offset);
   3971   1.9  christos 		  rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
   3972   1.9  christos 		  relative_reloc_name = "R_386_IRELATIVE";
   3973   1.9  christos 		}
   3974   1.9  christos 	      else
   3975   1.4  christos 		goto do_glob_dat;
   3976   1.4  christos 	    }
   3977   1.4  christos 	  else if (bfd_link_pic (info))
   3978   1.4  christos 	    {
   3979   1.4  christos 	      /* Generate R_386_GLOB_DAT.  */
   3980   1.4  christos 	      goto do_glob_dat;
   3981   1.4  christos 	    }
   3982  1.10  christos 	  else
   3983   1.4  christos 	    {
   3984   1.4  christos 	      asection *plt;
   3985   1.4  christos 	      bfd_vma plt_offset;
   3986   1.4  christos 
   3987   1.4  christos 	      if (!h->pointer_equality_needed)
   3988   1.4  christos 		abort ();
   3989   1.4  christos 
   3990  1.10  christos 	      /* For non-shared object, we can't use .got.plt, which
   3991  1.10  christos 		 contains the real function addres if we need pointer
   3992  1.10  christos 		 equality.  We load the GOT entry with the PLT entry.  */
   3993  1.10  christos 	      if (htab->plt_second != NULL)
   3994  1.10  christos 		{
   3995  1.10  christos 		  plt = htab->plt_second;
   3996  1.10  christos 		  plt_offset = eh->plt_second.offset;
   3997  1.10  christos 		}
   3998  1.10  christos 	      else
   3999  1.10  christos 		{
   4000   1.4  christos 		  plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
   4001   1.4  christos 		  plt_offset = h->plt.offset;
   4002  1.10  christos 		}
   4003   1.4  christos 	      bfd_put_32 (output_bfd,
   4004  1.13  christos 			  (plt->output_section->vma
   4005   1.4  christos 			   + plt->output_offset + plt_offset),
   4006   1.4  christos 			  htab->elf.sgot->contents + h->got.offset);
   4007   1.6  christos 	      return true;
   4008  1.10  christos 	    }
   4009   1.1     skrll 	}
   4010   1.1     skrll       else if (bfd_link_pic (info)
   4011  1.13  christos 	       && SYMBOL_REFERENCES_LOCAL_P (info, h))
   4012  1.13  christos 	{
   4013  1.13  christos 	  BFD_ASSERT((h->got.offset & 1) != 0);
   4014  1.13  christos 	  if (info->enable_dt_relr)
   4015  1.13  christos 	    generate_dynamic_reloc = false;
   4016  1.13  christos 	  else
   4017  1.13  christos 	    {
   4018   1.1     skrll 	      rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
   4019   1.1     skrll 	      relative_reloc_name = "R_386_RELATIVE";
   4020   1.1     skrll 	    }
   4021   1.1     skrll 	}
   4022  1.13  christos       else
   4023   1.1     skrll 	{
   4024   1.4  christos 	  BFD_ASSERT((h->got.offset & 1) == 0);
   4025   1.1     skrll 	do_glob_dat:
   4026   1.1     skrll 	  bfd_put_32 (output_bfd, (bfd_vma) 0,
   4027   1.1     skrll 		      htab->elf.sgot->contents + h->got.offset);
   4028  1.13  christos 	  rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
   4029  1.13  christos 	}
   4030  1.13  christos 
   4031  1.13  christos       if (generate_dynamic_reloc)
   4032  1.13  christos 	{
   4033  1.13  christos 	  if (relative_reloc_name != NULL
   4034  1.13  christos 	      && htab->params->report_relative_reloc)
   4035  1.17  christos 	    _bfd_x86_elf_link_report_relative_reloc
   4036  1.13  christos 	      (info, relgot, h, sym, relative_reloc_name, &rel);
   4037   1.1     skrll 
   4038   1.1     skrll 	  _bfd_elf_append_rel (output_bfd, relgot, &rel);
   4039   1.1     skrll 	}
   4040   1.1     skrll     }
   4041   1.1     skrll 
   4042  1.10  christos   if (h->needs_copy)
   4043   1.1     skrll     {
   4044   1.1     skrll       Elf_Internal_Rela rel;
   4045  1.10  christos       asection *s;
   4046   1.1     skrll 
   4047   1.1     skrll       /* This symbol needs a copy reloc.  Set it up.  */
   4048   1.1     skrll       VERIFY_COPY_RELOC (h, htab)
   4049   1.1     skrll 
   4050   1.1     skrll       rel.r_offset = (h->root.u.def.value
   4051  1.10  christos 		      + h->root.u.def.section->output_section->vma
   4052  1.10  christos 		      + h->root.u.def.section->output_offset);
   4053  1.10  christos       rel.r_info = ELF32_R_INFO (h->dynindx, R_386_COPY);
   4054  1.10  christos       if (h->root.u.def.section == htab->elf.sdynrelro)
   4055  1.17  christos 	s = htab->elf.sreldynrelro;
   4056   1.1     skrll       else
   4057   1.1     skrll 	s = htab->elf.srelbss;
   4058  1.13  christos       _bfd_elf_append_rel (output_bfd, s, &rel);
   4059   1.1     skrll     }
   4060   1.1     skrll 
   4061   1.4  christos   return true;
   4062   1.4  christos }
   4063   1.4  christos 
   4064  1.13  christos /* Finish up local dynamic symbol handling.  We set the contents of
   4065   1.4  christos    various dynamic sections here.  */
   4066   1.4  christos 
   4067   1.4  christos static int
   4068   1.4  christos elf_i386_finish_local_dynamic_symbol (void **slot, void *inf)
   4069   1.4  christos {
   4070   1.5  christos   struct elf_link_hash_entry *h
   4071   1.4  christos     = (struct elf_link_hash_entry *) *slot;
   4072   1.4  christos   struct bfd_link_info *info
   4073   1.4  christos     = (struct bfd_link_info *) inf;
   4074   1.4  christos 
   4075   1.4  christos   return elf_i386_finish_dynamic_symbol (info->output_bfd, info,
   4076   1.9  christos 					 h, NULL);
   4077   1.9  christos }
   4078   1.9  christos 
   4079   1.9  christos /* Finish up undefined weak symbol handling in PIE.  Fill its PLT entry
   4080  1.13  christos    here since undefined weak symbol may not be dynamic and may not be
   4081   1.9  christos    called for elf_i386_finish_dynamic_symbol.  */
   4082   1.9  christos 
   4083   1.9  christos static bool
   4084   1.9  christos elf_i386_pie_finish_undefweak_symbol (struct bfd_hash_entry *bh,
   4085   1.9  christos 				      void *inf)
   4086   1.9  christos {
   4087   1.9  christos   struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) bh;
   4088   1.9  christos   struct bfd_link_info *info = (struct bfd_link_info *) inf;
   4089  1.13  christos 
   4090   1.9  christos   if (h->root.type != bfd_link_hash_undefweak
   4091   1.9  christos       || h->dynindx != -1)
   4092  1.10  christos     return true;
   4093   1.9  christos 
   4094   1.9  christos   return elf_i386_finish_dynamic_symbol (info->output_bfd,
   4095   1.1     skrll 					 info, h, NULL);
   4096   1.1     skrll }
   4097   1.1     skrll 
   4098   1.1     skrll /* Used to decide how to sort relocs in an optimal manner for the
   4099   1.6  christos    dynamic linker, before writing them out.  */
   4100   1.6  christos 
   4101   1.6  christos static enum elf_reloc_type_class
   4102   1.1     skrll elf_i386_reloc_type_class (const struct bfd_link_info *info,
   4103   1.6  christos 			   const asection *rel_sec ATTRIBUTE_UNUSED,
   4104  1.17  christos 			   const Elf_Internal_Rela *rela)
   4105   1.6  christos {
   4106   1.6  christos   bfd *abfd = info->output_bfd;
   4107   1.8  christos   elf_backend_data *bed = get_elf_backend_data (abfd);
   4108   1.8  christos   struct elf_link_hash_table *htab = elf_hash_table (info);
   4109   1.8  christos 
   4110   1.8  christos   if (htab->dynsym != NULL
   4111  1.10  christos       && htab->dynsym->contents != NULL)
   4112   1.8  christos     {
   4113   1.9  christos       /* Check relocation against STT_GNU_IFUNC symbol if there are
   4114   1.9  christos 	 dynamic symbols.  */
   4115   1.9  christos       unsigned long r_symndx = ELF32_R_SYM (rela->r_info);
   4116   1.9  christos       if (r_symndx != STN_UNDEF)
   4117   1.9  christos 	{
   4118   1.9  christos 	  Elf_Internal_Sym sym;
   4119   1.9  christos 	  if (!bed->s->swap_symbol_in (abfd,
   4120   1.9  christos 				       (htab->dynsym->contents
   4121   1.6  christos 					+ r_symndx * sizeof (Elf32_External_Sym)),
   4122   1.9  christos 				       0, &sym))
   4123   1.9  christos 	    abort ();
   4124   1.9  christos 
   4125   1.8  christos 	  if (ELF32_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
   4126   1.6  christos 	    return reloc_class_ifunc;
   4127   1.1     skrll 	}
   4128   1.1     skrll     }
   4129   1.9  christos 
   4130   1.9  christos   switch (ELF32_R_TYPE (rela->r_info))
   4131   1.1     skrll     {
   4132   1.1     skrll     case R_386_IRELATIVE:
   4133   1.1     skrll       return reloc_class_ifunc;
   4134   1.1     skrll     case R_386_RELATIVE:
   4135   1.1     skrll       return reloc_class_relative;
   4136   1.1     skrll     case R_386_JUMP_SLOT:
   4137   1.1     skrll       return reloc_class_plt;
   4138   1.1     skrll     case R_386_COPY:
   4139   1.1     skrll       return reloc_class_copy;
   4140   1.1     skrll     default:
   4141   1.1     skrll       return reloc_class_normal;
   4142   1.1     skrll     }
   4143   1.1     skrll }
   4144  1.13  christos 
   4145   1.1     skrll /* Finish up the dynamic sections.  */
   4146  1.17  christos 
   4147  1.17  christos static bool
   4148   1.1     skrll elf_i386_finish_dynamic_sections (bfd *output_bfd,
   4149  1.10  christos 				  struct bfd_link_info *info,
   4150   1.1     skrll 				  bfd_byte *buf)
   4151  1.17  christos {
   4152   1.4  christos   struct elf_x86_link_hash_table *htab;
   4153  1.13  christos 
   4154   1.4  christos   htab = _bfd_x86_elf_finish_dynamic_sections (output_bfd, info, buf);
   4155  1.10  christos   if (htab == NULL)
   4156  1.13  christos     return false;
   4157   1.1     skrll 
   4158  1.10  christos   if (!htab->elf.dynamic_sections_created)
   4159   1.1     skrll     return true;
   4160  1.13  christos 
   4161  1.13  christos   if (htab->elf.splt && htab->elf.splt->size > 0)
   4162  1.16  christos     {
   4163  1.16  christos       if (bfd_is_abs_section (htab->elf.splt->output_section))
   4164  1.13  christos 	{
   4165  1.13  christos 	  info->callbacks->fatal
   4166  1.13  christos 	    (_("%P: discarded output section: `%pA'\n"),
   4167  1.13  christos 	     htab->elf.splt);
   4168  1.10  christos 	  return false;
   4169  1.10  christos 	}
   4170  1.10  christos 
   4171  1.10  christos       /* UnixWare sets the entsize of .plt to 4, although that doesn't
   4172   1.1     skrll 	 really seem like the right value.  */
   4173  1.10  christos       elf_section_data (htab->elf.splt->output_section)
   4174   1.1     skrll 	->this_hdr.sh_entsize = 4;
   4175  1.10  christos 
   4176  1.10  christos       if (htab->plt.has_plt0)
   4177  1.10  christos 	{
   4178  1.10  christos 	  /* Fill in the special first entry in the procedure linkage
   4179  1.10  christos 	     table.  */
   4180  1.10  christos 	  memcpy (htab->elf.splt->contents, htab->plt.plt0_entry,
   4181  1.10  christos 		  htab->lazy_plt->plt0_entry_size);
   4182  1.10  christos 	  memset (htab->elf.splt->contents + htab->lazy_plt->plt0_entry_size,
   4183   1.1     skrll 		  htab->plt0_pad_byte,
   4184   1.1     skrll 		  htab->plt.plt_entry_size - htab->lazy_plt->plt0_entry_size);
   4185   1.4  christos 	  if (!bfd_link_pic (info))
   4186   1.4  christos 	    {
   4187   1.1     skrll 	      bfd_put_32 (output_bfd,
   4188   1.5  christos 			  (htab->elf.sgotplt->output_section->vma
   4189  1.10  christos 			   + htab->elf.sgotplt->output_offset
   4190   1.1     skrll 			   + 4),
   4191   1.4  christos 			  htab->elf.splt->contents
   4192   1.4  christos 			  + htab->lazy_plt->plt0_got1_offset);
   4193   1.1     skrll 	      bfd_put_32 (output_bfd,
   4194   1.5  christos 			  (htab->elf.sgotplt->output_section->vma
   4195  1.10  christos 			   + htab->elf.sgotplt->output_offset
   4196   1.1     skrll 			   + 8),
   4197  1.13  christos 			  htab->elf.splt->contents
   4198   1.1     skrll 			  + htab->lazy_plt->plt0_got2_offset);
   4199   1.1     skrll 
   4200  1.10  christos 	      if (htab->elf.target_os == is_vxworks)
   4201  1.10  christos 		{
   4202  1.10  christos 		  Elf_Internal_Rela rel;
   4203  1.10  christos 		  int num_plts = (htab->elf.splt->size
   4204  1.10  christos 				  / htab->plt.plt_entry_size) - 1;
   4205  1.10  christos 		  unsigned char *p;
   4206  1.10  christos 		  asection *srelplt2 = htab->srelplt2;
   4207  1.10  christos 
   4208   1.4  christos 		  /* Generate a relocation for _GLOBAL_OFFSET_TABLE_
   4209   1.4  christos 		     + 4.  On IA32 we use REL relocations so the
   4210  1.10  christos 		     addend goes in the PLT directly.  */
   4211  1.10  christos 		  rel.r_offset = (htab->elf.splt->output_section->vma
   4212  1.10  christos 				  + htab->elf.splt->output_offset
   4213   1.1     skrll 				  + htab->lazy_plt->plt0_got1_offset);
   4214  1.10  christos 		  rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
   4215  1.10  christos 					     R_386_32);
   4216  1.10  christos 		  bfd_elf32_swap_reloc_out (output_bfd, &rel,
   4217   1.4  christos 					    srelplt2->contents);
   4218   1.4  christos 		  /* Generate a relocation for _GLOBAL_OFFSET_TABLE_
   4219  1.10  christos 		     + 8.  */
   4220  1.10  christos 		  rel.r_offset = (htab->elf.splt->output_section->vma
   4221  1.10  christos 				  + htab->elf.splt->output_offset
   4222   1.1     skrll 				  + htab->lazy_plt->plt0_got2_offset);
   4223  1.10  christos 		  rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
   4224   1.1     skrll 					     R_386_32);
   4225  1.10  christos 		  bfd_elf32_swap_reloc_out (output_bfd, &rel,
   4226  1.10  christos 					    srelplt2->contents +
   4227  1.10  christos 					    sizeof (Elf32_External_Rel));
   4228  1.10  christos 		  /* Correct the .rel.plt.unloaded relocations.  */
   4229  1.10  christos 		  p = srelplt2->contents;
   4230  1.10  christos 		  if (bfd_link_pic (info))
   4231   1.1     skrll 		    p += PLTRESOLVE_RELOCS_SHLIB * sizeof (Elf32_External_Rel);
   4232  1.10  christos 		  else
   4233  1.10  christos 		    p += PLTRESOLVE_RELOCS * sizeof (Elf32_External_Rel);
   4234  1.10  christos 
   4235  1.10  christos 		  for (; num_plts; num_plts--)
   4236  1.10  christos 		    {
   4237  1.10  christos 		      bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
   4238  1.10  christos 		      rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
   4239  1.10  christos 						 R_386_32);
   4240  1.10  christos 		      bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
   4241  1.10  christos 		      p += sizeof (Elf32_External_Rel);
   4242  1.10  christos 
   4243  1.10  christos 		      bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
   4244  1.10  christos 		      rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx,
   4245  1.10  christos 						 R_386_32);
   4246   1.1     skrll 		      bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
   4247   1.1     skrll 		      p += sizeof (Elf32_External_Rel);
   4248   1.1     skrll 		    }
   4249   1.1     skrll 		}
   4250   1.1     skrll 	    }
   4251   1.9  christos 	}
   4252   1.9  christos     }
   4253   1.9  christos 
   4254   1.9  christos   /* Fill PLT entries for undefined weak symbols in PIE.  */
   4255   1.9  christos   if (bfd_link_pie (info))
   4256   1.9  christos     bfd_hash_traverse (&info->hash->table,
   4257  1.13  christos 		       elf_i386_pie_finish_undefweak_symbol,
   4258   1.9  christos 		       info);
   4259   1.9  christos 
   4260   1.9  christos   return true;
   4261   1.9  christos }
   4262   1.9  christos 
   4263   1.9  christos /* Fill PLT/GOT entries and allocate dynamic relocations for local
   4264   1.9  christos    STT_GNU_IFUNC symbols, which aren't in the ELF linker hash table.
   4265  1.13  christos    It has to be done before elf_link_sort_relocs is called so that
   4266   1.9  christos    dynamic relocations are properly sorted.  */
   4267   1.9  christos 
   4268   1.9  christos static bool
   4269   1.9  christos elf_i386_output_arch_local_syms
   4270   1.9  christos   (bfd *output_bfd ATTRIBUTE_UNUSED,
   4271   1.9  christos    struct bfd_link_info *info,
   4272   1.9  christos    void *flaginfo ATTRIBUTE_UNUSED,
   4273   1.9  christos    int (*func) (void *, const char *,
   4274   1.9  christos 		Elf_Internal_Sym *,
   4275  1.10  christos 		asection *,
   4276  1.10  christos 		struct elf_link_hash_entry *) ATTRIBUTE_UNUSED)
   4277   1.9  christos {
   4278  1.13  christos   struct elf_x86_link_hash_table *htab
   4279   1.9  christos     = elf_x86_hash_table (info, I386_ELF_DATA);
   4280  1.17  christos   if (htab == NULL)
   4281  1.17  christos     return false;
   4282  1.17  christos 
   4283  1.17  christos   /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols if
   4284  1.17  christos      needed.  */
   4285  1.17  christos   if (htab->has_loc_hash_table)
   4286   1.1     skrll     htab_traverse (htab->loc_hash_table,
   4287  1.13  christos 		   elf_i386_finish_local_dynamic_symbol,
   4288   1.1     skrll 		   info);
   4289   1.1     skrll 
   4290  1.10  christos   return true;
   4291  1.10  christos }
   4292  1.10  christos 
   4293  1.10  christos /* Similar to _bfd_elf_get_synthetic_symtab.  Support PLTs with all
   4294  1.10  christos    dynamic relocations.   */
   4295  1.10  christos 
   4296  1.10  christos static long
   4297  1.10  christos elf_i386_get_synthetic_symtab (bfd *abfd,
   4298  1.10  christos 			       long symcount ATTRIBUTE_UNUSED,
   4299  1.10  christos 			       asymbol **syms ATTRIBUTE_UNUSED,
   4300  1.10  christos 			       long dynsymcount,
   4301  1.10  christos 			       asymbol **dynsyms,
   4302  1.10  christos 			       asymbol **ret)
   4303   1.6  christos {
   4304  1.10  christos   long count, i, n;
   4305  1.10  christos   int j;
   4306  1.10  christos   bfd_byte *plt_contents;
   4307  1.10  christos   long relsize;
   4308  1.10  christos   const struct elf_x86_lazy_plt_layout *lazy_plt;
   4309  1.10  christos   const struct elf_x86_non_lazy_plt_layout *non_lazy_plt;
   4310  1.10  christos   const struct elf_x86_lazy_plt_layout *lazy_ibt_plt;
   4311  1.10  christos   const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt;
   4312  1.10  christos   asection *plt;
   4313  1.10  christos   bfd_vma got_addr;
   4314  1.10  christos   enum elf_x86_plt_type plt_type;
   4315  1.10  christos   struct elf_x86_plt plts[] =
   4316  1.10  christos     {
   4317  1.10  christos       { ".plt", NULL, NULL, plt_unknown, 0, 0, 0, 0 },
   4318  1.10  christos       { ".plt.got", NULL, NULL, plt_non_lazy, 0, 0, 0, 0 },
   4319  1.10  christos       { ".plt.sec", NULL, NULL, plt_second, 0, 0, 0, 0 },
   4320  1.10  christos       { NULL, NULL, NULL, plt_non_lazy, 0, 0, 0, 0 }
   4321  1.10  christos     };
   4322  1.10  christos 
   4323  1.10  christos   *ret = NULL;
   4324  1.10  christos 
   4325  1.10  christos   if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
   4326  1.10  christos     return 0;
   4327  1.10  christos 
   4328  1.10  christos   if (dynsymcount <= 0)
   4329  1.10  christos     return 0;
   4330  1.10  christos 
   4331  1.10  christos   relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
   4332  1.10  christos   if (relsize <= 0)
   4333  1.10  christos     return -1;
   4334  1.10  christos 
   4335  1.10  christos   non_lazy_plt = NULL;
   4336  1.10  christos   /* Silence GCC 6.  */
   4337  1.13  christos   lazy_plt = NULL;
   4338  1.10  christos   non_lazy_ibt_plt = NULL;
   4339  1.10  christos   lazy_ibt_plt = NULL;
   4340  1.11  christos   switch (get_elf_backend_data (abfd)->target_os)
   4341  1.10  christos     {
   4342  1.10  christos     case is_normal:
   4343  1.10  christos     case is_solaris:
   4344  1.10  christos       non_lazy_plt = &elf_i386_non_lazy_plt;
   4345  1.10  christos       lazy_ibt_plt = &elf_i386_lazy_ibt_plt;
   4346  1.10  christos       non_lazy_ibt_plt = &elf_i386_non_lazy_ibt_plt;
   4347  1.10  christos       /* Fall through */
   4348  1.13  christos     case is_vxworks:
   4349  1.13  christos       lazy_plt = &elf_i386_lazy_plt;
   4350   1.6  christos       break;
   4351   1.6  christos     default:
   4352  1.10  christos       abort ();
   4353  1.10  christos     }
   4354  1.10  christos 
   4355  1.10  christos   got_addr = 0;
   4356   1.6  christos 
   4357  1.10  christos   count = 0;
   4358  1.10  christos   for (j = 0; plts[j].name != NULL; j++)
   4359  1.10  christos     {
   4360  1.10  christos       plt = bfd_get_section_by_name (abfd, plts[j].name);
   4361  1.10  christos       if (plt == NULL || plt->size == 0)
   4362  1.10  christos 	continue;
   4363  1.10  christos 
   4364  1.10  christos       /* Get the PLT section contents.  */
   4365  1.10  christos       plt_contents = (bfd_byte *) bfd_malloc (plt->size);
   4366  1.10  christos       if (plt_contents == NULL)
   4367  1.10  christos 	break;
   4368  1.10  christos       if (!bfd_get_section_contents (abfd, (asection *) plt,
   4369  1.10  christos 				     plt_contents, 0, plt->size))
   4370  1.10  christos 	{
   4371   1.6  christos 	  free (plt_contents);
   4372  1.10  christos 	  break;
   4373  1.10  christos 	}
   4374  1.10  christos 
   4375  1.10  christos       /* Check what kind of PLT it is.  */
   4376  1.10  christos       plt_type = plt_unknown;
   4377  1.10  christos       if (plts[j].type == plt_unknown
   4378  1.10  christos 	  && (plt->size >= (lazy_plt->plt0_entry_size
   4379  1.10  christos 			    + lazy_plt->plt_entry_size)))
   4380  1.10  christos 	{
   4381  1.10  christos 	  /* Match lazy PLT first.  */
   4382  1.10  christos 	  if (memcmp (plt_contents, lazy_plt->plt0_entry,
   4383  1.10  christos 		      lazy_plt->plt0_got1_offset) == 0)
   4384  1.10  christos 	    {
   4385  1.10  christos 	      /* The fist entry in the lazy IBT PLT is the same as the
   4386  1.10  christos 		 normal lazy PLT.  */
   4387  1.17  christos 	      if (lazy_ibt_plt != NULL
   4388  1.10  christos 		  && (memcmp (plt_contents + lazy_ibt_plt->plt0_entry_size,
   4389  1.10  christos 			      lazy_ibt_plt->plt_entry,
   4390  1.10  christos 			      lazy_ibt_plt->plt_reloc_offset) == 0))
   4391  1.10  christos 		plt_type = plt_lazy | plt_second;
   4392  1.10  christos 	      else
   4393  1.10  christos 		plt_type = plt_lazy;
   4394  1.10  christos 	    }
   4395  1.10  christos 	  else if (memcmp (plt_contents, lazy_plt->pic_plt0_entry,
   4396  1.10  christos 			   lazy_plt->plt0_got1_offset) == 0)
   4397  1.10  christos 	    {
   4398  1.10  christos 	      /* The fist entry in the PIC lazy IBT PLT is the same as
   4399  1.10  christos 		 the normal PIC lazy PLT.  */
   4400  1.17  christos 	      if (lazy_ibt_plt != NULL
   4401  1.10  christos 		  && (memcmp (plt_contents + lazy_ibt_plt->plt0_entry_size,
   4402  1.10  christos 			      lazy_ibt_plt->pic_plt_entry,
   4403  1.10  christos 			      lazy_ibt_plt->plt_reloc_offset) == 0))
   4404  1.10  christos 		plt_type = plt_lazy | plt_pic | plt_second;
   4405  1.10  christos 	      else
   4406  1.10  christos 		plt_type = plt_lazy | plt_pic;
   4407  1.10  christos 	    }
   4408  1.10  christos 	}
   4409  1.10  christos 
   4410  1.10  christos       if (non_lazy_plt != NULL
   4411  1.10  christos 	  && (plt_type == plt_unknown || plt_type == plt_non_lazy)
   4412  1.10  christos 	  && plt->size >= non_lazy_plt->plt_entry_size)
   4413  1.10  christos 	{
   4414  1.10  christos 	  /* Match non-lazy PLT.  */
   4415  1.10  christos 	  if (memcmp (plt_contents, non_lazy_plt->plt_entry,
   4416  1.10  christos 		      non_lazy_plt->plt_got_offset) == 0)
   4417  1.10  christos 	    plt_type = plt_non_lazy;
   4418  1.10  christos 	  else if (memcmp (plt_contents, non_lazy_plt->pic_plt_entry,
   4419  1.10  christos 			   non_lazy_plt->plt_got_offset) == 0)
   4420  1.10  christos 	    plt_type = plt_pic;
   4421  1.10  christos 	}
   4422  1.10  christos 
   4423  1.10  christos       if ((non_lazy_ibt_plt != NULL)
   4424  1.10  christos 	  && (plt_type == plt_unknown || plt_type == plt_second)
   4425  1.10  christos 	  && plt->size >= non_lazy_ibt_plt->plt_entry_size)
   4426  1.10  christos 	{
   4427  1.10  christos 	  if (memcmp (plt_contents,
   4428  1.10  christos 		      non_lazy_ibt_plt->plt_entry,
   4429  1.10  christos 		      non_lazy_ibt_plt->plt_got_offset) == 0)
   4430  1.10  christos 	    {
   4431  1.10  christos 	      /* Match IBT PLT.  */
   4432  1.10  christos 	      plt_type = plt_second;
   4433  1.10  christos 	      non_lazy_plt = non_lazy_ibt_plt;
   4434  1.10  christos 	    }
   4435  1.10  christos 	  else if (memcmp (plt_contents,
   4436  1.10  christos 			   non_lazy_ibt_plt->pic_plt_entry,
   4437  1.10  christos 			   non_lazy_ibt_plt->plt_got_offset) == 0)
   4438  1.10  christos 	    {
   4439  1.10  christos 	      /* Match PIC IBT PLT.  */
   4440  1.10  christos 	      plt_type = plt_second | plt_pic;
   4441  1.10  christos 	      non_lazy_plt = non_lazy_ibt_plt;
   4442  1.10  christos 	    }
   4443  1.10  christos 	}
   4444  1.10  christos 
   4445  1.10  christos       if (plt_type == plt_unknown)
   4446  1.10  christos 	{
   4447  1.10  christos 	  free (plt_contents);
   4448  1.10  christos 	  continue;
   4449  1.10  christos 	}
   4450  1.10  christos 
   4451  1.10  christos       plts[j].sec = plt;
   4452  1.10  christos       plts[j].type = plt_type;
   4453  1.10  christos 
   4454  1.10  christos       if ((plt_type & plt_lazy))
   4455  1.10  christos 	{
   4456  1.10  christos 	  plts[j].plt_got_offset = lazy_plt->plt_got_offset;
   4457  1.10  christos 	  plts[j].plt_entry_size = lazy_plt->plt_entry_size;
   4458  1.10  christos 	  /* Skip PLT0 in lazy PLT.  */
   4459  1.10  christos 	  i = 1;
   4460  1.10  christos 	}
   4461  1.10  christos       else
   4462  1.10  christos 	{
   4463  1.10  christos 	  plts[j].plt_got_offset = non_lazy_plt->plt_got_offset;
   4464  1.10  christos 	  plts[j].plt_entry_size = non_lazy_plt->plt_entry_size;
   4465  1.10  christos 	  i = 0;
   4466  1.10  christos 	}
   4467  1.10  christos 
   4468  1.10  christos       /* Skip lazy PLT when the second PLT is used.  */
   4469  1.10  christos       if ((plt_type & (plt_lazy | plt_second))
   4470  1.10  christos 	  == (plt_lazy | plt_second))
   4471  1.10  christos 	plts[j].count = 0;
   4472  1.10  christos       else
   4473  1.10  christos 	{
   4474  1.10  christos 	  n = plt->size / plts[j].plt_entry_size;
   4475   1.6  christos 	  plts[j].count = n;
   4476  1.10  christos 	  count += n - i;
   4477   1.6  christos 	}
   4478  1.10  christos 
   4479  1.10  christos       plts[j].contents = plt_contents;
   4480  1.10  christos 
   4481   1.6  christos       /* The _GLOBAL_OFFSET_TABLE_ address is needed.  */
   4482   1.6  christos       if ((plt_type & plt_pic))
   4483  1.10  christos 	got_addr = (bfd_vma) -1;
   4484  1.10  christos     }
   4485  1.10  christos 
   4486   1.6  christos   return _bfd_x86_elf_get_synthetic_symtab (abfd, count, relsize,
   4487   1.6  christos 					    got_addr, plts, dynsyms,
   4488  1.10  christos 					    ret);
   4489  1.10  christos }
   4490   1.1     skrll 
   4491  1.10  christos /* Set up i386 GNU properties.  Return the first relocatable ELF input
   4492  1.10  christos    with GNU properties if found.  Otherwise, return NULL.  */
   4493   1.6  christos 
   4494  1.10  christos static bfd *
   4495   1.1     skrll elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
   4496  1.13  christos {
   4497  1.10  christos   struct elf_x86_init_table init_table;
   4498  1.10  christos 
   4499  1.11  christos   switch (get_elf_backend_data (info->output_bfd)->target_os)
   4500  1.10  christos     {
   4501  1.10  christos     case is_normal:
   4502  1.10  christos     case is_solaris:
   4503  1.10  christos       init_table.plt0_pad_byte = 0x0;
   4504  1.10  christos       init_table.lazy_plt = &elf_i386_lazy_plt;
   4505  1.10  christos       init_table.non_lazy_plt = &elf_i386_non_lazy_plt;
   4506  1.10  christos       init_table.lazy_ibt_plt = &elf_i386_lazy_ibt_plt;
   4507  1.10  christos       init_table.non_lazy_ibt_plt = &elf_i386_non_lazy_ibt_plt;
   4508  1.10  christos       break;
   4509  1.10  christos     case is_vxworks:
   4510  1.10  christos       init_table.plt0_pad_byte = 0x90;
   4511  1.10  christos       init_table.lazy_plt = &elf_i386_lazy_plt;
   4512  1.10  christos       init_table.non_lazy_plt = NULL;
   4513  1.13  christos       init_table.lazy_ibt_plt = NULL;
   4514  1.13  christos       init_table.non_lazy_ibt_plt = NULL;
   4515  1.10  christos       break;
   4516   1.1     skrll     default:
   4517  1.10  christos       abort ();
   4518  1.10  christos     }
   4519   1.1     skrll 
   4520  1.10  christos   init_table.r_info = elf32_r_info;
   4521   1.1     skrll   init_table.r_sym = elf32_r_sym;
   4522   1.1     skrll 
   4523  1.17  christos   return _bfd_x86_elf_link_setup_gnu_properties (info, &init_table);
   4524  1.17  christos }
   4525  1.17  christos 
   4526  1.17  christos static void
   4527  1.17  christos elf_i386_add_glibc_version_dependency
   4528  1.17  christos   (struct elf_find_verdep_info *rinfo)
   4529  1.17  christos {
   4530  1.17  christos   int i = 0;
   4531  1.17  christos   const char *version[4] = { NULL, NULL, NULL, NULL };
   4532  1.17  christos   bool auto_version[4] = { false, false, false, false };
   4533  1.17  christos   struct elf_x86_link_hash_table *htab;
   4534  1.17  christos 
   4535  1.17  christos   if (rinfo->info->enable_dt_relr)
   4536  1.17  christos     {
   4537  1.17  christos       version[i] = "GLIBC_ABI_DT_RELR";
   4538  1.17  christos       i++;
   4539  1.17  christos     }
   4540  1.17  christos 
   4541  1.17  christos   htab = elf_x86_hash_table (rinfo->info, I386_ELF_DATA);
   4542  1.17  christos   if (htab != NULL)
   4543  1.17  christos     {
   4544  1.17  christos       if (htab->params->gnu2_tls_version_tag && htab->has_tls_desc_call)
   4545  1.17  christos 	{
   4546  1.17  christos 	  version[i] = "GLIBC_ABI_GNU2_TLS";
   4547  1.17  christos 	  /* 2 == auto, enable if libc.so defines the GLIBC_ABI_GNU2_TLS
   4548  1.17  christos 	     version.  */
   4549  1.17  christos 	  if (htab->params->gnu2_tls_version_tag == 2)
   4550  1.17  christos 	    auto_version[i] = true;
   4551  1.17  christos 	  i++;
   4552  1.17  christos 	}
   4553  1.17  christos       if (htab->params->gnu_tls_version_tag
   4554  1.17  christos 	  && htab->has_tls_get_addr_call)
   4555  1.17  christos 	{
   4556  1.17  christos 	  version[i] = "GLIBC_ABI_GNU_TLS";
   4557  1.17  christos 	  /* 2 == auto, enable if libc.so defines the GLIBC_ABI_GNU_TLS
   4558  1.17  christos 	     version.  */
   4559  1.17  christos 	  if (htab->params->gnu_tls_version_tag == 2)
   4560  1.17  christos 	    auto_version[i] = true;
   4561  1.17  christos 	  i++;
   4562  1.17  christos 	}
   4563  1.17  christos     }
   4564  1.17  christos 
   4565  1.17  christos   if (i != 0)
   4566  1.17  christos     _bfd_elf_link_add_glibc_version_dependency (rinfo, version,
   4567   1.6  christos 						auto_version);
   4568   1.1     skrll }
   4569   1.1     skrll 
   4570   1.4  christos #define TARGET_LITTLE_SYM		i386_elf32_vec
   4571   1.1     skrll #define TARGET_LITTLE_NAME		"elf32-i386"
   4572   1.1     skrll #define ELF_ARCH			bfd_arch_i386
   4573  1.17  christos #define ELF_TARGET_ID			I386_ELF_DATA
   4574   1.1     skrll #define ELF_MACHINE_CODE		EM_386
   4575   1.1     skrll #define ELF_MAXPAGESIZE			0x1000
   4576   1.1     skrll #define	ELF_OSABI			ELFOSABI_GNU
   4577   1.1     skrll 
   4578   1.1     skrll #define elf_backend_can_gc_sections	1
   4579   1.1     skrll #define elf_backend_can_refcount	1
   4580   1.1     skrll #define elf_backend_want_got_plt	1
   4581   1.5  christos #define elf_backend_plt_readonly	1
   4582  1.10  christos #define elf_backend_want_plt_sym	0
   4583   1.9  christos #define elf_backend_got_header_size	12
   4584  1.10  christos #define elf_backend_plt_alignment	4
   4585   1.1     skrll #define elf_backend_dtrel_excludes_plt	1
   4586   1.1     skrll #define elf_backend_caches_rawsize	1
   4587   1.1     skrll #define elf_backend_want_dynrelro	1
   4588   1.1     skrll 
   4589   1.1     skrll /* Support RELA for objdump of prelink objects.  */
   4590   1.1     skrll #define elf_info_to_howto		      elf_i386_info_to_howto_rel
   4591   1.1     skrll #define elf_info_to_howto_rel		      elf_i386_info_to_howto_rel
   4592   1.1     skrll 
   4593   1.6  christos #define bfd_elf32_bfd_is_local_label_name     elf_i386_is_local_label_name
   4594   1.1     skrll #define bfd_elf32_bfd_reloc_type_lookup	      elf_i386_reloc_type_lookup
   4595   1.1     skrll #define bfd_elf32_bfd_reloc_name_lookup	      elf_i386_reloc_name_lookup
   4596  1.16  christos #define bfd_elf32_get_synthetic_symtab	      elf_i386_get_synthetic_symtab
   4597  1.10  christos 
   4598   1.1     skrll #define elf_backend_relocs_compatible	      _bfd_elf_relocs_compatible
   4599   1.1     skrll #define elf_backend_early_size_sections	      elf_i386_early_size_sections
   4600   1.1     skrll #define elf_backend_create_dynamic_sections   _bfd_elf_create_dynamic_sections
   4601   1.9  christos #define elf_backend_fake_sections	      elf_i386_fake_sections
   4602   1.1     skrll #define elf_backend_finish_dynamic_sections   elf_i386_finish_dynamic_sections
   4603   1.1     skrll #define elf_backend_finish_dynamic_symbol     elf_i386_finish_dynamic_symbol
   4604   1.1     skrll #define elf_backend_output_arch_local_syms     elf_i386_output_arch_local_syms
   4605   1.1     skrll #define elf_backend_grok_prstatus	      elf_i386_grok_prstatus
   4606  1.10  christos #define elf_backend_grok_psinfo		      elf_i386_grok_psinfo
   4607  1.10  christos #define elf_backend_reloc_type_class	      elf_i386_reloc_type_class
   4608  1.17  christos #define elf_backend_relocate_section	      elf_i386_relocate_section
   4609  1.17  christos #define elf_backend_setup_gnu_properties      elf_i386_link_setup_gnu_properties
   4610  1.10  christos #define elf_backend_hide_symbol		      _bfd_x86_elf_hide_symbol
   4611  1.13  christos #define elf_backend_add_glibc_version_dependency \
   4612   1.1     skrll   elf_i386_add_glibc_version_dependency
   4613  1.11  christos 
   4614  1.11  christos #define elf_backend_linux_prpsinfo32_ugid16	true
   4615   1.1     skrll 
   4616   1.1     skrll #define	elf32_bed			      elf32_i386_bed
   4617  1.17  christos 
   4618  1.17  christos #include "elf32-target.h"
   4619   1.1     skrll 
   4620   1.1     skrll #undef elf_backend_add_glibc_version_dependency
   4621   1.1     skrll 
   4622   1.6  christos /* FreeBSD support.  */
   4623   1.1     skrll 
   4624   1.1     skrll #undef	TARGET_LITTLE_SYM
   4625   1.1     skrll #define	TARGET_LITTLE_SYM		i386_elf32_fbsd_vec
   4626   1.1     skrll #undef	TARGET_LITTLE_NAME
   4627  1.17  christos #define	TARGET_LITTLE_NAME		"elf32-i386-freebsd"
   4628  1.17  christos #undef	ELF_OSABI
   4629   1.1     skrll #define	ELF_OSABI			ELFOSABI_FREEBSD
   4630   1.1     skrll #undef	ELF_OSABI_EXACT
   4631   1.1     skrll #define	ELF_OSABI_EXACT			1
   4632   1.1     skrll 
   4633   1.1     skrll /* The kernel recognizes executables as valid only if they carry a
   4634  1.13  christos    "FreeBSD" label in the ELF header.  So we put this label on all
   4635  1.12  christos    executables and (for simplicity) also all other object files.  */
   4636   1.1     skrll 
   4637  1.12  christos static bool
   4638  1.13  christos elf_i386_fbsd_init_file_header (bfd *abfd, struct bfd_link_info *info)
   4639   1.1     skrll {
   4640   1.1     skrll   if (!_bfd_elf_init_file_header (abfd, info))
   4641   1.6  christos     return false;
   4642   1.6  christos 
   4643   1.6  christos #ifdef OLD_FREEBSD_ABI_LABEL
   4644   1.6  christos   {
   4645   1.6  christos     /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard.  */
   4646   1.1     skrll     Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
   4647  1.13  christos     memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
   4648   1.1     skrll   }
   4649   1.1     skrll #endif
   4650  1.12  christos   return true;
   4651  1.12  christos }
   4652   1.1     skrll 
   4653   1.1     skrll #undef	elf_backend_init_file_header
   4654   1.1     skrll #define	elf_backend_init_file_header	elf_i386_fbsd_init_file_header
   4655   1.4  christos #undef	elf32_bed
   4656   1.4  christos #define	elf32_bed				elf32_i386_fbsd_bed
   4657   1.4  christos 
   4658   1.4  christos #undef elf_backend_add_symbol_hook
   4659  1.12  christos 
   4660  1.12  christos #include "elf32-target.h"
   4661   1.4  christos 
   4662   1.4  christos #undef elf_backend_init_file_header
   4663   1.4  christos 
   4664   1.6  christos /* Solaris 2.  */
   4665   1.4  christos 
   4666   1.4  christos #undef	TARGET_LITTLE_SYM
   4667   1.4  christos #define	TARGET_LITTLE_SYM		i386_elf32_sol2_vec
   4668  1.17  christos #undef	TARGET_LITTLE_NAME
   4669  1.17  christos #define	TARGET_LITTLE_NAME		"elf32-i386-sol2"
   4670  1.17  christos 
   4671  1.13  christos #undef	ELF_MAXPAGESIZE
   4672  1.13  christos #define ELF_MAXPAGESIZE			0x10000
   4673  1.11  christos 
   4674   1.4  christos #undef	ELF_TARGET_OS
   4675  1.17  christos #define	ELF_TARGET_OS			is_solaris
   4676  1.17  christos 
   4677   1.4  christos #undef ELF_OSABI
   4678   1.4  christos #define ELF_OSABI			ELFOSABI_SOLARIS
   4679   1.4  christos #undef ELF_OSABI_EXACT
   4680   1.4  christos 
   4681   1.4  christos #undef	elf32_bed
   4682   1.4  christos #define	elf32_bed			elf32_i386_sol2_bed
   4683   1.9  christos 
   4684   1.4  christos /* The 32-bit static TLS arena size is rounded to the nearest 8-byte
   4685   1.4  christos    boundary.  */
   4686   1.4  christos #undef  elf_backend_static_tls_alignment
   4687   1.4  christos #define elf_backend_static_tls_alignment 8
   4688   1.4  christos 
   4689   1.4  christos /* The Solaris 2 ABI requires a plt symbol on all platforms.
   4690   1.9  christos 
   4691   1.4  christos    Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
   4692   1.4  christos    File, p.63.  */
   4693   1.1     skrll #undef  elf_backend_want_plt_sym
   4694   1.1     skrll #define elf_backend_want_plt_sym	1
   4695   1.6  christos 
   4696   1.6  christos #include "elf32-target.h"
   4697  1.13  christos 
   4698   1.6  christos /* Intel MCU support.  */
   4699   1.6  christos 
   4700   1.6  christos static bool
   4701   1.6  christos elf32_iamcu_elf_object_p (bfd *abfd)
   4702  1.13  christos {
   4703   1.6  christos   /* Set the right machine number for an IAMCU elf32 file.  */
   4704   1.6  christos   bfd_default_set_arch_mach (abfd, bfd_arch_iamcu, bfd_mach_i386_iamcu);
   4705   1.6  christos   return true;
   4706   1.6  christos }
   4707   1.6  christos 
   4708   1.6  christos #undef  TARGET_LITTLE_SYM
   4709   1.9  christos #define TARGET_LITTLE_SYM		iamcu_elf32_vec
   4710   1.6  christos #undef  TARGET_LITTLE_NAME
   4711   1.6  christos #define TARGET_LITTLE_NAME		"elf32-iamcu"
   4712   1.6  christos #undef  ELF_ARCH
   4713   1.6  christos #define ELF_ARCH			bfd_arch_iamcu
   4714   1.6  christos 
   4715  1.17  christos #undef	ELF_MACHINE_CODE
   4716  1.17  christos #define	ELF_MACHINE_CODE		EM_IAMCU
   4717  1.17  christos 
   4718  1.13  christos #undef	ELF_MAXPAGESIZE
   4719   1.6  christos #define ELF_MAXPAGESIZE			0x1000
   4720  1.17  christos 
   4721  1.17  christos #undef	ELF_TARGET_OS
   4722   1.6  christos #undef	ELF_OSABI
   4723   1.6  christos #define	ELF_OSABI			ELFOSABI_GNU
   4724   1.6  christos #undef	ELF_OSABI_EXACT
   4725   1.6  christos 
   4726   1.6  christos #undef  elf32_bed
   4727   1.6  christos #define elf32_bed			elf32_iamcu_bed
   4728   1.6  christos 
   4729   1.6  christos #undef	elf_backend_object_p
   4730   1.6  christos #define elf_backend_object_p		elf32_iamcu_elf_object_p
   4731   1.6  christos 
   4732  1.10  christos #undef	elf_backend_static_tls_alignment
   4733   1.6  christos 
   4734   1.6  christos #undef	elf_backend_want_plt_sym
   4735   1.6  christos #define elf_backend_want_plt_sym	0
   4736   1.6  christos 
   4737   1.6  christos #include "elf32-target.h"
   4738   1.6  christos 
   4739   1.6  christos /* Restore defaults.  */
   4740   1.6  christos #undef	ELF_ARCH
   4741   1.6  christos #define ELF_ARCH			bfd_arch_i386
   4742   1.5  christos #undef	ELF_MACHINE_CODE
   4743   1.1     skrll #define ELF_MACHINE_CODE		EM_386
   4744   1.1     skrll #undef	elf_backend_object_p
   4745   1.1     skrll 
   4746   1.6  christos /* VxWorks support.  */
   4747   1.1     skrll 
   4748   1.1     skrll #undef	TARGET_LITTLE_SYM
   4749  1.10  christos #define TARGET_LITTLE_SYM		i386_elf32_vxworks_vec
   4750  1.10  christos #undef	TARGET_LITTLE_NAME
   4751   1.5  christos #define TARGET_LITTLE_NAME		"elf32-i386-vxworks"
   4752   1.5  christos #undef	ELF_MAXPAGESIZE
   4753   1.1     skrll #define ELF_MAXPAGESIZE			0x1000
   4754  1.13  christos #undef	elf_backend_plt_alignment
   4755  1.13  christos #define elf_backend_plt_alignment	4
   4756  1.17  christos 
   4757  1.17  christos #undef	ELF_TARGET_OS
   4758   1.1     skrll #define ELF_TARGET_OS		is_vxworks
   4759   1.1     skrll #undef	ELF_OSABI
   4760   1.1     skrll #undef	ELF_OSABI_EXACT
   4761   1.1     skrll 
   4762   1.1     skrll #undef elf_backend_relocs_compatible
   4763   1.1     skrll #undef elf_backend_add_symbol_hook
   4764   1.1     skrll #define elf_backend_add_symbol_hook \
   4765   1.1     skrll   elf_vxworks_add_symbol_hook
   4766   1.1     skrll #undef elf_backend_link_output_symbol_hook
   4767   1.1     skrll #define elf_backend_link_output_symbol_hook \
   4768   1.1     skrll   elf_vxworks_link_output_symbol_hook
   4769   1.1     skrll #undef elf_backend_emit_relocs
   4770   1.1     skrll #define elf_backend_emit_relocs			elf_vxworks_emit_relocs
   4771   1.4  christos #undef elf_backend_final_write_processing
   4772   1.1     skrll #define elf_backend_final_write_processing \
   4773   1.1     skrll   elf_vxworks_final_write_processing
   4774   1.1     skrll #undef elf_backend_static_tls_alignment
   4775   1.1     skrll 
   4776   1.1     skrll /* On VxWorks, we emit relocations against _PROCEDURE_LINKAGE_TABLE_, so
   4777   1.1     skrll    define it.  */
   4778   1.1     skrll #undef elf_backend_want_plt_sym
   4779   1.1     skrll #define elf_backend_want_plt_sym	1
   4780   1.1     skrll 
   4781   1.1     skrll #undef	elf32_bed
   4782                 #define elf32_bed				elf32_i386_vxworks_bed
   4783                 
   4784                 #include "elf32-target.h"
   4785