OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [bfd/] [elf64-x86-64.c] - Blame information for rev 826

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* X86-64 specific support for 64-bit ELF
2 225 jeremybenn
   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3 24 jeremybenn
   Free Software Foundation, Inc.
4
   Contributed by Jan Hubicka <jh@suse.cz>.
5
 
6
   This file is part of BFD, the Binary File Descriptor library.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
   MA 02110-1301, USA.  */
22
 
23
#include "sysdep.h"
24
#include "bfd.h"
25
#include "bfdlink.h"
26
#include "libbfd.h"
27
#include "elf-bfd.h"
28
#include "bfd_stdint.h"
29 225 jeremybenn
#include "objalloc.h"
30
#include "hashtab.h"
31 24 jeremybenn
 
32
#include "elf/x86-64.h"
33
 
34
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
35
#define MINUS_ONE (~ (bfd_vma) 0)
36
 
37
/* The relocation "howto" table.  Order of fields:
38
   type, rightshift, size, bitsize, pc_relative, bitpos, complain_on_overflow,
39
   special_function, name, partial_inplace, src_mask, dst_mask, pcrel_offset.  */
40
static reloc_howto_type x86_64_elf_howto_table[] =
41
{
42
  HOWTO(R_X86_64_NONE, 0, 0, 0, FALSE, 0, complain_overflow_dont,
43
        bfd_elf_generic_reloc, "R_X86_64_NONE", FALSE, 0x00000000, 0x00000000,
44
        FALSE),
45
  HOWTO(R_X86_64_64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
46
        bfd_elf_generic_reloc, "R_X86_64_64", FALSE, MINUS_ONE, MINUS_ONE,
47
        FALSE),
48
  HOWTO(R_X86_64_PC32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
49
        bfd_elf_generic_reloc, "R_X86_64_PC32", FALSE, 0xffffffff, 0xffffffff,
50
        TRUE),
51
  HOWTO(R_X86_64_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
52
        bfd_elf_generic_reloc, "R_X86_64_GOT32", FALSE, 0xffffffff, 0xffffffff,
53
        FALSE),
54
  HOWTO(R_X86_64_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
55
        bfd_elf_generic_reloc, "R_X86_64_PLT32", FALSE, 0xffffffff, 0xffffffff,
56
        TRUE),
57
  HOWTO(R_X86_64_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
58
        bfd_elf_generic_reloc, "R_X86_64_COPY", FALSE, 0xffffffff, 0xffffffff,
59
        FALSE),
60
  HOWTO(R_X86_64_GLOB_DAT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
61
        bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", FALSE, MINUS_ONE,
62
        MINUS_ONE, FALSE),
63
  HOWTO(R_X86_64_JUMP_SLOT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
64
        bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", FALSE, MINUS_ONE,
65
        MINUS_ONE, FALSE),
66
  HOWTO(R_X86_64_RELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
67
        bfd_elf_generic_reloc, "R_X86_64_RELATIVE", FALSE, MINUS_ONE,
68
        MINUS_ONE, FALSE),
69
  HOWTO(R_X86_64_GOTPCREL, 0, 2, 32, TRUE, 0, complain_overflow_signed,
70
        bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", FALSE, 0xffffffff,
71
        0xffffffff, TRUE),
72
  HOWTO(R_X86_64_32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned,
73
        bfd_elf_generic_reloc, "R_X86_64_32", FALSE, 0xffffffff, 0xffffffff,
74
        FALSE),
75
  HOWTO(R_X86_64_32S, 0, 2, 32, FALSE, 0, complain_overflow_signed,
76
        bfd_elf_generic_reloc, "R_X86_64_32S", FALSE, 0xffffffff, 0xffffffff,
77
        FALSE),
78
  HOWTO(R_X86_64_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
79
        bfd_elf_generic_reloc, "R_X86_64_16", FALSE, 0xffff, 0xffff, FALSE),
80
  HOWTO(R_X86_64_PC16,0, 1, 16, TRUE, 0, complain_overflow_bitfield,
81
        bfd_elf_generic_reloc, "R_X86_64_PC16", FALSE, 0xffff, 0xffff, TRUE),
82
  HOWTO(R_X86_64_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
83
        bfd_elf_generic_reloc, "R_X86_64_8", FALSE, 0xff, 0xff, FALSE),
84
  HOWTO(R_X86_64_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed,
85
        bfd_elf_generic_reloc, "R_X86_64_PC8", FALSE, 0xff, 0xff, TRUE),
86
  HOWTO(R_X86_64_DTPMOD64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
87
        bfd_elf_generic_reloc, "R_X86_64_DTPMOD64", FALSE, MINUS_ONE,
88
        MINUS_ONE, FALSE),
89
  HOWTO(R_X86_64_DTPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
90
        bfd_elf_generic_reloc, "R_X86_64_DTPOFF64", FALSE, MINUS_ONE,
91
        MINUS_ONE, FALSE),
92
  HOWTO(R_X86_64_TPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
93
        bfd_elf_generic_reloc, "R_X86_64_TPOFF64", FALSE, MINUS_ONE,
94
        MINUS_ONE, FALSE),
95
  HOWTO(R_X86_64_TLSGD, 0, 2, 32, TRUE, 0, complain_overflow_signed,
96
        bfd_elf_generic_reloc, "R_X86_64_TLSGD", FALSE, 0xffffffff,
97
        0xffffffff, TRUE),
98
  HOWTO(R_X86_64_TLSLD, 0, 2, 32, TRUE, 0, complain_overflow_signed,
99
        bfd_elf_generic_reloc, "R_X86_64_TLSLD", FALSE, 0xffffffff,
100
        0xffffffff, TRUE),
101
  HOWTO(R_X86_64_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
102
        bfd_elf_generic_reloc, "R_X86_64_DTPOFF32", FALSE, 0xffffffff,
103
        0xffffffff, FALSE),
104
  HOWTO(R_X86_64_GOTTPOFF, 0, 2, 32, TRUE, 0, complain_overflow_signed,
105
        bfd_elf_generic_reloc, "R_X86_64_GOTTPOFF", FALSE, 0xffffffff,
106
        0xffffffff, TRUE),
107
  HOWTO(R_X86_64_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
108
        bfd_elf_generic_reloc, "R_X86_64_TPOFF32", FALSE, 0xffffffff,
109
        0xffffffff, FALSE),
110
  HOWTO(R_X86_64_PC64, 0, 4, 64, TRUE, 0, complain_overflow_bitfield,
111
        bfd_elf_generic_reloc, "R_X86_64_PC64", FALSE, MINUS_ONE, MINUS_ONE,
112
        TRUE),
113
  HOWTO(R_X86_64_GOTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
114
        bfd_elf_generic_reloc, "R_X86_64_GOTOFF64",
115
        FALSE, MINUS_ONE, MINUS_ONE, FALSE),
116
  HOWTO(R_X86_64_GOTPC32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
117
        bfd_elf_generic_reloc, "R_X86_64_GOTPC32",
118
        FALSE, 0xffffffff, 0xffffffff, TRUE),
119
  HOWTO(R_X86_64_GOT64, 0, 4, 64, FALSE, 0, complain_overflow_signed,
120
        bfd_elf_generic_reloc, "R_X86_64_GOT64", FALSE, MINUS_ONE, MINUS_ONE,
121
        FALSE),
122
  HOWTO(R_X86_64_GOTPCREL64, 0, 4, 64, TRUE, 0, complain_overflow_signed,
123
        bfd_elf_generic_reloc, "R_X86_64_GOTPCREL64", FALSE, MINUS_ONE,
124
        MINUS_ONE, TRUE),
125
  HOWTO(R_X86_64_GOTPC64, 0, 4, 64, TRUE, 0, complain_overflow_signed,
126
        bfd_elf_generic_reloc, "R_X86_64_GOTPC64",
127
        FALSE, MINUS_ONE, MINUS_ONE, TRUE),
128
  HOWTO(R_X86_64_GOTPLT64, 0, 4, 64, FALSE, 0, complain_overflow_signed,
129
        bfd_elf_generic_reloc, "R_X86_64_GOTPLT64", FALSE, MINUS_ONE,
130
        MINUS_ONE, FALSE),
131
  HOWTO(R_X86_64_PLTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_signed,
132
        bfd_elf_generic_reloc, "R_X86_64_PLTOFF64", FALSE, MINUS_ONE,
133
        MINUS_ONE, FALSE),
134
  EMPTY_HOWTO (32),
135
  EMPTY_HOWTO (33),
136
  HOWTO(R_X86_64_GOTPC32_TLSDESC, 0, 2, 32, TRUE, 0,
137
        complain_overflow_bitfield, bfd_elf_generic_reloc,
138
        "R_X86_64_GOTPC32_TLSDESC",
139
        FALSE, 0xffffffff, 0xffffffff, TRUE),
140
  HOWTO(R_X86_64_TLSDESC_CALL, 0, 0, 0, FALSE, 0,
141
        complain_overflow_dont, bfd_elf_generic_reloc,
142
        "R_X86_64_TLSDESC_CALL",
143
        FALSE, 0, 0, FALSE),
144
  HOWTO(R_X86_64_TLSDESC, 0, 4, 64, FALSE, 0,
145
        complain_overflow_bitfield, bfd_elf_generic_reloc,
146
        "R_X86_64_TLSDESC",
147
        FALSE, MINUS_ONE, MINUS_ONE, FALSE),
148 225 jeremybenn
  HOWTO(R_X86_64_IRELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
149
        bfd_elf_generic_reloc, "R_X86_64_IRELATIVE", FALSE, MINUS_ONE,
150
        MINUS_ONE, FALSE),
151 24 jeremybenn
 
152
  /* We have a gap in the reloc numbers here.
153
     R_X86_64_standard counts the number up to this point, and
154
     R_X86_64_vt_offset is the value to subtract from a reloc type of
155
     R_X86_64_GNU_VT* to form an index into this table.  */
156 225 jeremybenn
#define R_X86_64_standard (R_X86_64_IRELATIVE + 1)
157 24 jeremybenn
#define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard)
158
 
159
/* GNU extension to record C++ vtable hierarchy.  */
160
  HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, FALSE, 0, complain_overflow_dont,
161
         NULL, "R_X86_64_GNU_VTINHERIT", FALSE, 0, 0, FALSE),
162
 
163
/* GNU extension to record C++ vtable member usage.  */
164
  HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, FALSE, 0, complain_overflow_dont,
165
         _bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", FALSE, 0, 0,
166
         FALSE)
167
};
168
 
169 225 jeremybenn
#define IS_X86_64_PCREL_TYPE(TYPE)      \
170
  (   ((TYPE) == R_X86_64_PC8)          \
171
   || ((TYPE) == R_X86_64_PC16)         \
172
   || ((TYPE) == R_X86_64_PC32)         \
173
   || ((TYPE) == R_X86_64_PC64))
174
 
175 24 jeremybenn
/* Map BFD relocs to the x86_64 elf relocs.  */
176
struct elf_reloc_map
177
{
178
  bfd_reloc_code_real_type bfd_reloc_val;
179
  unsigned char elf_reloc_val;
180
};
181
 
182
static const struct elf_reloc_map x86_64_reloc_map[] =
183
{
184
  { BFD_RELOC_NONE,             R_X86_64_NONE, },
185
  { BFD_RELOC_64,               R_X86_64_64,   },
186
  { BFD_RELOC_32_PCREL,         R_X86_64_PC32, },
187
  { BFD_RELOC_X86_64_GOT32,     R_X86_64_GOT32,},
188
  { BFD_RELOC_X86_64_PLT32,     R_X86_64_PLT32,},
189
  { BFD_RELOC_X86_64_COPY,      R_X86_64_COPY, },
190
  { BFD_RELOC_X86_64_GLOB_DAT,  R_X86_64_GLOB_DAT, },
191
  { BFD_RELOC_X86_64_JUMP_SLOT, R_X86_64_JUMP_SLOT, },
192
  { BFD_RELOC_X86_64_RELATIVE,  R_X86_64_RELATIVE, },
193
  { BFD_RELOC_X86_64_GOTPCREL,  R_X86_64_GOTPCREL, },
194
  { BFD_RELOC_32,               R_X86_64_32, },
195
  { BFD_RELOC_X86_64_32S,       R_X86_64_32S, },
196
  { BFD_RELOC_16,               R_X86_64_16, },
197
  { BFD_RELOC_16_PCREL,         R_X86_64_PC16, },
198
  { BFD_RELOC_8,                R_X86_64_8, },
199
  { BFD_RELOC_8_PCREL,          R_X86_64_PC8, },
200
  { BFD_RELOC_X86_64_DTPMOD64,  R_X86_64_DTPMOD64, },
201
  { BFD_RELOC_X86_64_DTPOFF64,  R_X86_64_DTPOFF64, },
202
  { BFD_RELOC_X86_64_TPOFF64,   R_X86_64_TPOFF64, },
203
  { BFD_RELOC_X86_64_TLSGD,     R_X86_64_TLSGD, },
204
  { BFD_RELOC_X86_64_TLSLD,     R_X86_64_TLSLD, },
205
  { BFD_RELOC_X86_64_DTPOFF32,  R_X86_64_DTPOFF32, },
206
  { BFD_RELOC_X86_64_GOTTPOFF,  R_X86_64_GOTTPOFF, },
207
  { BFD_RELOC_X86_64_TPOFF32,   R_X86_64_TPOFF32, },
208
  { BFD_RELOC_64_PCREL,         R_X86_64_PC64, },
209
  { BFD_RELOC_X86_64_GOTOFF64,  R_X86_64_GOTOFF64, },
210
  { BFD_RELOC_X86_64_GOTPC32,   R_X86_64_GOTPC32, },
211
  { BFD_RELOC_X86_64_GOT64,     R_X86_64_GOT64, },
212
  { BFD_RELOC_X86_64_GOTPCREL64,R_X86_64_GOTPCREL64, },
213
  { BFD_RELOC_X86_64_GOTPC64,   R_X86_64_GOTPC64, },
214
  { BFD_RELOC_X86_64_GOTPLT64,  R_X86_64_GOTPLT64, },
215
  { BFD_RELOC_X86_64_PLTOFF64,  R_X86_64_PLTOFF64, },
216
  { BFD_RELOC_X86_64_GOTPC32_TLSDESC, R_X86_64_GOTPC32_TLSDESC, },
217
  { BFD_RELOC_X86_64_TLSDESC_CALL, R_X86_64_TLSDESC_CALL, },
218
  { BFD_RELOC_X86_64_TLSDESC,   R_X86_64_TLSDESC, },
219 225 jeremybenn
  { BFD_RELOC_X86_64_IRELATIVE, R_X86_64_IRELATIVE, },
220 24 jeremybenn
  { BFD_RELOC_VTABLE_INHERIT,   R_X86_64_GNU_VTINHERIT, },
221
  { BFD_RELOC_VTABLE_ENTRY,     R_X86_64_GNU_VTENTRY, },
222
};
223
 
224
static reloc_howto_type *
225
elf64_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type)
226
{
227
  unsigned i;
228
 
229
  if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT
230
      || r_type >= (unsigned int) R_X86_64_max)
231
    {
232
      if (r_type >= (unsigned int) R_X86_64_standard)
233
        {
234
          (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
235
                                 abfd, (int) r_type);
236
          r_type = R_X86_64_NONE;
237
        }
238
      i = r_type;
239
    }
240
  else
241
    i = r_type - (unsigned int) R_X86_64_vt_offset;
242
  BFD_ASSERT (x86_64_elf_howto_table[i].type == r_type);
243
  return &x86_64_elf_howto_table[i];
244
}
245
 
246
/* Given a BFD reloc type, return a HOWTO structure.  */
247
static reloc_howto_type *
248
elf64_x86_64_reloc_type_lookup (bfd *abfd,
249
                                bfd_reloc_code_real_type code)
250
{
251
  unsigned int i;
252
 
253
  for (i = 0; i < sizeof (x86_64_reloc_map) / sizeof (struct elf_reloc_map);
254
       i++)
255
    {
256
      if (x86_64_reloc_map[i].bfd_reloc_val == code)
257
        return elf64_x86_64_rtype_to_howto (abfd,
258
                                            x86_64_reloc_map[i].elf_reloc_val);
259
    }
260
  return 0;
261
}
262
 
263
static reloc_howto_type *
264
elf64_x86_64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
265
                                const char *r_name)
266
{
267
  unsigned int i;
268
 
269
  for (i = 0;
270
       i < (sizeof (x86_64_elf_howto_table)
271
            / sizeof (x86_64_elf_howto_table[0]));
272
       i++)
273
    if (x86_64_elf_howto_table[i].name != NULL
274
        && strcasecmp (x86_64_elf_howto_table[i].name, r_name) == 0)
275
      return &x86_64_elf_howto_table[i];
276
 
277
  return NULL;
278
}
279
 
280
/* Given an x86_64 ELF reloc type, fill in an arelent structure.  */
281
 
282
static void
283
elf64_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
284
                            Elf_Internal_Rela *dst)
285
{
286
  unsigned r_type;
287
 
288
  r_type = ELF64_R_TYPE (dst->r_info);
289
  cache_ptr->howto = elf64_x86_64_rtype_to_howto (abfd, r_type);
290
  BFD_ASSERT (r_type == cache_ptr->howto->type);
291
}
292
 
293
/* Support for core dump NOTE sections.  */
294
static bfd_boolean
295
elf64_x86_64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
296
{
297
  int offset;
298
  size_t size;
299
 
300
  switch (note->descsz)
301
    {
302
      default:
303
        return FALSE;
304
 
305
      case 336:         /* sizeof(istruct elf_prstatus) on Linux/x86_64 */
306
        /* pr_cursig */
307
        elf_tdata (abfd)->core_signal
308
          = bfd_get_16 (abfd, note->descdata + 12);
309
 
310
        /* pr_pid */
311
        elf_tdata (abfd)->core_pid
312
          = bfd_get_32 (abfd, note->descdata + 32);
313
 
314
        /* pr_reg */
315
        offset = 112;
316
        size = 216;
317
 
318
        break;
319
    }
320
 
321
  /* Make a ".reg/999" section.  */
322
  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
323
                                          size, note->descpos + offset);
324
}
325
 
326
static bfd_boolean
327
elf64_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
328
{
329
  switch (note->descsz)
330
    {
331
      default:
332
        return FALSE;
333
 
334
      case 136:         /* sizeof(struct elf_prpsinfo) on Linux/x86_64 */
335
        elf_tdata (abfd)->core_program
336
         = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
337
        elf_tdata (abfd)->core_command
338
         = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
339
    }
340
 
341
  /* Note that for some reason, a spurious space is tacked
342
     onto the end of the args in some (at least one anyway)
343
     implementations, so strip it off if it exists.  */
344
 
345
  {
346
    char *command = elf_tdata (abfd)->core_command;
347
    int n = strlen (command);
348
 
349
    if (0 < n && command[n - 1] == ' ')
350
      command[n - 1] = '\0';
351
  }
352
 
353
  return TRUE;
354
}
355
 
356
/* Functions for the x86-64 ELF linker.  */
357
 
358
/* The name of the dynamic interpreter.  This is put in the .interp
359
   section.  */
360
 
361
#define ELF_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
362
 
363
/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
364
   copying dynamic variables from a shared lib into an app's dynbss
365
   section, and instead use a dynamic relocation to point into the
366
   shared lib.  */
367
#define ELIMINATE_COPY_RELOCS 1
368
 
369
/* The size in bytes of an entry in the global offset table.  */
370
 
371
#define GOT_ENTRY_SIZE 8
372
 
373
/* The size in bytes of an entry in the procedure linkage table.  */
374
 
375
#define PLT_ENTRY_SIZE 16
376
 
377
/* The first entry in a procedure linkage table looks like this.  See the
378
   SVR4 ABI i386 supplement and the x86-64 ABI to see how this works.  */
379
 
380
static const bfd_byte elf64_x86_64_plt0_entry[PLT_ENTRY_SIZE] =
381
{
382
  0xff, 0x35, 8, 0, 0, 0,  /* pushq GOT+8(%rip)  */
383
  0xff, 0x25, 16, 0, 0, 0, /* jmpq *GOT+16(%rip) */
384
  0x0f, 0x1f, 0x40, 0x00        /* nopl 0(%rax)       */
385
};
386
 
387
/* Subsequent entries in a procedure linkage table look like this.  */
388
 
389
static const bfd_byte elf64_x86_64_plt_entry[PLT_ENTRY_SIZE] =
390
{
391
  0xff, 0x25,   /* jmpq *name@GOTPC(%rip) */
392
  0, 0, 0, 0,       /* replaced with offset to this symbol in .got.  */
393
  0x68,         /* pushq immediate */
394
  0, 0, 0, 0,       /* replaced with index into relocation table.  */
395
  0xe9,         /* jmp relative */
396
  0, 0, 0, 0        /* replaced with offset to start of .plt0.  */
397
};
398
 
399
/* x86-64 ELF linker hash entry.  */
400
 
401
struct elf64_x86_64_link_hash_entry
402
{
403
  struct elf_link_hash_entry elf;
404
 
405
  /* Track dynamic relocs copied for this symbol.  */
406 225 jeremybenn
  struct elf_dyn_relocs *dyn_relocs;
407 24 jeremybenn
 
408
#define GOT_UNKNOWN     0
409
#define GOT_NORMAL      1
410
#define GOT_TLS_GD      2
411
#define GOT_TLS_IE      3
412
#define GOT_TLS_GDESC   4
413
#define GOT_TLS_GD_BOTH_P(type) \
414
  ((type) == (GOT_TLS_GD | GOT_TLS_GDESC))
415
#define GOT_TLS_GD_P(type) \
416
  ((type) == GOT_TLS_GD || GOT_TLS_GD_BOTH_P (type))
417
#define GOT_TLS_GDESC_P(type) \
418
  ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type))
419
#define GOT_TLS_GD_ANY_P(type) \
420
  (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type))
421
  unsigned char tls_type;
422
 
423
  /* Offset of the GOTPLT entry reserved for the TLS descriptor,
424
     starting at the end of the jump table.  */
425
  bfd_vma tlsdesc_got;
426
};
427
 
428
#define elf64_x86_64_hash_entry(ent) \
429
  ((struct elf64_x86_64_link_hash_entry *)(ent))
430
 
431
struct elf64_x86_64_obj_tdata
432
{
433
  struct elf_obj_tdata root;
434
 
435
  /* tls_type for each local got entry.  */
436
  char *local_got_tls_type;
437
 
438
  /* GOTPLT entries for TLS descriptors.  */
439
  bfd_vma *local_tlsdesc_gotent;
440
};
441
 
442
#define elf64_x86_64_tdata(abfd) \
443
  ((struct elf64_x86_64_obj_tdata *) (abfd)->tdata.any)
444
 
445
#define elf64_x86_64_local_got_tls_type(abfd) \
446
  (elf64_x86_64_tdata (abfd)->local_got_tls_type)
447
 
448
#define elf64_x86_64_local_tlsdesc_gotent(abfd) \
449
  (elf64_x86_64_tdata (abfd)->local_tlsdesc_gotent)
450
 
451
#define is_x86_64_elf(bfd)                              \
452
  (bfd_get_flavour (bfd) == bfd_target_elf_flavour      \
453
   && elf_tdata (bfd) != NULL                           \
454
   && elf_object_id (bfd) == X86_64_ELF_TDATA)
455
 
456
static bfd_boolean
457
elf64_x86_64_mkobject (bfd *abfd)
458
{
459
  return bfd_elf_allocate_object (abfd, sizeof (struct elf64_x86_64_obj_tdata),
460
                                  X86_64_ELF_TDATA);
461
}
462
 
463
/* x86-64 ELF linker hash table.  */
464
 
465
struct elf64_x86_64_link_hash_table
466
{
467
  struct elf_link_hash_table elf;
468
 
469
  /* Short-cuts to get to dynamic linker sections.  */
470
  asection *sdynbss;
471
  asection *srelbss;
472
 
473
  /* The offset into splt of the PLT entry for the TLS descriptor
474
     resolver.  Special values are 0, if not necessary (or not found
475
     to be necessary yet), and -1 if needed but not determined
476
     yet.  */
477
  bfd_vma tlsdesc_plt;
478
  /* The offset into sgot of the GOT entry used by the PLT entry
479
     above.  */
480
  bfd_vma tlsdesc_got;
481
 
482
  union {
483
    bfd_signed_vma refcount;
484
    bfd_vma offset;
485
  } tls_ld_got;
486
 
487
  /* The amount of space used by the jump slots in the GOT.  */
488
  bfd_vma sgotplt_jump_table_size;
489
 
490 225 jeremybenn
  /* Small local sym cache.  */
491
  struct sym_cache sym_cache;
492
 
493
  /* _TLS_MODULE_BASE_ symbol.  */
494
  struct bfd_link_hash_entry *tls_module_base;
495
 
496
  /* Used by local STT_GNU_IFUNC symbols.  */
497
  htab_t loc_hash_table;
498
  void *loc_hash_memory;
499 24 jeremybenn
};
500
 
501
/* Get the x86-64 ELF linker hash table from a link_info structure.  */
502
 
503
#define elf64_x86_64_hash_table(p) \
504
  ((struct elf64_x86_64_link_hash_table *) ((p)->hash))
505
 
506
#define elf64_x86_64_compute_jump_table_size(htab) \
507 225 jeremybenn
  ((htab)->elf.srelplt->reloc_count * GOT_ENTRY_SIZE)
508 24 jeremybenn
 
509
/* Create an entry in an x86-64 ELF linker hash table.  */
510
 
511
static struct bfd_hash_entry *
512 225 jeremybenn
elf64_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry,
513
                                struct bfd_hash_table *table,
514
                                const char *string)
515 24 jeremybenn
{
516
  /* Allocate the structure if it has not already been allocated by a
517
     subclass.  */
518
  if (entry == NULL)
519
    {
520 225 jeremybenn
      entry = (struct bfd_hash_entry *)
521
          bfd_hash_allocate (table,
522
                             sizeof (struct elf64_x86_64_link_hash_entry));
523 24 jeremybenn
      if (entry == NULL)
524
        return entry;
525
    }
526
 
527
  /* Call the allocation method of the superclass.  */
528
  entry = _bfd_elf_link_hash_newfunc (entry, table, string);
529
  if (entry != NULL)
530
    {
531
      struct elf64_x86_64_link_hash_entry *eh;
532
 
533
      eh = (struct elf64_x86_64_link_hash_entry *) entry;
534
      eh->dyn_relocs = NULL;
535
      eh->tls_type = GOT_UNKNOWN;
536
      eh->tlsdesc_got = (bfd_vma) -1;
537
    }
538
 
539
  return entry;
540
}
541
 
542 225 jeremybenn
/* Compute a hash of a local hash entry.  We use elf_link_hash_entry
543
  for local symbol so that we can handle local STT_GNU_IFUNC symbols
544
  as global symbol.  We reuse indx and dynstr_index for local symbol
545
  hash since they aren't used by global symbols in this backend.  */
546
 
547
static hashval_t
548
elf64_x86_64_local_htab_hash (const void *ptr)
549
{
550
  struct elf_link_hash_entry *h
551
    = (struct elf_link_hash_entry *) ptr;
552
  return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
553
}
554
 
555
/* Compare local hash entries.  */
556
 
557
static int
558
elf64_x86_64_local_htab_eq (const void *ptr1, const void *ptr2)
559
{
560
  struct elf_link_hash_entry *h1
561
     = (struct elf_link_hash_entry *) ptr1;
562
  struct elf_link_hash_entry *h2
563
    = (struct elf_link_hash_entry *) ptr2;
564
 
565
  return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
566
}
567
 
568
/* Find and/or create a hash entry for local symbol.  */
569
 
570
static struct elf_link_hash_entry *
571
elf64_x86_64_get_local_sym_hash (struct elf64_x86_64_link_hash_table *htab,
572
                                 bfd *abfd, const Elf_Internal_Rela *rel,
573
                                 bfd_boolean create)
574
{
575
  struct elf64_x86_64_link_hash_entry e, *ret;
576
  asection *sec = abfd->sections;
577
  hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
578
                                       ELF64_R_SYM (rel->r_info));
579
  void **slot;
580
 
581
  e.elf.indx = sec->id;
582
  e.elf.dynstr_index = ELF64_R_SYM (rel->r_info);
583
  slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
584
                                   create ? INSERT : NO_INSERT);
585
 
586
  if (!slot)
587
    return NULL;
588
 
589
  if (*slot)
590
    {
591
      ret = (struct elf64_x86_64_link_hash_entry *) *slot;
592
      return &ret->elf;
593
    }
594
 
595
  ret = (struct elf64_x86_64_link_hash_entry *)
596
        objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
597
                        sizeof (struct elf64_x86_64_link_hash_entry));
598
  if (ret)
599
    {
600
      memset (ret, 0, sizeof (*ret));
601
      ret->elf.indx = sec->id;
602
      ret->elf.dynstr_index = ELF64_R_SYM (rel->r_info);
603
      ret->elf.dynindx = -1;
604
      ret->elf.plt.offset = (bfd_vma) -1;
605
      ret->elf.got.offset = (bfd_vma) -1;
606
      *slot = ret;
607
    }
608
  return &ret->elf;
609
}
610
 
611 24 jeremybenn
/* Create an X86-64 ELF linker hash table.  */
612
 
613
static struct bfd_link_hash_table *
614
elf64_x86_64_link_hash_table_create (bfd *abfd)
615
{
616
  struct elf64_x86_64_link_hash_table *ret;
617
  bfd_size_type amt = sizeof (struct elf64_x86_64_link_hash_table);
618
 
619
  ret = (struct elf64_x86_64_link_hash_table *) bfd_malloc (amt);
620
  if (ret == NULL)
621
    return NULL;
622
 
623 225 jeremybenn
  if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
624
                                      elf64_x86_64_link_hash_newfunc,
625 24 jeremybenn
                                      sizeof (struct elf64_x86_64_link_hash_entry)))
626
    {
627
      free (ret);
628
      return NULL;
629
    }
630
 
631
  ret->sdynbss = NULL;
632
  ret->srelbss = NULL;
633 225 jeremybenn
  ret->sym_cache.abfd = NULL;
634 24 jeremybenn
  ret->tlsdesc_plt = 0;
635
  ret->tlsdesc_got = 0;
636
  ret->tls_ld_got.refcount = 0;
637
  ret->sgotplt_jump_table_size = 0;
638 225 jeremybenn
  ret->tls_module_base = NULL;
639 24 jeremybenn
 
640 225 jeremybenn
  ret->loc_hash_table = htab_try_create (1024,
641
                                         elf64_x86_64_local_htab_hash,
642
                                         elf64_x86_64_local_htab_eq,
643
                                         NULL);
644
  ret->loc_hash_memory = objalloc_create ();
645
  if (!ret->loc_hash_table || !ret->loc_hash_memory)
646
    {
647
      free (ret);
648
      return NULL;
649
    }
650
 
651 24 jeremybenn
  return &ret->elf.root;
652
}
653
 
654 225 jeremybenn
/* Destroy an X86-64 ELF linker hash table.  */
655 24 jeremybenn
 
656 225 jeremybenn
static void
657
elf64_x86_64_link_hash_table_free (struct bfd_link_hash_table *hash)
658 24 jeremybenn
{
659 225 jeremybenn
  struct elf64_x86_64_link_hash_table *htab
660
    = (struct elf64_x86_64_link_hash_table *) hash;
661 24 jeremybenn
 
662 225 jeremybenn
  if (htab->loc_hash_table)
663
    htab_delete (htab->loc_hash_table);
664
  if (htab->loc_hash_memory)
665
    objalloc_free ((struct objalloc *) htab->loc_hash_memory);
666
  _bfd_generic_link_hash_table_free (hash);
667 24 jeremybenn
}
668
 
669
/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
670
   .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
671
   hash table.  */
672
 
673
static bfd_boolean
674
elf64_x86_64_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
675
{
676
  struct elf64_x86_64_link_hash_table *htab;
677
 
678
  if (!_bfd_elf_create_dynamic_sections (dynobj, info))
679
    return FALSE;
680
 
681 225 jeremybenn
  htab = elf64_x86_64_hash_table (info);
682 24 jeremybenn
  htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
683
  if (!info->shared)
684
    htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
685
 
686 225 jeremybenn
  if (!htab->sdynbss
687 24 jeremybenn
      || (!info->shared && !htab->srelbss))
688
    abort ();
689
 
690
  return TRUE;
691
}
692
 
693
/* Copy the extra info we tack onto an elf_link_hash_entry.  */
694
 
695
static void
696
elf64_x86_64_copy_indirect_symbol (struct bfd_link_info *info,
697
                                   struct elf_link_hash_entry *dir,
698
                                   struct elf_link_hash_entry *ind)
699
{
700
  struct elf64_x86_64_link_hash_entry *edir, *eind;
701
 
702
  edir = (struct elf64_x86_64_link_hash_entry *) dir;
703
  eind = (struct elf64_x86_64_link_hash_entry *) ind;
704
 
705
  if (eind->dyn_relocs != NULL)
706
    {
707
      if (edir->dyn_relocs != NULL)
708
        {
709 225 jeremybenn
          struct elf_dyn_relocs **pp;
710
          struct elf_dyn_relocs *p;
711 24 jeremybenn
 
712
          /* Add reloc counts against the indirect sym to the direct sym
713
             list.  Merge any entries against the same section.  */
714
          for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
715
            {
716 225 jeremybenn
              struct elf_dyn_relocs *q;
717 24 jeremybenn
 
718
              for (q = edir->dyn_relocs; q != NULL; q = q->next)
719
                if (q->sec == p->sec)
720
                  {
721
                    q->pc_count += p->pc_count;
722
                    q->count += p->count;
723
                    *pp = p->next;
724
                    break;
725
                  }
726
              if (q == NULL)
727
                pp = &p->next;
728
            }
729
          *pp = edir->dyn_relocs;
730
        }
731
 
732
      edir->dyn_relocs = eind->dyn_relocs;
733
      eind->dyn_relocs = NULL;
734
    }
735
 
736
  if (ind->root.type == bfd_link_hash_indirect
737
      && dir->got.refcount <= 0)
738
    {
739
      edir->tls_type = eind->tls_type;
740
      eind->tls_type = GOT_UNKNOWN;
741
    }
742
 
743
  if (ELIMINATE_COPY_RELOCS
744
      && ind->root.type != bfd_link_hash_indirect
745
      && dir->dynamic_adjusted)
746
    {
747
      /* If called to transfer flags for a weakdef during processing
748
         of elf_adjust_dynamic_symbol, don't copy non_got_ref.
749
         We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
750
      dir->ref_dynamic |= ind->ref_dynamic;
751
      dir->ref_regular |= ind->ref_regular;
752
      dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
753
      dir->needs_plt |= ind->needs_plt;
754
      dir->pointer_equality_needed |= ind->pointer_equality_needed;
755
    }
756
  else
757
    _bfd_elf_link_hash_copy_indirect (info, dir, ind);
758
}
759
 
760
static bfd_boolean
761
elf64_x86_64_elf_object_p (bfd *abfd)
762
{
763
  /* Set the right machine number for an x86-64 elf64 file.  */
764
  bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
765
  return TRUE;
766
}
767
 
768
typedef union
769
  {
770
    unsigned char c[2];
771
    uint16_t i;
772
  }
773
x86_64_opcode16;
774
 
775
typedef union
776
  {
777
    unsigned char c[4];
778
    uint32_t i;
779
  }
780
x86_64_opcode32;
781
 
782
/* Return TRUE if the TLS access code sequence support transition
783
   from R_TYPE.  */
784
 
785
static bfd_boolean
786
elf64_x86_64_check_tls_transition (bfd *abfd, asection *sec,
787
                                   bfd_byte *contents,
788
                                   Elf_Internal_Shdr *symtab_hdr,
789
                                   struct elf_link_hash_entry **sym_hashes,
790
                                   unsigned int r_type,
791
                                   const Elf_Internal_Rela *rel,
792
                                   const Elf_Internal_Rela *relend)
793
{
794
  unsigned int val;
795
  unsigned long r_symndx;
796
  struct elf_link_hash_entry *h;
797
  bfd_vma offset;
798
 
799
  /* Get the section contents.  */
800
  if (contents == NULL)
801
    {
802
      if (elf_section_data (sec)->this_hdr.contents != NULL)
803
        contents = elf_section_data (sec)->this_hdr.contents;
804
      else
805
        {
806
          /* FIXME: How to better handle error condition?  */
807
          if (!bfd_malloc_and_get_section (abfd, sec, &contents))
808
            return FALSE;
809
 
810
          /* Cache the section contents for elf_link_input_bfd.  */
811
          elf_section_data (sec)->this_hdr.contents = contents;
812
        }
813
    }
814
 
815
  offset = rel->r_offset;
816
  switch (r_type)
817
    {
818
    case R_X86_64_TLSGD:
819
    case R_X86_64_TLSLD:
820
      if ((rel + 1) >= relend)
821
        return FALSE;
822
 
823
      if (r_type == R_X86_64_TLSGD)
824
        {
825
          /* Check transition from GD access model.  Only
826
                .byte 0x66; leaq foo@tlsgd(%rip), %rdi
827
                .word 0x6666; rex64; call __tls_get_addr
828
             can transit to different access model.  */
829
 
830
          static x86_64_opcode32 leaq = { { 0x66, 0x48, 0x8d, 0x3d } },
831
                                 call = { { 0x66, 0x66, 0x48, 0xe8 } };
832
          if (offset < 4
833
              || (offset + 12) > sec->size
834
              || bfd_get_32 (abfd, contents + offset - 4) != leaq.i
835
              || bfd_get_32 (abfd, contents + offset + 4) != call.i)
836
            return FALSE;
837
        }
838
      else
839
        {
840
          /* Check transition from LD access model.  Only
841
                leaq foo@tlsld(%rip), %rdi;
842
                call __tls_get_addr
843
             can transit to different access model.  */
844
 
845
          static x86_64_opcode32 ld = { { 0x48, 0x8d, 0x3d, 0xe8 } };
846
          x86_64_opcode32 op;
847
 
848
          if (offset < 3 || (offset + 9) > sec->size)
849
            return FALSE;
850
 
851
          op.i = bfd_get_32 (abfd, contents + offset - 3);
852
          op.c[3] = bfd_get_8 (abfd, contents + offset + 4);
853
          if (op.i != ld.i)
854
            return FALSE;
855
        }
856
 
857
      r_symndx = ELF64_R_SYM (rel[1].r_info);
858
      if (r_symndx < symtab_hdr->sh_info)
859
        return FALSE;
860
 
861
      h = sym_hashes[r_symndx - symtab_hdr->sh_info];
862 225 jeremybenn
      /* Use strncmp to check __tls_get_addr since __tls_get_addr
863
         may be versioned.  */
864 24 jeremybenn
      return (h != NULL
865
              && h->root.root.string != NULL
866
              && (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PC32
867
                  || ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32)
868 225 jeremybenn
              && (strncmp (h->root.root.string,
869
                           "__tls_get_addr", 14) == 0));
870 24 jeremybenn
 
871
    case R_X86_64_GOTTPOFF:
872
      /* Check transition from IE access model:
873
                movq foo@gottpoff(%rip), %reg
874
                addq foo@gottpoff(%rip), %reg
875
       */
876
 
877
      if (offset < 3 || (offset + 4) > sec->size)
878
        return FALSE;
879
 
880
      val = bfd_get_8 (abfd, contents + offset - 3);
881
      if (val != 0x48 && val != 0x4c)
882
        return FALSE;
883
 
884
      val = bfd_get_8 (abfd, contents + offset - 2);
885
      if (val != 0x8b && val != 0x03)
886
        return FALSE;
887
 
888
      val = bfd_get_8 (abfd, contents + offset - 1);
889
      return (val & 0xc7) == 5;
890
 
891
    case R_X86_64_GOTPC32_TLSDESC:
892
      /* Check transition from GDesc access model:
893
                leaq x@tlsdesc(%rip), %rax
894
 
895
         Make sure it's a leaq adding rip to a 32-bit offset
896
         into any register, although it's probably almost always
897
         going to be rax.  */
898
 
899
      if (offset < 3 || (offset + 4) > sec->size)
900
        return FALSE;
901
 
902
      val = bfd_get_8 (abfd, contents + offset - 3);
903
      if ((val & 0xfb) != 0x48)
904
        return FALSE;
905
 
906
      if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d)
907
        return FALSE;
908
 
909
      val = bfd_get_8 (abfd, contents + offset - 1);
910
      return (val & 0xc7) == 0x05;
911
 
912
    case R_X86_64_TLSDESC_CALL:
913
      /* Check transition from GDesc access model:
914
                call *x@tlsdesc(%rax)
915
       */
916
      if (offset + 2 <= sec->size)
917
        {
918
          /* Make sure that it's a call *x@tlsdesc(%rax).  */
919
          static x86_64_opcode16 call = { { 0xff, 0x10 } };
920
          return bfd_get_16 (abfd, contents + offset) == call.i;
921
        }
922
 
923
      return FALSE;
924
 
925
    default:
926
      abort ();
927
    }
928
}
929
 
930
/* Return TRUE if the TLS access transition is OK or no transition
931
   will be performed.  Update R_TYPE if there is a transition.  */
932
 
933
static bfd_boolean
934
elf64_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
935
                             asection *sec, bfd_byte *contents,
936
                             Elf_Internal_Shdr *symtab_hdr,
937
                             struct elf_link_hash_entry **sym_hashes,
938
                             unsigned int *r_type, int tls_type,
939
                             const Elf_Internal_Rela *rel,
940
                             const Elf_Internal_Rela *relend,
941 225 jeremybenn
                             struct elf_link_hash_entry *h,
942
                             unsigned long r_symndx)
943 24 jeremybenn
{
944
  unsigned int from_type = *r_type;
945
  unsigned int to_type = from_type;
946
  bfd_boolean check = TRUE;
947
 
948
  switch (from_type)
949
    {
950
    case R_X86_64_TLSGD:
951
    case R_X86_64_GOTPC32_TLSDESC:
952
    case R_X86_64_TLSDESC_CALL:
953
    case R_X86_64_GOTTPOFF:
954 225 jeremybenn
      if (info->executable)
955 24 jeremybenn
        {
956
          if (h == NULL)
957
            to_type = R_X86_64_TPOFF32;
958
          else
959
            to_type = R_X86_64_GOTTPOFF;
960
        }
961
 
962
      /* When we are called from elf64_x86_64_relocate_section,
963
         CONTENTS isn't NULL and there may be additional transitions
964
         based on TLS_TYPE.  */
965
      if (contents != NULL)
966
        {
967
          unsigned int new_to_type = to_type;
968
 
969 225 jeremybenn
          if (info->executable
970 24 jeremybenn
              && h != NULL
971
              && h->dynindx == -1
972
              && tls_type == GOT_TLS_IE)
973
            new_to_type = R_X86_64_TPOFF32;
974
 
975
          if (to_type == R_X86_64_TLSGD
976
              || to_type == R_X86_64_GOTPC32_TLSDESC
977
              || to_type == R_X86_64_TLSDESC_CALL)
978
            {
979
              if (tls_type == GOT_TLS_IE)
980
                new_to_type = R_X86_64_GOTTPOFF;
981
            }
982
 
983
          /* We checked the transition before when we were called from
984
             elf64_x86_64_check_relocs.  We only want to check the new
985
             transition which hasn't been checked before.  */
986
          check = new_to_type != to_type && from_type == to_type;
987
          to_type = new_to_type;
988
        }
989
 
990
      break;
991
 
992
    case R_X86_64_TLSLD:
993 225 jeremybenn
      if (info->executable)
994 24 jeremybenn
        to_type = R_X86_64_TPOFF32;
995
      break;
996
 
997
    default:
998
      return TRUE;
999
    }
1000
 
1001
  /* Return TRUE if there is no transition.  */
1002
  if (from_type == to_type)
1003
    return TRUE;
1004
 
1005
  /* Check if the transition can be performed.  */
1006
  if (check
1007
      && ! elf64_x86_64_check_tls_transition (abfd, sec, contents,
1008
                                              symtab_hdr, sym_hashes,
1009
                                              from_type, rel, relend))
1010
    {
1011
      reloc_howto_type *from, *to;
1012 225 jeremybenn
      const char *name;
1013 24 jeremybenn
 
1014
      from = elf64_x86_64_rtype_to_howto (abfd, from_type);
1015
      to = elf64_x86_64_rtype_to_howto (abfd, to_type);
1016
 
1017 225 jeremybenn
      if (h)
1018
        name = h->root.root.string;
1019
      else
1020
        {
1021
          Elf_Internal_Sym *isym;
1022
          struct elf64_x86_64_link_hash_table *htab;
1023
          htab = elf64_x86_64_hash_table (info);
1024
          isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1025
                                        abfd, r_symndx);
1026
          name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
1027
        }
1028
 
1029 24 jeremybenn
      (*_bfd_error_handler)
1030
        (_("%B: TLS transition from %s to %s against `%s' at 0x%lx "
1031
           "in section `%A' failed"),
1032 225 jeremybenn
         abfd, sec, from->name, to->name, name,
1033 24 jeremybenn
         (unsigned long) rel->r_offset);
1034
      bfd_set_error (bfd_error_bad_value);
1035
      return FALSE;
1036
    }
1037
 
1038
  *r_type = to_type;
1039
  return TRUE;
1040
}
1041
 
1042
/* Look through the relocs for a section during the first phase, and
1043
   calculate needed space in the global offset table, procedure
1044
   linkage table, and dynamic reloc sections.  */
1045
 
1046
static bfd_boolean
1047
elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
1048
                           asection *sec,
1049
                           const Elf_Internal_Rela *relocs)
1050
{
1051
  struct elf64_x86_64_link_hash_table *htab;
1052
  Elf_Internal_Shdr *symtab_hdr;
1053
  struct elf_link_hash_entry **sym_hashes;
1054
  const Elf_Internal_Rela *rel;
1055
  const Elf_Internal_Rela *rel_end;
1056
  asection *sreloc;
1057
 
1058
  if (info->relocatable)
1059
    return TRUE;
1060
 
1061
  BFD_ASSERT (is_x86_64_elf (abfd));
1062
 
1063
  htab = elf64_x86_64_hash_table (info);
1064
  symtab_hdr = &elf_symtab_hdr (abfd);
1065
  sym_hashes = elf_sym_hashes (abfd);
1066
 
1067
  sreloc = NULL;
1068
 
1069
  rel_end = relocs + sec->reloc_count;
1070
  for (rel = relocs; rel < rel_end; rel++)
1071
    {
1072
      unsigned int r_type;
1073
      unsigned long r_symndx;
1074
      struct elf_link_hash_entry *h;
1075 225 jeremybenn
      Elf_Internal_Sym *isym;
1076
      const char *name;
1077 24 jeremybenn
 
1078
      r_symndx = ELF64_R_SYM (rel->r_info);
1079
      r_type = ELF64_R_TYPE (rel->r_info);
1080
 
1081
      if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
1082
        {
1083
          (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
1084
                                 abfd, r_symndx);
1085
          return FALSE;
1086
        }
1087
 
1088
      if (r_symndx < symtab_hdr->sh_info)
1089 225 jeremybenn
        {
1090
          /* A local symbol.  */
1091
          isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1092
                                        abfd, r_symndx);
1093
          if (isym == NULL)
1094
            return FALSE;
1095
 
1096
          /* Check relocation against local STT_GNU_IFUNC symbol.  */
1097
          if (ELF64_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
1098
            {
1099
              h = elf64_x86_64_get_local_sym_hash (htab, abfd, rel,
1100
                                                   TRUE);
1101
              if (h == NULL)
1102
                return FALSE;
1103
 
1104
              /* Fake a STT_GNU_IFUNC symbol.  */
1105
              h->type = STT_GNU_IFUNC;
1106
              h->def_regular = 1;
1107
              h->ref_regular = 1;
1108
              h->forced_local = 1;
1109
              h->root.type = bfd_link_hash_defined;
1110
            }
1111
          else
1112
            h = NULL;
1113
        }
1114 24 jeremybenn
      else
1115
        {
1116 225 jeremybenn
          isym = NULL;
1117 24 jeremybenn
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1118
          while (h->root.type == bfd_link_hash_indirect
1119
                 || h->root.type == bfd_link_hash_warning)
1120
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
1121
        }
1122
 
1123 225 jeremybenn
      if (h != NULL)
1124
        {
1125
          /* Create the ifunc sections for static executables.  If we
1126
             never see an indirect function symbol nor we are building
1127
             a static executable, those sections will be empty and
1128
             won't appear in output.  */
1129
          switch (r_type)
1130
            {
1131
            default:
1132
              break;
1133
 
1134
            case R_X86_64_32S:
1135
            case R_X86_64_32:
1136
            case R_X86_64_64:
1137
            case R_X86_64_PC32:
1138
            case R_X86_64_PC64:
1139
            case R_X86_64_PLT32:
1140
            case R_X86_64_GOTPCREL:
1141
            case R_X86_64_GOTPCREL64:
1142
              if (!_bfd_elf_create_ifunc_sections (abfd, info))
1143
                return FALSE;
1144
              break;
1145
            }
1146
 
1147
          /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
1148
             it here if it is defined in a non-shared object.  */
1149
          if (h->type == STT_GNU_IFUNC
1150
              && h->def_regular)
1151
            {
1152
              /* It is referenced by a non-shared object. */
1153
              h->ref_regular = 1;
1154
              h->needs_plt = 1;
1155
 
1156
              /* STT_GNU_IFUNC symbol must go through PLT.  */
1157
              h->plt.refcount += 1;
1158
 
1159
              /* STT_GNU_IFUNC needs dynamic sections.  */
1160
              if (htab->elf.dynobj == NULL)
1161
                htab->elf.dynobj = abfd;
1162
 
1163
              switch (r_type)
1164
                {
1165
                default:
1166
                  if (h->root.root.string)
1167
                    name = h->root.root.string;
1168
                  else
1169
                    name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
1170
                                             NULL);
1171
                  (*_bfd_error_handler)
1172
                    (_("%B: relocation %s against STT_GNU_IFUNC "
1173
                       "symbol `%s' isn't handled by %s"), abfd,
1174
                     x86_64_elf_howto_table[r_type].name,
1175
                     name, __FUNCTION__);
1176
                  bfd_set_error (bfd_error_bad_value);
1177
                  return FALSE;
1178
 
1179
                case R_X86_64_64:
1180
                  h->non_got_ref = 1;
1181
                  h->pointer_equality_needed = 1;
1182
                  if (info->shared)
1183
                    {
1184
                      /* We must copy these reloc types into the output
1185
                         file.  Create a reloc section in dynobj and
1186
                         make room for this reloc.  */
1187
                      sreloc = _bfd_elf_create_ifunc_dyn_reloc
1188
                        (abfd, info, sec, sreloc,
1189
                         &((struct elf64_x86_64_link_hash_entry *) h)->dyn_relocs);
1190
                      if (sreloc == NULL)
1191
                        return FALSE;
1192
                    }
1193
                  break;
1194
 
1195
                case R_X86_64_32S:
1196
                case R_X86_64_32:
1197
                case R_X86_64_PC32:
1198
                case R_X86_64_PC64:
1199
                  h->non_got_ref = 1;
1200
                  if (r_type != R_X86_64_PC32
1201
                      && r_type != R_X86_64_PC64)
1202
                    h->pointer_equality_needed = 1;
1203
                  break;
1204
 
1205
                case R_X86_64_PLT32:
1206
                  break;
1207
 
1208
                case R_X86_64_GOTPCREL:
1209
                case R_X86_64_GOTPCREL64:
1210
                  h->got.refcount += 1;
1211
                  if (htab->elf.sgot == NULL
1212
                      && !_bfd_elf_create_got_section (htab->elf.dynobj,
1213
                                                       info))
1214
                    return FALSE;
1215
                  break;
1216
                }
1217
 
1218
              continue;
1219
            }
1220
        }
1221
 
1222 24 jeremybenn
      if (! elf64_x86_64_tls_transition (info, abfd, sec, NULL,
1223
                                         symtab_hdr, sym_hashes,
1224
                                         &r_type, GOT_UNKNOWN,
1225 225 jeremybenn
                                         rel, rel_end, h, r_symndx))
1226 24 jeremybenn
        return FALSE;
1227
 
1228
      switch (r_type)
1229
        {
1230
        case R_X86_64_TLSLD:
1231
          htab->tls_ld_got.refcount += 1;
1232
          goto create_got;
1233
 
1234
        case R_X86_64_TPOFF32:
1235 225 jeremybenn
          if (!info->executable)
1236 24 jeremybenn
            {
1237 225 jeremybenn
              if (h)
1238
                name = h->root.root.string;
1239
              else
1240
                name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
1241
                                         NULL);
1242 24 jeremybenn
              (*_bfd_error_handler)
1243
                (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1244
                 abfd,
1245 225 jeremybenn
                 x86_64_elf_howto_table[r_type].name, name);
1246 24 jeremybenn
              bfd_set_error (bfd_error_bad_value);
1247
              return FALSE;
1248
            }
1249
          break;
1250
 
1251
        case R_X86_64_GOTTPOFF:
1252 225 jeremybenn
          if (!info->executable)
1253 24 jeremybenn
            info->flags |= DF_STATIC_TLS;
1254
          /* Fall through */
1255
 
1256
        case R_X86_64_GOT32:
1257
        case R_X86_64_GOTPCREL:
1258
        case R_X86_64_TLSGD:
1259
        case R_X86_64_GOT64:
1260
        case R_X86_64_GOTPCREL64:
1261
        case R_X86_64_GOTPLT64:
1262
        case R_X86_64_GOTPC32_TLSDESC:
1263
        case R_X86_64_TLSDESC_CALL:
1264
          /* This symbol requires a global offset table entry.  */
1265
          {
1266
            int tls_type, old_tls_type;
1267
 
1268
            switch (r_type)
1269
              {
1270
              default: tls_type = GOT_NORMAL; break;
1271
              case R_X86_64_TLSGD: tls_type = GOT_TLS_GD; break;
1272
              case R_X86_64_GOTTPOFF: tls_type = GOT_TLS_IE; break;
1273
              case R_X86_64_GOTPC32_TLSDESC:
1274
              case R_X86_64_TLSDESC_CALL:
1275
                tls_type = GOT_TLS_GDESC; break;
1276
              }
1277
 
1278
            if (h != NULL)
1279
              {
1280
                if (r_type == R_X86_64_GOTPLT64)
1281
                  {
1282
                    /* This relocation indicates that we also need
1283
                       a PLT entry, as this is a function.  We don't need
1284
                       a PLT entry for local symbols.  */
1285
                    h->needs_plt = 1;
1286
                    h->plt.refcount += 1;
1287
                  }
1288
                h->got.refcount += 1;
1289
                old_tls_type = elf64_x86_64_hash_entry (h)->tls_type;
1290
              }
1291
            else
1292
              {
1293
                bfd_signed_vma *local_got_refcounts;
1294
 
1295
                /* This is a global offset table entry for a local symbol.  */
1296
                local_got_refcounts = elf_local_got_refcounts (abfd);
1297
                if (local_got_refcounts == NULL)
1298
                  {
1299
                    bfd_size_type size;
1300
 
1301
                    size = symtab_hdr->sh_info;
1302
                    size *= sizeof (bfd_signed_vma)
1303
                      + sizeof (bfd_vma) + sizeof (char);
1304
                    local_got_refcounts = ((bfd_signed_vma *)
1305
                                           bfd_zalloc (abfd, size));
1306
                    if (local_got_refcounts == NULL)
1307
                      return FALSE;
1308
                    elf_local_got_refcounts (abfd) = local_got_refcounts;
1309
                    elf64_x86_64_local_tlsdesc_gotent (abfd)
1310
                      = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
1311
                    elf64_x86_64_local_got_tls_type (abfd)
1312
                      = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
1313
                  }
1314
                local_got_refcounts[r_symndx] += 1;
1315
                old_tls_type
1316
                  = elf64_x86_64_local_got_tls_type (abfd) [r_symndx];
1317
              }
1318
 
1319
            /* If a TLS symbol is accessed using IE at least once,
1320
               there is no point to use dynamic model for it.  */
1321
            if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
1322
                && (! GOT_TLS_GD_ANY_P (old_tls_type)
1323
                    || tls_type != GOT_TLS_IE))
1324
              {
1325
                if (old_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (tls_type))
1326
                  tls_type = old_tls_type;
1327
                else if (GOT_TLS_GD_ANY_P (old_tls_type)
1328
                         && GOT_TLS_GD_ANY_P (tls_type))
1329
                  tls_type |= old_tls_type;
1330
                else
1331
                  {
1332 225 jeremybenn
                    if (h)
1333
                      name = h->root.root.string;
1334
                    else
1335
                      name = bfd_elf_sym_name (abfd, symtab_hdr,
1336
                                               isym, NULL);
1337 24 jeremybenn
                    (*_bfd_error_handler)
1338
                      (_("%B: '%s' accessed both as normal and thread local symbol"),
1339 225 jeremybenn
                       abfd, name);
1340 24 jeremybenn
                    return FALSE;
1341
                  }
1342
              }
1343
 
1344
            if (old_tls_type != tls_type)
1345
              {
1346
                if (h != NULL)
1347
                  elf64_x86_64_hash_entry (h)->tls_type = tls_type;
1348
                else
1349
                  elf64_x86_64_local_got_tls_type (abfd) [r_symndx] = tls_type;
1350
              }
1351
          }
1352
          /* Fall through */
1353
 
1354
        case R_X86_64_GOTOFF64:
1355
        case R_X86_64_GOTPC32:
1356
        case R_X86_64_GOTPC64:
1357
        create_got:
1358 225 jeremybenn
          if (htab->elf.sgot == NULL)
1359 24 jeremybenn
            {
1360
              if (htab->elf.dynobj == NULL)
1361
                htab->elf.dynobj = abfd;
1362 225 jeremybenn
              if (!_bfd_elf_create_got_section (htab->elf.dynobj,
1363
                                                info))
1364 24 jeremybenn
                return FALSE;
1365
            }
1366
          break;
1367
 
1368
        case R_X86_64_PLT32:
1369
          /* This symbol requires a procedure linkage table entry.  We
1370
             actually build the entry in adjust_dynamic_symbol,
1371
             because this might be a case of linking PIC code which is
1372
             never referenced by a dynamic object, in which case we
1373
             don't need to generate a procedure linkage table entry
1374
             after all.  */
1375
 
1376
          /* If this is a local symbol, we resolve it directly without
1377
             creating a procedure linkage table entry.  */
1378
          if (h == NULL)
1379
            continue;
1380
 
1381
          h->needs_plt = 1;
1382
          h->plt.refcount += 1;
1383
          break;
1384
 
1385
        case R_X86_64_PLTOFF64:
1386
          /* This tries to form the 'address' of a function relative
1387
             to GOT.  For global symbols we need a PLT entry.  */
1388
          if (h != NULL)
1389
            {
1390
              h->needs_plt = 1;
1391
              h->plt.refcount += 1;
1392
            }
1393
          goto create_got;
1394
 
1395
        case R_X86_64_8:
1396
        case R_X86_64_16:
1397
        case R_X86_64_32:
1398
        case R_X86_64_32S:
1399
          /* Let's help debug shared library creation.  These relocs
1400
             cannot be used in shared libs.  Don't error out for
1401
             sections we don't care about, such as debug sections or
1402
             non-constant sections.  */
1403
          if (info->shared
1404
              && (sec->flags & SEC_ALLOC) != 0
1405
              && (sec->flags & SEC_READONLY) != 0)
1406
            {
1407 225 jeremybenn
              if (h)
1408
                name = h->root.root.string;
1409
              else
1410
                name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
1411 24 jeremybenn
              (*_bfd_error_handler)
1412
                (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1413 225 jeremybenn
                 abfd, x86_64_elf_howto_table[r_type].name, name);
1414 24 jeremybenn
              bfd_set_error (bfd_error_bad_value);
1415
              return FALSE;
1416
            }
1417
          /* Fall through.  */
1418
 
1419
        case R_X86_64_PC8:
1420
        case R_X86_64_PC16:
1421
        case R_X86_64_PC32:
1422
        case R_X86_64_PC64:
1423
        case R_X86_64_64:
1424 225 jeremybenn
          if (h != NULL && info->executable)
1425 24 jeremybenn
            {
1426
              /* If this reloc is in a read-only section, we might
1427
                 need a copy reloc.  We can't check reliably at this
1428
                 stage whether the section is read-only, as input
1429
                 sections have not yet been mapped to output sections.
1430
                 Tentatively set the flag for now, and correct in
1431
                 adjust_dynamic_symbol.  */
1432
              h->non_got_ref = 1;
1433
 
1434
              /* We may need a .plt entry if the function this reloc
1435
                 refers to is in a shared lib.  */
1436
              h->plt.refcount += 1;
1437
              if (r_type != R_X86_64_PC32 && r_type != R_X86_64_PC64)
1438
                h->pointer_equality_needed = 1;
1439
            }
1440
 
1441
          /* If we are creating a shared library, and this is a reloc
1442
             against a global symbol, or a non PC relative reloc
1443
             against a local symbol, then we need to copy the reloc
1444
             into the shared library.  However, if we are linking with
1445
             -Bsymbolic, we do not need to copy a reloc against a
1446
             global symbol which is defined in an object we are
1447
             including in the link (i.e., DEF_REGULAR is set).  At
1448
             this point we have not seen all the input files, so it is
1449
             possible that DEF_REGULAR is not set now but will be set
1450
             later (it is never cleared).  In case of a weak definition,
1451
             DEF_REGULAR may be cleared later by a strong definition in
1452
             a shared library.  We account for that possibility below by
1453
             storing information in the relocs_copied field of the hash
1454
             table entry.  A similar situation occurs when creating
1455
             shared libraries and symbol visibility changes render the
1456
             symbol local.
1457
 
1458
             If on the other hand, we are creating an executable, we
1459
             may need to keep relocations for symbols satisfied by a
1460
             dynamic library if we manage to avoid copy relocs for the
1461
             symbol.  */
1462
          if ((info->shared
1463
               && (sec->flags & SEC_ALLOC) != 0
1464 225 jeremybenn
               && (! IS_X86_64_PCREL_TYPE (r_type)
1465 24 jeremybenn
                   || (h != NULL
1466
                       && (! SYMBOLIC_BIND (info, h)
1467
                           || h->root.type == bfd_link_hash_defweak
1468
                           || !h->def_regular))))
1469
              || (ELIMINATE_COPY_RELOCS
1470
                  && !info->shared
1471
                  && (sec->flags & SEC_ALLOC) != 0
1472
                  && h != NULL
1473
                  && (h->root.type == bfd_link_hash_defweak
1474
                      || !h->def_regular)))
1475
            {
1476 225 jeremybenn
              struct elf_dyn_relocs *p;
1477
              struct elf_dyn_relocs **head;
1478 24 jeremybenn
 
1479
              /* We must copy these reloc types into the output file.
1480
                 Create a reloc section in dynobj and make room for
1481
                 this reloc.  */
1482
              if (sreloc == NULL)
1483
                {
1484
                  if (htab->elf.dynobj == NULL)
1485
                    htab->elf.dynobj = abfd;
1486
 
1487 225 jeremybenn
                  sreloc = _bfd_elf_make_dynamic_reloc_section
1488
                    (sec, htab->elf.dynobj, 3, abfd, /*rela?*/ TRUE);
1489 24 jeremybenn
 
1490
                  if (sreloc == NULL)
1491 225 jeremybenn
                    return FALSE;
1492 24 jeremybenn
                }
1493
 
1494
              /* If this is a global symbol, we count the number of
1495
                 relocations we need for this symbol.  */
1496
              if (h != NULL)
1497
                {
1498
                  head = &((struct elf64_x86_64_link_hash_entry *) h)->dyn_relocs;
1499
                }
1500
              else
1501
                {
1502
                  /* Track dynamic relocs needed for local syms too.
1503
                     We really need local syms available to do this
1504
                     easily.  Oh well.  */
1505 225 jeremybenn
                  asection *s;
1506
                  void **vpp;
1507
                  Elf_Internal_Sym *isym;
1508 24 jeremybenn
 
1509 225 jeremybenn
                  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1510
                                                abfd, r_symndx);
1511
                  if (isym == NULL)
1512 24 jeremybenn
                    return FALSE;
1513
 
1514 225 jeremybenn
                  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
1515
                  if (s == NULL)
1516
                    s = sec;
1517
 
1518 24 jeremybenn
                  /* Beware of type punned pointers vs strict aliasing
1519
                     rules.  */
1520
                  vpp = &(elf_section_data (s)->local_dynrel);
1521 225 jeremybenn
                  head = (struct elf_dyn_relocs **)vpp;
1522 24 jeremybenn
                }
1523
 
1524
              p = *head;
1525
              if (p == NULL || p->sec != sec)
1526
                {
1527
                  bfd_size_type amt = sizeof *p;
1528 225 jeremybenn
 
1529
                  p = ((struct elf_dyn_relocs *)
1530 24 jeremybenn
                       bfd_alloc (htab->elf.dynobj, amt));
1531
                  if (p == NULL)
1532
                    return FALSE;
1533
                  p->next = *head;
1534
                  *head = p;
1535
                  p->sec = sec;
1536
                  p->count = 0;
1537
                  p->pc_count = 0;
1538
                }
1539
 
1540
              p->count += 1;
1541 225 jeremybenn
              if (IS_X86_64_PCREL_TYPE (r_type))
1542 24 jeremybenn
                p->pc_count += 1;
1543
            }
1544
          break;
1545
 
1546
          /* This relocation describes the C++ object vtable hierarchy.
1547
             Reconstruct it for later use during GC.  */
1548
        case R_X86_64_GNU_VTINHERIT:
1549
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1550
            return FALSE;
1551
          break;
1552
 
1553
          /* This relocation describes which C++ vtable entries are actually
1554
             used.  Record for later use during GC.  */
1555
        case R_X86_64_GNU_VTENTRY:
1556
          BFD_ASSERT (h != NULL);
1557
          if (h != NULL
1558
              && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1559
            return FALSE;
1560
          break;
1561
 
1562
        default:
1563
          break;
1564
        }
1565
    }
1566
 
1567
  return TRUE;
1568
}
1569
 
1570
/* Return the section that should be marked against GC for a given
1571
   relocation.  */
1572
 
1573
static asection *
1574
elf64_x86_64_gc_mark_hook (asection *sec,
1575
                           struct bfd_link_info *info,
1576
                           Elf_Internal_Rela *rel,
1577
                           struct elf_link_hash_entry *h,
1578
                           Elf_Internal_Sym *sym)
1579
{
1580
  if (h != NULL)
1581
    switch (ELF64_R_TYPE (rel->r_info))
1582
      {
1583
      case R_X86_64_GNU_VTINHERIT:
1584
      case R_X86_64_GNU_VTENTRY:
1585
        return NULL;
1586
      }
1587
 
1588
  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
1589
}
1590
 
1591
/* Update the got entry reference counts for the section being removed.  */
1592
 
1593
static bfd_boolean
1594
elf64_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
1595
                            asection *sec,
1596
                            const Elf_Internal_Rela *relocs)
1597
{
1598
  Elf_Internal_Shdr *symtab_hdr;
1599
  struct elf_link_hash_entry **sym_hashes;
1600
  bfd_signed_vma *local_got_refcounts;
1601
  const Elf_Internal_Rela *rel, *relend;
1602
 
1603
  if (info->relocatable)
1604
    return TRUE;
1605
 
1606
  elf_section_data (sec)->local_dynrel = NULL;
1607
 
1608
  symtab_hdr = &elf_symtab_hdr (abfd);
1609
  sym_hashes = elf_sym_hashes (abfd);
1610
  local_got_refcounts = elf_local_got_refcounts (abfd);
1611
 
1612
  relend = relocs + sec->reloc_count;
1613
  for (rel = relocs; rel < relend; rel++)
1614
    {
1615
      unsigned long r_symndx;
1616
      unsigned int r_type;
1617
      struct elf_link_hash_entry *h = NULL;
1618
 
1619
      r_symndx = ELF64_R_SYM (rel->r_info);
1620
      if (r_symndx >= symtab_hdr->sh_info)
1621
        {
1622
          struct elf64_x86_64_link_hash_entry *eh;
1623 225 jeremybenn
          struct elf_dyn_relocs **pp;
1624
          struct elf_dyn_relocs *p;
1625 24 jeremybenn
 
1626
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1627
          while (h->root.type == bfd_link_hash_indirect
1628
                 || h->root.type == bfd_link_hash_warning)
1629
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
1630
          eh = (struct elf64_x86_64_link_hash_entry *) h;
1631
 
1632
          for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
1633
            if (p->sec == sec)
1634
              {
1635
                /* Everything must go for SEC.  */
1636
                *pp = p->next;
1637
                break;
1638
              }
1639
        }
1640
 
1641
      r_type = ELF64_R_TYPE (rel->r_info);
1642
      if (! elf64_x86_64_tls_transition (info, abfd, sec, NULL,
1643
                                         symtab_hdr, sym_hashes,
1644
                                         &r_type, GOT_UNKNOWN,
1645 225 jeremybenn
                                         rel, relend, h, r_symndx))
1646 24 jeremybenn
        return FALSE;
1647
 
1648
      switch (r_type)
1649
        {
1650
        case R_X86_64_TLSLD:
1651
          if (elf64_x86_64_hash_table (info)->tls_ld_got.refcount > 0)
1652
            elf64_x86_64_hash_table (info)->tls_ld_got.refcount -= 1;
1653
          break;
1654
 
1655
        case R_X86_64_TLSGD:
1656
        case R_X86_64_GOTPC32_TLSDESC:
1657
        case R_X86_64_TLSDESC_CALL:
1658
        case R_X86_64_GOTTPOFF:
1659
        case R_X86_64_GOT32:
1660
        case R_X86_64_GOTPCREL:
1661
        case R_X86_64_GOT64:
1662
        case R_X86_64_GOTPCREL64:
1663
        case R_X86_64_GOTPLT64:
1664
          if (h != NULL)
1665
            {
1666
              if (r_type == R_X86_64_GOTPLT64 && h->plt.refcount > 0)
1667
                h->plt.refcount -= 1;
1668
              if (h->got.refcount > 0)
1669
                h->got.refcount -= 1;
1670
            }
1671
          else if (local_got_refcounts != NULL)
1672
            {
1673
              if (local_got_refcounts[r_symndx] > 0)
1674
                local_got_refcounts[r_symndx] -= 1;
1675
            }
1676
          break;
1677
 
1678
        case R_X86_64_8:
1679
        case R_X86_64_16:
1680
        case R_X86_64_32:
1681
        case R_X86_64_64:
1682
        case R_X86_64_32S:
1683
        case R_X86_64_PC8:
1684
        case R_X86_64_PC16:
1685
        case R_X86_64_PC32:
1686
        case R_X86_64_PC64:
1687
          if (info->shared)
1688
            break;
1689
          /* Fall thru */
1690
 
1691
        case R_X86_64_PLT32:
1692
        case R_X86_64_PLTOFF64:
1693
          if (h != NULL)
1694
            {
1695
              if (h->plt.refcount > 0)
1696
                h->plt.refcount -= 1;
1697
            }
1698
          break;
1699
 
1700
        default:
1701
          break;
1702
        }
1703
    }
1704
 
1705
  return TRUE;
1706
}
1707
 
1708
/* Adjust a symbol defined by a dynamic object and referenced by a
1709
   regular object.  The current definition is in some section of the
1710
   dynamic object, but we're not including those sections.  We have to
1711
   change the definition to something the rest of the link can
1712
   understand.  */
1713
 
1714
static bfd_boolean
1715
elf64_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
1716
                                    struct elf_link_hash_entry *h)
1717
{
1718
  struct elf64_x86_64_link_hash_table *htab;
1719
  asection *s;
1720
 
1721 225 jeremybenn
  /* STT_GNU_IFUNC symbol must go through PLT. */
1722
  if (h->type == STT_GNU_IFUNC)
1723
    {
1724
      if (h->plt.refcount <= 0)
1725
        {
1726
          h->plt.offset = (bfd_vma) -1;
1727
          h->needs_plt = 0;
1728
        }
1729
      return TRUE;
1730
    }
1731
 
1732 24 jeremybenn
  /* If this is a function, put it in the procedure linkage table.  We
1733
     will fill in the contents of the procedure linkage table later,
1734
     when we know the address of the .got section.  */
1735
  if (h->type == STT_FUNC
1736
      || h->needs_plt)
1737
    {
1738
      if (h->plt.refcount <= 0
1739
          || SYMBOL_CALLS_LOCAL (info, h)
1740
          || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1741
              && h->root.type == bfd_link_hash_undefweak))
1742
        {
1743
          /* This case can occur if we saw a PLT32 reloc in an input
1744
             file, but the symbol was never referred to by a dynamic
1745
             object, or if all references were garbage collected.  In
1746
             such a case, we don't actually need to build a procedure
1747
             linkage table, and we can just do a PC32 reloc instead.  */
1748
          h->plt.offset = (bfd_vma) -1;
1749
          h->needs_plt = 0;
1750
        }
1751
 
1752
      return TRUE;
1753
    }
1754
  else
1755
    /* It's possible that we incorrectly decided a .plt reloc was
1756
       needed for an R_X86_64_PC32 reloc to a non-function sym in
1757
       check_relocs.  We can't decide accurately between function and
1758
       non-function syms in check-relocs;  Objects loaded later in
1759
       the link may change h->type.  So fix it now.  */
1760
    h->plt.offset = (bfd_vma) -1;
1761
 
1762
  /* If this is a weak symbol, and there is a real definition, the
1763
     processor independent code will have arranged for us to see the
1764
     real definition first, and we can just use the same value.  */
1765
  if (h->u.weakdef != NULL)
1766
    {
1767
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
1768
                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
1769
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
1770
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
1771
      if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
1772
        h->non_got_ref = h->u.weakdef->non_got_ref;
1773
      return TRUE;
1774
    }
1775
 
1776
  /* This is a reference to a symbol defined by a dynamic object which
1777
     is not a function.  */
1778
 
1779
  /* If we are creating a shared library, we must presume that the
1780
     only references to the symbol are via the global offset table.
1781
     For such cases we need not do anything here; the relocations will
1782
     be handled correctly by relocate_section.  */
1783
  if (info->shared)
1784
    return TRUE;
1785
 
1786
  /* If there are no references to this symbol that do not use the
1787
     GOT, we don't need to generate a copy reloc.  */
1788
  if (!h->non_got_ref)
1789
    return TRUE;
1790
 
1791
  /* If -z nocopyreloc was given, we won't generate them either.  */
1792
  if (info->nocopyreloc)
1793
    {
1794
      h->non_got_ref = 0;
1795
      return TRUE;
1796
    }
1797
 
1798
  if (ELIMINATE_COPY_RELOCS)
1799
    {
1800
      struct elf64_x86_64_link_hash_entry * eh;
1801 225 jeremybenn
      struct elf_dyn_relocs *p;
1802 24 jeremybenn
 
1803
      eh = (struct elf64_x86_64_link_hash_entry *) h;
1804
      for (p = eh->dyn_relocs; p != NULL; p = p->next)
1805
        {
1806
          s = p->sec->output_section;
1807
          if (s != NULL && (s->flags & SEC_READONLY) != 0)
1808
            break;
1809
        }
1810
 
1811
      /* If we didn't find any dynamic relocs in read-only sections, then
1812
         we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
1813
      if (p == NULL)
1814
        {
1815
          h->non_got_ref = 0;
1816
          return TRUE;
1817
        }
1818
    }
1819
 
1820
  if (h->size == 0)
1821
    {
1822
      (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
1823
                             h->root.root.string);
1824
      return TRUE;
1825
    }
1826
 
1827
  /* We must allocate the symbol in our .dynbss section, which will
1828
     become part of the .bss section of the executable.  There will be
1829
     an entry for this symbol in the .dynsym section.  The dynamic
1830
     object will contain position independent code, so all references
1831
     from the dynamic object to this symbol will go through the global
1832
     offset table.  The dynamic linker will use the .dynsym entry to
1833
     determine the address it must put in the global offset table, so
1834
     both the dynamic object and the regular object will refer to the
1835
     same memory location for the variable.  */
1836
 
1837
  htab = elf64_x86_64_hash_table (info);
1838
 
1839
  /* We must generate a R_X86_64_COPY reloc to tell the dynamic linker
1840
     to copy the initial value out of the dynamic object and into the
1841
     runtime process image.  */
1842
  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
1843
    {
1844
      htab->srelbss->size += sizeof (Elf64_External_Rela);
1845
      h->needs_copy = 1;
1846
    }
1847
 
1848
  s = htab->sdynbss;
1849
 
1850
  return _bfd_elf_adjust_dynamic_copy (h, s);
1851
}
1852
 
1853
/* Allocate space in .plt, .got and associated reloc sections for
1854
   dynamic relocs.  */
1855
 
1856
static bfd_boolean
1857 225 jeremybenn
elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
1858 24 jeremybenn
{
1859
  struct bfd_link_info *info;
1860
  struct elf64_x86_64_link_hash_table *htab;
1861
  struct elf64_x86_64_link_hash_entry *eh;
1862 225 jeremybenn
  struct elf_dyn_relocs *p;
1863 24 jeremybenn
 
1864
  if (h->root.type == bfd_link_hash_indirect)
1865
    return TRUE;
1866
 
1867
  if (h->root.type == bfd_link_hash_warning)
1868
    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1869 225 jeremybenn
  eh = (struct elf64_x86_64_link_hash_entry *) h;
1870 24 jeremybenn
 
1871
  info = (struct bfd_link_info *) inf;
1872
  htab = elf64_x86_64_hash_table (info);
1873
 
1874 225 jeremybenn
  /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1875
     here if it is defined and referenced in a non-shared object.  */
1876
  if (h->type == STT_GNU_IFUNC
1877
      && h->def_regular)
1878
    return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
1879
                                               &eh->dyn_relocs,
1880
                                               PLT_ENTRY_SIZE,
1881
                                               GOT_ENTRY_SIZE);
1882
  else if (htab->elf.dynamic_sections_created
1883
           && h->plt.refcount > 0)
1884 24 jeremybenn
    {
1885
      /* Make sure this symbol is output as a dynamic symbol.
1886
         Undefined weak syms won't yet be marked as dynamic.  */
1887
      if (h->dynindx == -1
1888
          && !h->forced_local)
1889
        {
1890
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
1891
            return FALSE;
1892
        }
1893
 
1894
      if (info->shared
1895
          || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
1896
        {
1897 225 jeremybenn
          asection *s = htab->elf.splt;
1898 24 jeremybenn
 
1899
          /* If this is the first .plt entry, make room for the special
1900
             first entry.  */
1901
          if (s->size == 0)
1902
            s->size += PLT_ENTRY_SIZE;
1903
 
1904
          h->plt.offset = s->size;
1905
 
1906
          /* If this symbol is not defined in a regular file, and we are
1907
             not generating a shared library, then set the symbol to this
1908
             location in the .plt.  This is required to make function
1909
             pointers compare as equal between the normal executable and
1910
             the shared library.  */
1911
          if (! info->shared
1912
              && !h->def_regular)
1913
            {
1914
              h->root.u.def.section = s;
1915
              h->root.u.def.value = h->plt.offset;
1916
            }
1917
 
1918
          /* Make room for this entry.  */
1919
          s->size += PLT_ENTRY_SIZE;
1920
 
1921
          /* We also need to make an entry in the .got.plt section, which
1922
             will be placed in the .got section by the linker script.  */
1923 225 jeremybenn
          htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
1924 24 jeremybenn
 
1925
          /* We also need to make an entry in the .rela.plt section.  */
1926 225 jeremybenn
          htab->elf.srelplt->size += sizeof (Elf64_External_Rela);
1927
          htab->elf.srelplt->reloc_count++;
1928 24 jeremybenn
        }
1929
      else
1930
        {
1931
          h->plt.offset = (bfd_vma) -1;
1932
          h->needs_plt = 0;
1933
        }
1934
    }
1935
  else
1936
    {
1937
      h->plt.offset = (bfd_vma) -1;
1938
      h->needs_plt = 0;
1939
    }
1940
 
1941
  eh->tlsdesc_got = (bfd_vma) -1;
1942
 
1943
  /* If R_X86_64_GOTTPOFF symbol is now local to the binary,
1944
     make it a R_X86_64_TPOFF32 requiring no GOT entry.  */
1945
  if (h->got.refcount > 0
1946 225 jeremybenn
      && info->executable
1947 24 jeremybenn
      && h->dynindx == -1
1948
      && elf64_x86_64_hash_entry (h)->tls_type == GOT_TLS_IE)
1949 225 jeremybenn
    {
1950
      h->got.offset = (bfd_vma) -1;
1951
    }
1952 24 jeremybenn
  else if (h->got.refcount > 0)
1953
    {
1954
      asection *s;
1955
      bfd_boolean dyn;
1956
      int tls_type = elf64_x86_64_hash_entry (h)->tls_type;
1957
 
1958
      /* Make sure this symbol is output as a dynamic symbol.
1959
         Undefined weak syms won't yet be marked as dynamic.  */
1960
      if (h->dynindx == -1
1961
          && !h->forced_local)
1962
        {
1963
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
1964
            return FALSE;
1965
        }
1966
 
1967
      if (GOT_TLS_GDESC_P (tls_type))
1968
        {
1969 225 jeremybenn
          eh->tlsdesc_got = htab->elf.sgotplt->size
1970 24 jeremybenn
            - elf64_x86_64_compute_jump_table_size (htab);
1971 225 jeremybenn
          htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
1972 24 jeremybenn
          h->got.offset = (bfd_vma) -2;
1973
        }
1974
      if (! GOT_TLS_GDESC_P (tls_type)
1975
          || GOT_TLS_GD_P (tls_type))
1976
        {
1977 225 jeremybenn
          s = htab->elf.sgot;
1978 24 jeremybenn
          h->got.offset = s->size;
1979
          s->size += GOT_ENTRY_SIZE;
1980
          if (GOT_TLS_GD_P (tls_type))
1981
            s->size += GOT_ENTRY_SIZE;
1982
        }
1983
      dyn = htab->elf.dynamic_sections_created;
1984
      /* R_X86_64_TLSGD needs one dynamic relocation if local symbol
1985
         and two if global.
1986
         R_X86_64_GOTTPOFF needs one dynamic relocation.  */
1987
      if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
1988
          || tls_type == GOT_TLS_IE)
1989 225 jeremybenn
        htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
1990 24 jeremybenn
      else if (GOT_TLS_GD_P (tls_type))
1991 225 jeremybenn
        htab->elf.srelgot->size += 2 * sizeof (Elf64_External_Rela);
1992 24 jeremybenn
      else if (! GOT_TLS_GDESC_P (tls_type)
1993
               && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1994
                   || h->root.type != bfd_link_hash_undefweak)
1995
               && (info->shared
1996
                   || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
1997 225 jeremybenn
        htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
1998 24 jeremybenn
      if (GOT_TLS_GDESC_P (tls_type))
1999
        {
2000 225 jeremybenn
          htab->elf.srelplt->size += sizeof (Elf64_External_Rela);
2001 24 jeremybenn
          htab->tlsdesc_plt = (bfd_vma) -1;
2002
        }
2003
    }
2004
  else
2005
    h->got.offset = (bfd_vma) -1;
2006
 
2007
  if (eh->dyn_relocs == NULL)
2008
    return TRUE;
2009
 
2010
  /* In the shared -Bsymbolic case, discard space allocated for
2011
     dynamic pc-relative relocs against symbols which turn out to be
2012
     defined in regular objects.  For the normal shared case, discard
2013
     space for pc-relative relocs that have become local due to symbol
2014
     visibility changes.  */
2015
 
2016
  if (info->shared)
2017
    {
2018
      /* Relocs that use pc_count are those that appear on a call
2019
         insn, or certain REL relocs that can generated via assembly.
2020
         We want calls to protected symbols to resolve directly to the
2021
         function rather than going via the plt.  If people want
2022
         function pointer comparisons to work as expected then they
2023
         should avoid writing weird assembly.  */
2024
      if (SYMBOL_CALLS_LOCAL (info, h))
2025
        {
2026 225 jeremybenn
          struct elf_dyn_relocs **pp;
2027 24 jeremybenn
 
2028
          for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
2029
            {
2030
              p->count -= p->pc_count;
2031
              p->pc_count = 0;
2032
              if (p->count == 0)
2033
                *pp = p->next;
2034
              else
2035
                pp = &p->next;
2036
            }
2037
        }
2038
 
2039
      /* Also discard relocs on undefined weak syms with non-default
2040
         visibility.  */
2041
      if (eh->dyn_relocs != NULL
2042
          && h->root.type == bfd_link_hash_undefweak)
2043
        {
2044
          if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
2045
            eh->dyn_relocs = NULL;
2046
 
2047
          /* Make sure undefined weak symbols are output as a dynamic
2048
             symbol in PIEs.  */
2049
          else if (h->dynindx == -1
2050 225 jeremybenn
                   && ! h->forced_local
2051
                   && ! bfd_elf_link_record_dynamic_symbol (info, h))
2052
            return FALSE;
2053 24 jeremybenn
        }
2054 225 jeremybenn
 
2055 24 jeremybenn
    }
2056
  else if (ELIMINATE_COPY_RELOCS)
2057
    {
2058
      /* For the non-shared case, discard space for relocs against
2059
         symbols which turn out to need copy relocs or are not
2060
         dynamic.  */
2061
 
2062
      if (!h->non_got_ref
2063
          && ((h->def_dynamic
2064
               && !h->def_regular)
2065
              || (htab->elf.dynamic_sections_created
2066
                  && (h->root.type == bfd_link_hash_undefweak
2067
                      || h->root.type == bfd_link_hash_undefined))))
2068
        {
2069
          /* Make sure this symbol is output as a dynamic symbol.
2070
             Undefined weak syms won't yet be marked as dynamic.  */
2071
          if (h->dynindx == -1
2072 225 jeremybenn
              && ! h->forced_local
2073
              && ! bfd_elf_link_record_dynamic_symbol (info, h))
2074
            return FALSE;
2075 24 jeremybenn
 
2076
          /* If that succeeded, we know we'll be keeping all the
2077
             relocs.  */
2078
          if (h->dynindx != -1)
2079
            goto keep;
2080
        }
2081
 
2082
      eh->dyn_relocs = NULL;
2083
 
2084
    keep: ;
2085
    }
2086
 
2087
  /* Finally, allocate space.  */
2088
  for (p = eh->dyn_relocs; p != NULL; p = p->next)
2089
    {
2090 225 jeremybenn
      asection * sreloc;
2091
 
2092
      sreloc = elf_section_data (p->sec)->sreloc;
2093
 
2094
      BFD_ASSERT (sreloc != NULL);
2095
 
2096 24 jeremybenn
      sreloc->size += p->count * sizeof (Elf64_External_Rela);
2097
    }
2098
 
2099
  return TRUE;
2100
}
2101
 
2102 225 jeremybenn
/* Allocate space in .plt, .got and associated reloc sections for
2103
   local dynamic relocs.  */
2104
 
2105
static bfd_boolean
2106
elf64_x86_64_allocate_local_dynrelocs (void **slot, void *inf)
2107
{
2108
  struct elf_link_hash_entry *h
2109
    = (struct elf_link_hash_entry *) *slot;
2110
 
2111
  if (h->type != STT_GNU_IFUNC
2112
      || !h->def_regular
2113
      || !h->ref_regular
2114
      || !h->forced_local
2115
      || h->root.type != bfd_link_hash_defined)
2116
    abort ();
2117
 
2118
  return elf64_x86_64_allocate_dynrelocs (h, inf);
2119
}
2120
 
2121 24 jeremybenn
/* Find any dynamic relocs that apply to read-only sections.  */
2122
 
2123
static bfd_boolean
2124 225 jeremybenn
elf64_x86_64_readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
2125 24 jeremybenn
{
2126
  struct elf64_x86_64_link_hash_entry *eh;
2127 225 jeremybenn
  struct elf_dyn_relocs *p;
2128 24 jeremybenn
 
2129
  if (h->root.type == bfd_link_hash_warning)
2130
    h = (struct elf_link_hash_entry *) h->root.u.i.link;
2131
 
2132
  eh = (struct elf64_x86_64_link_hash_entry *) h;
2133
  for (p = eh->dyn_relocs; p != NULL; p = p->next)
2134
    {
2135
      asection *s = p->sec->output_section;
2136
 
2137
      if (s != NULL && (s->flags & SEC_READONLY) != 0)
2138
        {
2139
          struct bfd_link_info *info = (struct bfd_link_info *) inf;
2140
 
2141
          info->flags |= DF_TEXTREL;
2142
 
2143
          /* Not an error, just cut short the traversal.  */
2144
          return FALSE;
2145
        }
2146
    }
2147
  return TRUE;
2148
}
2149
 
2150
/* Set the sizes of the dynamic sections.  */
2151
 
2152
static bfd_boolean
2153
elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2154
                                    struct bfd_link_info *info)
2155
{
2156
  struct elf64_x86_64_link_hash_table *htab;
2157
  bfd *dynobj;
2158
  asection *s;
2159
  bfd_boolean relocs;
2160
  bfd *ibfd;
2161
 
2162
  htab = elf64_x86_64_hash_table (info);
2163
  dynobj = htab->elf.dynobj;
2164
  if (dynobj == NULL)
2165
    abort ();
2166
 
2167
  if (htab->elf.dynamic_sections_created)
2168
    {
2169
      /* Set the contents of the .interp section to the interpreter.  */
2170
      if (info->executable)
2171
        {
2172
          s = bfd_get_section_by_name (dynobj, ".interp");
2173
          if (s == NULL)
2174
            abort ();
2175
          s->size = sizeof ELF_DYNAMIC_INTERPRETER;
2176
          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2177
        }
2178
    }
2179
 
2180
  /* Set up .got offsets for local syms, and space for local dynamic
2181
     relocs.  */
2182
  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
2183
    {
2184
      bfd_signed_vma *local_got;
2185
      bfd_signed_vma *end_local_got;
2186
      char *local_tls_type;
2187
      bfd_vma *local_tlsdesc_gotent;
2188
      bfd_size_type locsymcount;
2189
      Elf_Internal_Shdr *symtab_hdr;
2190
      asection *srel;
2191
 
2192
      if (! is_x86_64_elf (ibfd))
2193
        continue;
2194
 
2195
      for (s = ibfd->sections; s != NULL; s = s->next)
2196
        {
2197 225 jeremybenn
          struct elf_dyn_relocs *p;
2198 24 jeremybenn
 
2199 225 jeremybenn
          for (p = (struct elf_dyn_relocs *)
2200 24 jeremybenn
                    (elf_section_data (s)->local_dynrel);
2201
               p != NULL;
2202
               p = p->next)
2203
            {
2204
              if (!bfd_is_abs_section (p->sec)
2205
                  && bfd_is_abs_section (p->sec->output_section))
2206
                {
2207
                  /* Input section has been discarded, either because
2208
                     it is a copy of a linkonce section or due to
2209
                     linker script /DISCARD/, so we'll be discarding
2210
                     the relocs too.  */
2211
                }
2212
              else if (p->count != 0)
2213
                {
2214
                  srel = elf_section_data (p->sec)->sreloc;
2215
                  srel->size += p->count * sizeof (Elf64_External_Rela);
2216
                  if ((p->sec->output_section->flags & SEC_READONLY) != 0)
2217
                    info->flags |= DF_TEXTREL;
2218
                }
2219
            }
2220
        }
2221
 
2222
      local_got = elf_local_got_refcounts (ibfd);
2223
      if (!local_got)
2224
        continue;
2225
 
2226
      symtab_hdr = &elf_symtab_hdr (ibfd);
2227
      locsymcount = symtab_hdr->sh_info;
2228
      end_local_got = local_got + locsymcount;
2229
      local_tls_type = elf64_x86_64_local_got_tls_type (ibfd);
2230
      local_tlsdesc_gotent = elf64_x86_64_local_tlsdesc_gotent (ibfd);
2231 225 jeremybenn
      s = htab->elf.sgot;
2232
      srel = htab->elf.srelgot;
2233 24 jeremybenn
      for (; local_got < end_local_got;
2234
           ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
2235
        {
2236
          *local_tlsdesc_gotent = (bfd_vma) -1;
2237
          if (*local_got > 0)
2238
            {
2239
              if (GOT_TLS_GDESC_P (*local_tls_type))
2240
                {
2241 225 jeremybenn
                  *local_tlsdesc_gotent = htab->elf.sgotplt->size
2242 24 jeremybenn
                    - elf64_x86_64_compute_jump_table_size (htab);
2243 225 jeremybenn
                  htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
2244 24 jeremybenn
                  *local_got = (bfd_vma) -2;
2245
                }
2246
              if (! GOT_TLS_GDESC_P (*local_tls_type)
2247
                  || GOT_TLS_GD_P (*local_tls_type))
2248
                {
2249
                  *local_got = s->size;
2250
                  s->size += GOT_ENTRY_SIZE;
2251
                  if (GOT_TLS_GD_P (*local_tls_type))
2252
                    s->size += GOT_ENTRY_SIZE;
2253
                }
2254
              if (info->shared
2255
                  || GOT_TLS_GD_ANY_P (*local_tls_type)
2256
                  || *local_tls_type == GOT_TLS_IE)
2257
                {
2258
                  if (GOT_TLS_GDESC_P (*local_tls_type))
2259
                    {
2260 225 jeremybenn
                      htab->elf.srelplt->size
2261
                        += sizeof (Elf64_External_Rela);
2262 24 jeremybenn
                      htab->tlsdesc_plt = (bfd_vma) -1;
2263
                    }
2264
                  if (! GOT_TLS_GDESC_P (*local_tls_type)
2265
                      || GOT_TLS_GD_P (*local_tls_type))
2266
                    srel->size += sizeof (Elf64_External_Rela);
2267
                }
2268
            }
2269
          else
2270
            *local_got = (bfd_vma) -1;
2271
        }
2272
    }
2273
 
2274
  if (htab->tls_ld_got.refcount > 0)
2275
    {
2276
      /* Allocate 2 got entries and 1 dynamic reloc for R_X86_64_TLSLD
2277
         relocs.  */
2278 225 jeremybenn
      htab->tls_ld_got.offset = htab->elf.sgot->size;
2279
      htab->elf.sgot->size += 2 * GOT_ENTRY_SIZE;
2280
      htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
2281 24 jeremybenn
    }
2282
  else
2283
    htab->tls_ld_got.offset = -1;
2284
 
2285
  /* Allocate global sym .plt and .got entries, and space for global
2286
     sym dynamic relocs.  */
2287 225 jeremybenn
  elf_link_hash_traverse (&htab->elf, elf64_x86_64_allocate_dynrelocs,
2288
                          info);
2289 24 jeremybenn
 
2290 225 jeremybenn
  /* Allocate .plt and .got entries, and space for local symbols.  */
2291
  htab_traverse (htab->loc_hash_table,
2292
                 elf64_x86_64_allocate_local_dynrelocs,
2293
                 info);
2294
 
2295 24 jeremybenn
  /* For every jump slot reserved in the sgotplt, reloc_count is
2296
     incremented.  However, when we reserve space for TLS descriptors,
2297
     it's not incremented, so in order to compute the space reserved
2298
     for them, it suffices to multiply the reloc count by the jump
2299
     slot size.  */
2300 225 jeremybenn
  if (htab->elf.srelplt)
2301 24 jeremybenn
    htab->sgotplt_jump_table_size
2302
      = elf64_x86_64_compute_jump_table_size (htab);
2303
 
2304
  if (htab->tlsdesc_plt)
2305
    {
2306
      /* If we're not using lazy TLS relocations, don't generate the
2307
         PLT and GOT entries they require.  */
2308
      if ((info->flags & DF_BIND_NOW))
2309
        htab->tlsdesc_plt = 0;
2310
      else
2311
        {
2312 225 jeremybenn
          htab->tlsdesc_got = htab->elf.sgot->size;
2313
          htab->elf.sgot->size += GOT_ENTRY_SIZE;
2314 24 jeremybenn
          /* Reserve room for the initial entry.
2315
             FIXME: we could probably do away with it in this case.  */
2316 225 jeremybenn
          if (htab->elf.splt->size == 0)
2317
            htab->elf.splt->size += PLT_ENTRY_SIZE;
2318
          htab->tlsdesc_plt = htab->elf.splt->size;
2319
          htab->elf.splt->size += PLT_ENTRY_SIZE;
2320 24 jeremybenn
        }
2321
    }
2322
 
2323
  /* We now have determined the sizes of the various dynamic sections.
2324
     Allocate memory for them.  */
2325
  relocs = FALSE;
2326
  for (s = dynobj->sections; s != NULL; s = s->next)
2327
    {
2328
      if ((s->flags & SEC_LINKER_CREATED) == 0)
2329
        continue;
2330
 
2331 225 jeremybenn
      if (s == htab->elf.splt
2332
          || s == htab->elf.sgot
2333
          || s == htab->elf.sgotplt
2334
          || s == htab->elf.iplt
2335
          || s == htab->elf.igotplt
2336 24 jeremybenn
          || s == htab->sdynbss)
2337
        {
2338
          /* Strip this section if we don't need it; see the
2339
             comment below.  */
2340
        }
2341
      else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
2342
        {
2343 225 jeremybenn
          if (s->size != 0 && s != htab->elf.srelplt)
2344 24 jeremybenn
            relocs = TRUE;
2345
 
2346
          /* We use the reloc_count field as a counter if we need
2347
             to copy relocs into the output file.  */
2348 225 jeremybenn
          if (s != htab->elf.srelplt)
2349 24 jeremybenn
            s->reloc_count = 0;
2350
        }
2351
      else
2352
        {
2353
          /* It's not one of our sections, so don't allocate space.  */
2354
          continue;
2355
        }
2356
 
2357
      if (s->size == 0)
2358
        {
2359
          /* If we don't need this section, strip it from the
2360
             output file.  This is mostly to handle .rela.bss and
2361
             .rela.plt.  We must create both sections in
2362
             create_dynamic_sections, because they must be created
2363
             before the linker maps input sections to output
2364
             sections.  The linker does that before
2365
             adjust_dynamic_symbol is called, and it is that
2366
             function which decides whether anything needs to go
2367
             into these sections.  */
2368
 
2369
          s->flags |= SEC_EXCLUDE;
2370
          continue;
2371
        }
2372
 
2373
      if ((s->flags & SEC_HAS_CONTENTS) == 0)
2374
        continue;
2375
 
2376
      /* Allocate memory for the section contents.  We use bfd_zalloc
2377
         here in case unused entries are not reclaimed before the
2378
         section's contents are written out.  This should not happen,
2379
         but this way if it does, we get a R_X86_64_NONE reloc instead
2380
         of garbage.  */
2381
      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2382
      if (s->contents == NULL)
2383
        return FALSE;
2384
    }
2385
 
2386
  if (htab->elf.dynamic_sections_created)
2387
    {
2388
      /* Add some entries to the .dynamic section.  We fill in the
2389
         values later, in elf64_x86_64_finish_dynamic_sections, but we
2390
         must add the entries now so that we get the correct size for
2391
         the .dynamic section.  The DT_DEBUG entry is filled in by the
2392
         dynamic linker and used by the debugger.  */
2393
#define add_dynamic_entry(TAG, VAL) \
2394
  _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2395
 
2396
      if (info->executable)
2397
        {
2398
          if (!add_dynamic_entry (DT_DEBUG, 0))
2399
            return FALSE;
2400
        }
2401
 
2402 225 jeremybenn
      if (htab->elf.splt->size != 0)
2403 24 jeremybenn
        {
2404
          if (!add_dynamic_entry (DT_PLTGOT, 0)
2405
              || !add_dynamic_entry (DT_PLTRELSZ, 0)
2406
              || !add_dynamic_entry (DT_PLTREL, DT_RELA)
2407
              || !add_dynamic_entry (DT_JMPREL, 0))
2408
            return FALSE;
2409
 
2410
          if (htab->tlsdesc_plt
2411
              && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
2412
                  || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
2413
            return FALSE;
2414
        }
2415
 
2416
      if (relocs)
2417
        {
2418
          if (!add_dynamic_entry (DT_RELA, 0)
2419
              || !add_dynamic_entry (DT_RELASZ, 0)
2420
              || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
2421
            return FALSE;
2422
 
2423
          /* If any dynamic relocs apply to a read-only section,
2424
             then we need a DT_TEXTREL entry.  */
2425
          if ((info->flags & DF_TEXTREL) == 0)
2426 225 jeremybenn
            elf_link_hash_traverse (&htab->elf,
2427
                                    elf64_x86_64_readonly_dynrelocs,
2428
                                    info);
2429 24 jeremybenn
 
2430
          if ((info->flags & DF_TEXTREL) != 0)
2431
            {
2432
              if (!add_dynamic_entry (DT_TEXTREL, 0))
2433
                return FALSE;
2434
            }
2435
        }
2436
    }
2437
#undef add_dynamic_entry
2438
 
2439
  return TRUE;
2440
}
2441
 
2442
static bfd_boolean
2443
elf64_x86_64_always_size_sections (bfd *output_bfd,
2444
                                   struct bfd_link_info *info)
2445
{
2446
  asection *tls_sec = elf_hash_table (info)->tls_sec;
2447
 
2448
  if (tls_sec)
2449
    {
2450
      struct elf_link_hash_entry *tlsbase;
2451
 
2452
      tlsbase = elf_link_hash_lookup (elf_hash_table (info),
2453
                                      "_TLS_MODULE_BASE_",
2454
                                      FALSE, FALSE, FALSE);
2455
 
2456
      if (tlsbase && tlsbase->type == STT_TLS)
2457
        {
2458
          struct bfd_link_hash_entry *bh = NULL;
2459
          const struct elf_backend_data *bed
2460
            = get_elf_backend_data (output_bfd);
2461
 
2462
          if (!(_bfd_generic_link_add_one_symbol
2463
                (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
2464
                 tls_sec, 0, NULL, FALSE,
2465
                 bed->collect, &bh)))
2466
            return FALSE;
2467 225 jeremybenn
 
2468
          elf64_x86_64_hash_table (info)->tls_module_base = bh;
2469
 
2470 24 jeremybenn
          tlsbase = (struct elf_link_hash_entry *)bh;
2471
          tlsbase->def_regular = 1;
2472
          tlsbase->other = STV_HIDDEN;
2473
          (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
2474
        }
2475
    }
2476
 
2477
  return TRUE;
2478
}
2479
 
2480 225 jeremybenn
/* _TLS_MODULE_BASE_ needs to be treated especially when linking
2481
   executables.  Rather than setting it to the beginning of the TLS
2482
   section, we have to set it to the end.  This function may be called
2483
   multiple times, it is idempotent.  */
2484
 
2485
static void
2486
elf64_x86_64_set_tls_module_base (struct bfd_link_info *info)
2487
{
2488
  struct bfd_link_hash_entry *base;
2489
 
2490
  if (!info->executable)
2491
    return;
2492
 
2493
  base = elf64_x86_64_hash_table (info)->tls_module_base;
2494
 
2495
  if (!base)
2496
    return;
2497
 
2498
  base->u.def.value = elf_hash_table (info)->tls_size;
2499
}
2500
 
2501 24 jeremybenn
/* Return the base VMA address which should be subtracted from real addresses
2502
   when resolving @dtpoff relocation.
2503
   This is PT_TLS segment p_vaddr.  */
2504
 
2505
static bfd_vma
2506 225 jeremybenn
elf64_x86_64_dtpoff_base (struct bfd_link_info *info)
2507 24 jeremybenn
{
2508
  /* If tls_sec is NULL, we should have signalled an error already.  */
2509
  if (elf_hash_table (info)->tls_sec == NULL)
2510
    return 0;
2511
  return elf_hash_table (info)->tls_sec->vma;
2512
}
2513
 
2514
/* Return the relocation value for @tpoff relocation
2515
   if STT_TLS virtual address is ADDRESS.  */
2516
 
2517
static bfd_vma
2518 225 jeremybenn
elf64_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address)
2519 24 jeremybenn
{
2520
  struct elf_link_hash_table *htab = elf_hash_table (info);
2521
 
2522
  /* If tls_segment is NULL, we should have signalled an error already.  */
2523
  if (htab->tls_sec == NULL)
2524
    return 0;
2525
  return address - htab->tls_size - htab->tls_sec->vma;
2526
}
2527
 
2528
/* Is the instruction before OFFSET in CONTENTS a 32bit relative
2529
   branch?  */
2530
 
2531
static bfd_boolean
2532
is_32bit_relative_branch (bfd_byte *contents, bfd_vma offset)
2533
{
2534
  /* Opcode             Instruction
2535
     0xe8               call
2536
     0xe9               jump
2537
     0x0f 0x8x          conditional jump */
2538
  return ((offset > 0
2539
           && (contents [offset - 1] == 0xe8
2540
               || contents [offset - 1] == 0xe9))
2541
          || (offset > 1
2542
              && contents [offset - 2] == 0x0f
2543
              && (contents [offset - 1] & 0xf0) == 0x80));
2544
}
2545
 
2546
/* Relocate an x86_64 ELF section.  */
2547
 
2548
static bfd_boolean
2549
elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
2550
                               bfd *input_bfd, asection *input_section,
2551
                               bfd_byte *contents, Elf_Internal_Rela *relocs,
2552
                               Elf_Internal_Sym *local_syms,
2553
                               asection **local_sections)
2554
{
2555
  struct elf64_x86_64_link_hash_table *htab;
2556
  Elf_Internal_Shdr *symtab_hdr;
2557
  struct elf_link_hash_entry **sym_hashes;
2558
  bfd_vma *local_got_offsets;
2559
  bfd_vma *local_tlsdesc_gotents;
2560
  Elf_Internal_Rela *rel;
2561
  Elf_Internal_Rela *relend;
2562
 
2563
  BFD_ASSERT (is_x86_64_elf (input_bfd));
2564
 
2565
  htab = elf64_x86_64_hash_table (info);
2566
  symtab_hdr = &elf_symtab_hdr (input_bfd);
2567
  sym_hashes = elf_sym_hashes (input_bfd);
2568
  local_got_offsets = elf_local_got_offsets (input_bfd);
2569
  local_tlsdesc_gotents = elf64_x86_64_local_tlsdesc_gotent (input_bfd);
2570
 
2571 225 jeremybenn
  elf64_x86_64_set_tls_module_base (info);
2572
 
2573 24 jeremybenn
  rel = relocs;
2574
  relend = relocs + input_section->reloc_count;
2575
  for (; rel < relend; rel++)
2576
    {
2577
      unsigned int r_type;
2578
      reloc_howto_type *howto;
2579
      unsigned long r_symndx;
2580
      struct elf_link_hash_entry *h;
2581
      Elf_Internal_Sym *sym;
2582
      asection *sec;
2583
      bfd_vma off, offplt;
2584
      bfd_vma relocation;
2585
      bfd_boolean unresolved_reloc;
2586
      bfd_reloc_status_type r;
2587
      int tls_type;
2588 225 jeremybenn
      asection *base_got;
2589 24 jeremybenn
 
2590
      r_type = ELF64_R_TYPE (rel->r_info);
2591
      if (r_type == (int) R_X86_64_GNU_VTINHERIT
2592
          || r_type == (int) R_X86_64_GNU_VTENTRY)
2593
        continue;
2594
 
2595
      if (r_type >= R_X86_64_max)
2596
        {
2597
          bfd_set_error (bfd_error_bad_value);
2598
          return FALSE;
2599
        }
2600
 
2601
      howto = x86_64_elf_howto_table + r_type;
2602
      r_symndx = ELF64_R_SYM (rel->r_info);
2603
      h = NULL;
2604
      sym = NULL;
2605
      sec = NULL;
2606
      unresolved_reloc = FALSE;
2607
      if (r_symndx < symtab_hdr->sh_info)
2608
        {
2609
          sym = local_syms + r_symndx;
2610
          sec = local_sections[r_symndx];
2611
 
2612 225 jeremybenn
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym,
2613
                                                &sec, rel);
2614
 
2615
          /* Relocate against local STT_GNU_IFUNC symbol.  */
2616
          if (!info->relocatable
2617
              && ELF64_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2618
            {
2619
              h = elf64_x86_64_get_local_sym_hash (htab, input_bfd,
2620
                                                   rel, FALSE);
2621
              if (h == NULL)
2622
                abort ();
2623
 
2624
              /* Set STT_GNU_IFUNC symbol value.  */
2625
              h->root.u.def.value = sym->st_value;
2626
              h->root.u.def.section = sec;
2627
            }
2628 24 jeremybenn
        }
2629
      else
2630
        {
2631
          bfd_boolean warned;
2632
 
2633
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2634
                                   r_symndx, symtab_hdr, sym_hashes,
2635
                                   h, sec, relocation,
2636
                                   unresolved_reloc, warned);
2637
        }
2638
 
2639
      if (sec != NULL && elf_discarded_section (sec))
2640
        {
2641
          /* For relocs against symbols from removed linkonce sections,
2642
             or sections discarded by a linker script, we just want the
2643
             section contents zeroed.  Avoid any special processing.  */
2644
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
2645
          rel->r_info = 0;
2646
          rel->r_addend = 0;
2647
          continue;
2648
        }
2649
 
2650
      if (info->relocatable)
2651
        continue;
2652
 
2653 225 jeremybenn
      /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
2654
         it here if it is defined in a non-shared object.  */
2655
      if (h != NULL
2656
          && h->type == STT_GNU_IFUNC
2657
          && h->def_regular)
2658
        {
2659
          asection *plt;
2660
          bfd_vma plt_index;
2661
          const char *name;
2662
 
2663
          if ((input_section->flags & SEC_ALLOC) == 0
2664
              || h->plt.offset == (bfd_vma) -1)
2665
            abort ();
2666
 
2667
          /* STT_GNU_IFUNC symbol must go through PLT.  */
2668
          plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
2669
          relocation = (plt->output_section->vma
2670
                        + plt->output_offset + h->plt.offset);
2671
 
2672
          switch (r_type)
2673
            {
2674
            default:
2675
              if (h->root.root.string)
2676
                name = h->root.root.string;
2677
              else
2678
                name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
2679
                                         NULL);
2680
              (*_bfd_error_handler)
2681
                (_("%B: relocation %s against STT_GNU_IFUNC "
2682
                   "symbol `%s' isn't handled by %s"), input_bfd,
2683
                 x86_64_elf_howto_table[r_type].name,
2684
                 name, __FUNCTION__);
2685
              bfd_set_error (bfd_error_bad_value);
2686
              return FALSE;
2687
 
2688
            case R_X86_64_32S:
2689
              if (info->shared)
2690
                abort ();
2691
              goto do_relocation;
2692
 
2693
            case R_X86_64_64:
2694
              if (rel->r_addend != 0)
2695
                {
2696
                  if (h->root.root.string)
2697
                    name = h->root.root.string;
2698
                  else
2699
                    name = bfd_elf_sym_name (input_bfd, symtab_hdr,
2700
                                             sym, NULL);
2701
                  (*_bfd_error_handler)
2702
                    (_("%B: relocation %s against STT_GNU_IFUNC "
2703
                       "symbol `%s' has non-zero addend: %d"),
2704
                     input_bfd, x86_64_elf_howto_table[r_type].name,
2705
                     name, rel->r_addend);
2706
                  bfd_set_error (bfd_error_bad_value);
2707
                  return FALSE;
2708
                }
2709
 
2710
              /* Generate dynamic relcoation only when there is a
2711
                 non-GOF reference in a shared object.  */
2712
              if (info->shared && h->non_got_ref)
2713
                {
2714
                  Elf_Internal_Rela outrel;
2715
                  bfd_byte *loc;
2716
                  asection *sreloc;
2717
 
2718
                  /* Need a dynamic relocation to get the real function
2719
                     address.  */
2720
                  outrel.r_offset = _bfd_elf_section_offset (output_bfd,
2721
                                                             info,
2722
                                                             input_section,
2723
                                                             rel->r_offset);
2724
                  if (outrel.r_offset == (bfd_vma) -1
2725
                      || outrel.r_offset == (bfd_vma) -2)
2726
                    abort ();
2727
 
2728
                  outrel.r_offset += (input_section->output_section->vma
2729
                                      + input_section->output_offset);
2730
 
2731
                  if (h->dynindx == -1
2732
                      || h->forced_local
2733
                      || info->executable)
2734
                    {
2735
                      /* This symbol is resolved locally.  */
2736
                      outrel.r_info = ELF64_R_INFO (0, R_X86_64_IRELATIVE);
2737
                      outrel.r_addend = (h->root.u.def.value
2738
                                         + h->root.u.def.section->output_section->vma
2739
                                         + h->root.u.def.section->output_offset);
2740
                    }
2741
                  else
2742
                    {
2743
                      outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
2744
                      outrel.r_addend = 0;
2745
                    }
2746
 
2747
                  sreloc = htab->elf.irelifunc;
2748
                  loc = sreloc->contents;
2749
                  loc += (sreloc->reloc_count++
2750
                          * sizeof (Elf64_External_Rela));
2751
                  bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
2752
 
2753
                  /* If this reloc is against an external symbol, we
2754
                     do not want to fiddle with the addend.  Otherwise,
2755
                     we need to include the symbol value so that it
2756
                     becomes an addend for the dynamic reloc.  For an
2757
                     internal symbol, we have updated addend.  */
2758
                  continue;
2759
                }
2760
 
2761
            case R_X86_64_32:
2762
            case R_X86_64_PC32:
2763
            case R_X86_64_PC64:
2764
            case R_X86_64_PLT32:
2765
              goto do_relocation;
2766
 
2767
            case R_X86_64_GOTPCREL:
2768
            case R_X86_64_GOTPCREL64:
2769
              base_got = htab->elf.sgot;
2770
              off = h->got.offset;
2771
 
2772
              if (base_got == NULL)
2773
                abort ();
2774
 
2775
              if (off == (bfd_vma) -1)
2776
                {
2777
                  /* We can't use h->got.offset here to save state, or
2778
                     even just remember the offset, as finish_dynamic_symbol
2779
                     would use that as offset into .got.  */
2780
 
2781
                  if (htab->elf.splt != NULL)
2782
                    {
2783
                      plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
2784
                      off = (plt_index + 3) * GOT_ENTRY_SIZE;
2785
                      base_got = htab->elf.sgotplt;
2786
                    }
2787
                  else
2788
                    {
2789
                      plt_index = h->plt.offset / PLT_ENTRY_SIZE;
2790
                      off = plt_index * GOT_ENTRY_SIZE;
2791
                      base_got = htab->elf.igotplt;
2792
                    }
2793
 
2794
                  if (h->dynindx == -1
2795
                      || h->forced_local
2796
                      || info->symbolic)
2797
                    {
2798
                      /* This references the local defitionion.  We must
2799
                         initialize this entry in the global offset table.
2800
                         Since the offset must always be a multiple of 8,
2801
                         we use the least significant bit to record
2802
                         whether we have initialized it already.
2803
 
2804
                         When doing a dynamic link, we create a .rela.got
2805
                         relocation entry to initialize the value.  This
2806
                         is done in the finish_dynamic_symbol routine.   */
2807
                      if ((off & 1) != 0)
2808
                        off &= ~1;
2809
                      else
2810
                        {
2811
                          bfd_put_64 (output_bfd, relocation,
2812
                                      base_got->contents + off);
2813
                          /* Note that this is harmless for the GOTPLT64
2814
                             case, as -1 | 1 still is -1.  */
2815
                          h->got.offset |= 1;
2816
                        }
2817
                    }
2818
                }
2819
 
2820
              relocation = (base_got->output_section->vma
2821
                            + base_got->output_offset + off);
2822
 
2823
              if (r_type != R_X86_64_GOTPCREL
2824
                  && r_type != R_X86_64_GOTPCREL64)
2825
                {
2826
                  asection *gotplt;
2827
                  if (htab->elf.splt != NULL)
2828
                    gotplt = htab->elf.sgotplt;
2829
                  else
2830
                    gotplt = htab->elf.igotplt;
2831
                  relocation -= (gotplt->output_section->vma
2832
                                 - gotplt->output_offset);
2833
                }
2834
 
2835
              goto do_relocation;
2836
            }
2837
        }
2838
 
2839 24 jeremybenn
      /* When generating a shared object, the relocations handled here are
2840
         copied into the output file to be resolved at run time.  */
2841
      switch (r_type)
2842
        {
2843
        case R_X86_64_GOT32:
2844
        case R_X86_64_GOT64:
2845
          /* Relocation is to the entry for this symbol in the global
2846
             offset table.  */
2847
        case R_X86_64_GOTPCREL:
2848
        case R_X86_64_GOTPCREL64:
2849
          /* Use global offset table entry as symbol value.  */
2850
        case R_X86_64_GOTPLT64:
2851
          /* This is the same as GOT64 for relocation purposes, but
2852
             indicates the existence of a PLT entry.  The difficulty is,
2853
             that we must calculate the GOT slot offset from the PLT
2854
             offset, if this symbol got a PLT entry (it was global).
2855
             Additionally if it's computed from the PLT entry, then that
2856
             GOT offset is relative to .got.plt, not to .got.  */
2857 225 jeremybenn
          base_got = htab->elf.sgot;
2858 24 jeremybenn
 
2859 225 jeremybenn
          if (htab->elf.sgot == NULL)
2860 24 jeremybenn
            abort ();
2861
 
2862
          if (h != NULL)
2863
            {
2864
              bfd_boolean dyn;
2865
 
2866
              off = h->got.offset;
2867
              if (h->needs_plt
2868
                  && h->plt.offset != (bfd_vma)-1
2869
                  && off == (bfd_vma)-1)
2870
                {
2871
                  /* We can't use h->got.offset here to save
2872
                     state, or even just remember the offset, as
2873
                     finish_dynamic_symbol would use that as offset into
2874
                     .got.  */
2875
                  bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
2876
                  off = (plt_index + 3) * GOT_ENTRY_SIZE;
2877 225 jeremybenn
                  base_got = htab->elf.sgotplt;
2878 24 jeremybenn
                }
2879
 
2880
              dyn = htab->elf.dynamic_sections_created;
2881
 
2882
              if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
2883
                  || (info->shared
2884
                      && SYMBOL_REFERENCES_LOCAL (info, h))
2885
                  || (ELF_ST_VISIBILITY (h->other)
2886
                      && h->root.type == bfd_link_hash_undefweak))
2887
                {
2888
                  /* This is actually a static link, or it is a -Bsymbolic
2889
                     link and the symbol is defined locally, or the symbol
2890
                     was forced to be local because of a version file.  We
2891
                     must initialize this entry in the global offset table.
2892
                     Since the offset must always be a multiple of 8, we
2893
                     use the least significant bit to record whether we
2894
                     have initialized it already.
2895
 
2896
                     When doing a dynamic link, we create a .rela.got
2897
                     relocation entry to initialize the value.  This is
2898
                     done in the finish_dynamic_symbol routine.  */
2899
                  if ((off & 1) != 0)
2900
                    off &= ~1;
2901
                  else
2902
                    {
2903
                      bfd_put_64 (output_bfd, relocation,
2904
                                  base_got->contents + off);
2905
                      /* Note that this is harmless for the GOTPLT64 case,
2906
                         as -1 | 1 still is -1.  */
2907
                      h->got.offset |= 1;
2908
                    }
2909
                }
2910
              else
2911
                unresolved_reloc = FALSE;
2912
            }
2913
          else
2914
            {
2915
              if (local_got_offsets == NULL)
2916
                abort ();
2917
 
2918
              off = local_got_offsets[r_symndx];
2919
 
2920
              /* The offset must always be a multiple of 8.  We use
2921
                 the least significant bit to record whether we have
2922
                 already generated the necessary reloc.  */
2923
              if ((off & 1) != 0)
2924
                off &= ~1;
2925
              else
2926
                {
2927
                  bfd_put_64 (output_bfd, relocation,
2928
                              base_got->contents + off);
2929
 
2930
                  if (info->shared)
2931
                    {
2932
                      asection *s;
2933
                      Elf_Internal_Rela outrel;
2934
                      bfd_byte *loc;
2935
 
2936
                      /* We need to generate a R_X86_64_RELATIVE reloc
2937
                         for the dynamic linker.  */
2938 225 jeremybenn
                      s = htab->elf.srelgot;
2939 24 jeremybenn
                      if (s == NULL)
2940
                        abort ();
2941
 
2942
                      outrel.r_offset = (base_got->output_section->vma
2943
                                         + base_got->output_offset
2944
                                         + off);
2945
                      outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
2946
                      outrel.r_addend = relocation;
2947
                      loc = s->contents;
2948
                      loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
2949
                      bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
2950
                    }
2951
 
2952
                  local_got_offsets[r_symndx] |= 1;
2953
                }
2954
            }
2955
 
2956
          if (off >= (bfd_vma) -2)
2957
            abort ();
2958
 
2959
          relocation = base_got->output_section->vma
2960
                       + base_got->output_offset + off;
2961
          if (r_type != R_X86_64_GOTPCREL && r_type != R_X86_64_GOTPCREL64)
2962 225 jeremybenn
            relocation -= htab->elf.sgotplt->output_section->vma
2963
                          - htab->elf.sgotplt->output_offset;
2964 24 jeremybenn
 
2965
          break;
2966
 
2967
        case R_X86_64_GOTOFF64:
2968
          /* Relocation is relative to the start of the global offset
2969
             table.  */
2970
 
2971
          /* Check to make sure it isn't a protected function symbol
2972
             for shared library since it may not be local when used
2973
             as function address.  */
2974
          if (info->shared
2975
              && h
2976
              && h->def_regular
2977
              && h->type == STT_FUNC
2978
              && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
2979
            {
2980
              (*_bfd_error_handler)
2981
                (_("%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"),
2982
                 input_bfd, h->root.root.string);
2983
              bfd_set_error (bfd_error_bad_value);
2984
              return FALSE;
2985
            }
2986
 
2987
          /* Note that sgot is not involved in this
2988
             calculation.  We always want the start of .got.plt.  If we
2989
             defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
2990
             permitted by the ABI, we might have to change this
2991
             calculation.  */
2992 225 jeremybenn
          relocation -= htab->elf.sgotplt->output_section->vma
2993
                        + htab->elf.sgotplt->output_offset;
2994 24 jeremybenn
          break;
2995
 
2996
        case R_X86_64_GOTPC32:
2997
        case R_X86_64_GOTPC64:
2998
          /* Use global offset table as symbol value.  */
2999 225 jeremybenn
          relocation = htab->elf.sgotplt->output_section->vma
3000
                       + htab->elf.sgotplt->output_offset;
3001 24 jeremybenn
          unresolved_reloc = FALSE;
3002
          break;
3003
 
3004
        case R_X86_64_PLTOFF64:
3005
          /* Relocation is PLT entry relative to GOT.  For local
3006
             symbols it's the symbol itself relative to GOT.  */
3007
          if (h != NULL
3008
              /* See PLT32 handling.  */
3009
              && h->plt.offset != (bfd_vma) -1
3010 225 jeremybenn
              && htab->elf.splt != NULL)
3011 24 jeremybenn
            {
3012 225 jeremybenn
              relocation = (htab->elf.splt->output_section->vma
3013
                            + htab->elf.splt->output_offset
3014 24 jeremybenn
                            + h->plt.offset);
3015
              unresolved_reloc = FALSE;
3016
            }
3017
 
3018 225 jeremybenn
          relocation -= htab->elf.sgotplt->output_section->vma
3019
                        + htab->elf.sgotplt->output_offset;
3020 24 jeremybenn
          break;
3021
 
3022
        case R_X86_64_PLT32:
3023
          /* Relocation is to the entry for this symbol in the
3024
             procedure linkage table.  */
3025
 
3026
          /* Resolve a PLT32 reloc against a local symbol directly,
3027
             without using the procedure linkage table.  */
3028
          if (h == NULL)
3029
            break;
3030
 
3031
          if (h->plt.offset == (bfd_vma) -1
3032 225 jeremybenn
              || htab->elf.splt == NULL)
3033 24 jeremybenn
            {
3034
              /* We didn't make a PLT entry for this symbol.  This
3035
                 happens when statically linking PIC code, or when
3036
                 using -Bsymbolic.  */
3037
              break;
3038
            }
3039
 
3040 225 jeremybenn
          relocation = (htab->elf.splt->output_section->vma
3041
                        + htab->elf.splt->output_offset
3042 24 jeremybenn
                        + h->plt.offset);
3043
          unresolved_reloc = FALSE;
3044
          break;
3045
 
3046
        case R_X86_64_PC8:
3047
        case R_X86_64_PC16:
3048
        case R_X86_64_PC32:
3049
          if (info->shared
3050
              && (input_section->flags & SEC_ALLOC) != 0
3051
              && (input_section->flags & SEC_READONLY) != 0
3052 225 jeremybenn
              && h != NULL)
3053 24 jeremybenn
            {
3054 225 jeremybenn
              bfd_boolean fail = FALSE;
3055
              bfd_boolean branch
3056
                = (r_type == R_X86_64_PC32
3057
                   && is_32bit_relative_branch (contents, rel->r_offset));
3058
 
3059
              if (SYMBOL_REFERENCES_LOCAL (info, h))
3060
                {
3061
                  /* Symbol is referenced locally.  Make sure it is
3062
                     defined locally or for a branch.  */
3063
                  fail = !h->def_regular && !branch;
3064
                }
3065 24 jeremybenn
              else
3066 225 jeremybenn
                {
3067
                  /* Symbol isn't referenced locally.  We only allow
3068
                     branch to symbol with non-default visibility. */
3069
                  fail = (!branch
3070
                          || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT);
3071
                }
3072
 
3073
              if (fail)
3074
                {
3075
                  const char *fmt;
3076
                  const char *v;
3077
                  const char *pic = "";
3078
 
3079
                  switch (ELF_ST_VISIBILITY (h->other))
3080
                    {
3081
                    case STV_HIDDEN:
3082
                      v = _("hidden symbol");
3083
                      break;
3084
                    case STV_INTERNAL:
3085
                      v = _("internal symbol");
3086
                      break;
3087
                    case STV_PROTECTED:
3088
                      v = _("protected symbol");
3089
                      break;
3090
                    default:
3091
                      v = _("symbol");
3092
                      pic = _("; recompile with -fPIC");
3093
                      break;
3094
                    }
3095
 
3096
                  if (h->def_regular)
3097
                    fmt = _("%B: relocation %s against %s `%s' can not be used when making a shared object%s");
3098
                  else
3099
                    fmt = _("%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s");
3100
 
3101
                  (*_bfd_error_handler) (fmt, input_bfd,
3102
                                         x86_64_elf_howto_table[r_type].name,
3103
                                         v,  h->root.root.string, pic);
3104
                  bfd_set_error (bfd_error_bad_value);
3105
                  return FALSE;
3106
                }
3107 24 jeremybenn
            }
3108
          /* Fall through.  */
3109
 
3110
        case R_X86_64_8:
3111
        case R_X86_64_16:
3112
        case R_X86_64_32:
3113
        case R_X86_64_PC64:
3114
        case R_X86_64_64:
3115
          /* FIXME: The ABI says the linker should make sure the value is
3116
             the same when it's zeroextended to 64 bit.  */
3117
 
3118
          if ((input_section->flags & SEC_ALLOC) == 0)
3119
            break;
3120
 
3121
          if ((info->shared
3122
               && (h == NULL
3123
                   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3124
                   || h->root.type != bfd_link_hash_undefweak)
3125 225 jeremybenn
               && (! IS_X86_64_PCREL_TYPE (r_type)
3126
                   || ! SYMBOL_CALLS_LOCAL (info, h)))
3127 24 jeremybenn
              || (ELIMINATE_COPY_RELOCS
3128
                  && !info->shared
3129
                  && h != NULL
3130
                  && h->dynindx != -1
3131
                  && !h->non_got_ref
3132
                  && ((h->def_dynamic
3133
                       && !h->def_regular)
3134
                      || h->root.type == bfd_link_hash_undefweak
3135
                      || h->root.type == bfd_link_hash_undefined)))
3136
            {
3137
              Elf_Internal_Rela outrel;
3138
              bfd_byte *loc;
3139
              bfd_boolean skip, relocate;
3140
              asection *sreloc;
3141
 
3142
              /* When generating a shared object, these relocations
3143
                 are copied into the output file to be resolved at run
3144
                 time.  */
3145
              skip = FALSE;
3146
              relocate = FALSE;
3147
 
3148
              outrel.r_offset =
3149
                _bfd_elf_section_offset (output_bfd, info, input_section,
3150
                                         rel->r_offset);
3151
              if (outrel.r_offset == (bfd_vma) -1)
3152
                skip = TRUE;
3153
              else if (outrel.r_offset == (bfd_vma) -2)
3154
                skip = TRUE, relocate = TRUE;
3155
 
3156
              outrel.r_offset += (input_section->output_section->vma
3157
                                  + input_section->output_offset);
3158
 
3159
              if (skip)
3160
                memset (&outrel, 0, sizeof outrel);
3161
 
3162
              /* h->dynindx may be -1 if this symbol was marked to
3163
                 become local.  */
3164
              else if (h != NULL
3165
                       && h->dynindx != -1
3166 225 jeremybenn
                       && (IS_X86_64_PCREL_TYPE (r_type)
3167
                           || ! info->shared
3168
                           || ! SYMBOLIC_BIND (info, h)
3169
                           || ! h->def_regular))
3170 24 jeremybenn
                {
3171
                  outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
3172
                  outrel.r_addend = rel->r_addend;
3173
                }
3174
              else
3175
                {
3176
                  /* This symbol is local, or marked to become local.  */
3177
                  if (r_type == R_X86_64_64)
3178
                    {
3179
                      relocate = TRUE;
3180
                      outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
3181
                      outrel.r_addend = relocation + rel->r_addend;
3182
                    }
3183
                  else
3184
                    {
3185
                      long sindx;
3186
 
3187
                      if (bfd_is_abs_section (sec))
3188
                        sindx = 0;
3189
                      else if (sec == NULL || sec->owner == NULL)
3190
                        {
3191
                          bfd_set_error (bfd_error_bad_value);
3192
                          return FALSE;
3193
                        }
3194
                      else
3195
                        {
3196
                          asection *osec;
3197
 
3198
                          /* We are turning this relocation into one
3199
                             against a section symbol.  It would be
3200
                             proper to subtract the symbol's value,
3201
                             osec->vma, from the emitted reloc addend,
3202
                             but ld.so expects buggy relocs.  */
3203
                          osec = sec->output_section;
3204
                          sindx = elf_section_data (osec)->dynindx;
3205
                          if (sindx == 0)
3206
                            {
3207
                              asection *oi = htab->elf.text_index_section;
3208
                              sindx = elf_section_data (oi)->dynindx;
3209
                            }
3210
                          BFD_ASSERT (sindx != 0);
3211
                        }
3212
 
3213
                      outrel.r_info = ELF64_R_INFO (sindx, r_type);
3214
                      outrel.r_addend = relocation + rel->r_addend;
3215
                    }
3216
                }
3217
 
3218
              sreloc = elf_section_data (input_section)->sreloc;
3219
 
3220 225 jeremybenn
              BFD_ASSERT (sreloc != NULL && sreloc->contents != NULL);
3221
 
3222 24 jeremybenn
              loc = sreloc->contents;
3223
              loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
3224
              bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
3225
 
3226
              /* If this reloc is against an external symbol, we do
3227
                 not want to fiddle with the addend.  Otherwise, we
3228
                 need to include the symbol value so that it becomes
3229
                 an addend for the dynamic reloc.  */
3230
              if (! relocate)
3231
                continue;
3232
            }
3233
 
3234
          break;
3235
 
3236
        case R_X86_64_TLSGD:
3237
        case R_X86_64_GOTPC32_TLSDESC:
3238
        case R_X86_64_TLSDESC_CALL:
3239
        case R_X86_64_GOTTPOFF:
3240
          tls_type = GOT_UNKNOWN;
3241
          if (h == NULL && local_got_offsets)
3242
            tls_type = elf64_x86_64_local_got_tls_type (input_bfd) [r_symndx];
3243
          else if (h != NULL)
3244
            tls_type = elf64_x86_64_hash_entry (h)->tls_type;
3245
 
3246
          if (! elf64_x86_64_tls_transition (info, input_bfd,
3247
                                             input_section, contents,
3248
                                             symtab_hdr, sym_hashes,
3249
                                             &r_type, tls_type, rel,
3250 225 jeremybenn
                                             relend, h, r_symndx))
3251 24 jeremybenn
            return FALSE;
3252
 
3253
          if (r_type == R_X86_64_TPOFF32)
3254
            {
3255
              bfd_vma roff = rel->r_offset;
3256
 
3257
              BFD_ASSERT (! unresolved_reloc);
3258
 
3259
              if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
3260
                {
3261
                  /* GD->LE transition.
3262
                     .byte 0x66; leaq foo@tlsgd(%rip), %rdi
3263
                     .word 0x6666; rex64; call __tls_get_addr
3264
                     Change it into:
3265
                     movq %fs:0, %rax
3266
                     leaq foo@tpoff(%rax), %rax */
3267
                  memcpy (contents + roff - 4,
3268
                          "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
3269
                          16);
3270 225 jeremybenn
                  bfd_put_32 (output_bfd,
3271
                              elf64_x86_64_tpoff (info, relocation),
3272 24 jeremybenn
                              contents + roff + 8);
3273
                  /* Skip R_X86_64_PC32/R_X86_64_PLT32.  */
3274
                  rel++;
3275
                  continue;
3276
                }
3277
              else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
3278
                {
3279
                  /* GDesc -> LE transition.
3280
                     It's originally something like:
3281
                     leaq x@tlsdesc(%rip), %rax
3282
 
3283
                     Change it to:
3284
                     movl $x@tpoff, %rax
3285
                   */
3286
 
3287
                  unsigned int val, type, type2;
3288
 
3289
                  type = bfd_get_8 (input_bfd, contents + roff - 3);
3290
                  type2 = bfd_get_8 (input_bfd, contents + roff - 2);
3291
                  val = bfd_get_8 (input_bfd, contents + roff - 1);
3292
                  bfd_put_8 (output_bfd, 0x48 | ((type >> 2) & 1),
3293
                             contents + roff - 3);
3294
                  bfd_put_8 (output_bfd, 0xc7, contents + roff - 2);
3295
                  bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
3296
                             contents + roff - 1);
3297 225 jeremybenn
                  bfd_put_32 (output_bfd,
3298
                              elf64_x86_64_tpoff (info, relocation),
3299 24 jeremybenn
                              contents + roff);
3300
                  continue;
3301
                }
3302
              else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
3303
                {
3304
                  /* GDesc -> LE transition.
3305
                     It's originally:
3306
                     call *(%rax)
3307
                     Turn it into:
3308
                     xchg %ax,%ax.  */
3309
                  bfd_put_8 (output_bfd, 0x66, contents + roff);
3310
                  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
3311
                  continue;
3312
                }
3313
              else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_GOTTPOFF)
3314
                {
3315
                  /* IE->LE transition:
3316
                     Originally it can be one of:
3317
                     movq foo@gottpoff(%rip), %reg
3318
                     addq foo@gottpoff(%rip), %reg
3319
                     We change it into:
3320
                     movq $foo, %reg
3321
                     leaq foo(%reg), %reg
3322
                     addq $foo, %reg.  */
3323
 
3324
                  unsigned int val, type, reg;
3325
 
3326
                  val = bfd_get_8 (input_bfd, contents + roff - 3);
3327
                  type = bfd_get_8 (input_bfd, contents + roff - 2);
3328
                  reg = bfd_get_8 (input_bfd, contents + roff - 1);
3329
                  reg >>= 3;
3330
                  if (type == 0x8b)
3331
                    {
3332
                      /* movq */
3333
                      if (val == 0x4c)
3334
                        bfd_put_8 (output_bfd, 0x49,
3335
                                   contents + roff - 3);
3336
                      bfd_put_8 (output_bfd, 0xc7,
3337
                                 contents + roff - 2);
3338
                      bfd_put_8 (output_bfd, 0xc0 | reg,
3339
                                 contents + roff - 1);
3340
                    }
3341
                  else if (reg == 4)
3342
                    {
3343
                      /* addq -> addq - addressing with %rsp/%r12 is
3344
                         special  */
3345
                      if (val == 0x4c)
3346
                        bfd_put_8 (output_bfd, 0x49,
3347
                                   contents + roff - 3);
3348
                      bfd_put_8 (output_bfd, 0x81,
3349
                                 contents + roff - 2);
3350
                      bfd_put_8 (output_bfd, 0xc0 | reg,
3351
                                 contents + roff - 1);
3352
                    }
3353
                  else
3354
                    {
3355
                      /* addq -> leaq */
3356
                      if (val == 0x4c)
3357
                        bfd_put_8 (output_bfd, 0x4d,
3358
                                   contents + roff - 3);
3359
                      bfd_put_8 (output_bfd, 0x8d,
3360
                                 contents + roff - 2);
3361
                      bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3),
3362
                                 contents + roff - 1);
3363
                    }
3364 225 jeremybenn
                  bfd_put_32 (output_bfd,
3365
                              elf64_x86_64_tpoff (info, relocation),
3366 24 jeremybenn
                              contents + roff);
3367
                  continue;
3368
                }
3369
              else
3370
                BFD_ASSERT (FALSE);
3371
            }
3372
 
3373 225 jeremybenn
          if (htab->elf.sgot == NULL)
3374 24 jeremybenn
            abort ();
3375
 
3376
          if (h != NULL)
3377
            {
3378
              off = h->got.offset;
3379
              offplt = elf64_x86_64_hash_entry (h)->tlsdesc_got;
3380
            }
3381
          else
3382
            {
3383
              if (local_got_offsets == NULL)
3384
                abort ();
3385
 
3386
              off = local_got_offsets[r_symndx];
3387
              offplt = local_tlsdesc_gotents[r_symndx];
3388
            }
3389
 
3390
          if ((off & 1) != 0)
3391
            off &= ~1;
3392
          else
3393
            {
3394
              Elf_Internal_Rela outrel;
3395
              bfd_byte *loc;
3396
              int dr_type, indx;
3397
              asection *sreloc;
3398
 
3399 225 jeremybenn
              if (htab->elf.srelgot == NULL)
3400 24 jeremybenn
                abort ();
3401
 
3402
              indx = h && h->dynindx != -1 ? h->dynindx : 0;
3403
 
3404
              if (GOT_TLS_GDESC_P (tls_type))
3405
                {
3406
                  outrel.r_info = ELF64_R_INFO (indx, R_X86_64_TLSDESC);
3407
                  BFD_ASSERT (htab->sgotplt_jump_table_size + offplt
3408 225 jeremybenn
                              + 2 * GOT_ENTRY_SIZE <= htab->elf.sgotplt->size);
3409
                  outrel.r_offset = (htab->elf.sgotplt->output_section->vma
3410
                                     + htab->elf.sgotplt->output_offset
3411 24 jeremybenn
                                     + offplt
3412
                                     + htab->sgotplt_jump_table_size);
3413 225 jeremybenn
                  sreloc = htab->elf.srelplt;
3414 24 jeremybenn
                  loc = sreloc->contents;
3415
                  loc += sreloc->reloc_count++
3416
                    * sizeof (Elf64_External_Rela);
3417
                  BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
3418
                              <= sreloc->contents + sreloc->size);
3419
                  if (indx == 0)
3420 225 jeremybenn
                    outrel.r_addend = relocation - elf64_x86_64_dtpoff_base (info);
3421 24 jeremybenn
                  else
3422
                    outrel.r_addend = 0;
3423
                  bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
3424
                }
3425
 
3426 225 jeremybenn
              sreloc = htab->elf.srelgot;
3427 24 jeremybenn
 
3428 225 jeremybenn
              outrel.r_offset = (htab->elf.sgot->output_section->vma
3429
                                 + htab->elf.sgot->output_offset + off);
3430 24 jeremybenn
 
3431
              if (GOT_TLS_GD_P (tls_type))
3432
                dr_type = R_X86_64_DTPMOD64;
3433
              else if (GOT_TLS_GDESC_P (tls_type))
3434
                goto dr_done;
3435
              else
3436
                dr_type = R_X86_64_TPOFF64;
3437
 
3438 225 jeremybenn
              bfd_put_64 (output_bfd, 0, htab->elf.sgot->contents + off);
3439 24 jeremybenn
              outrel.r_addend = 0;
3440
              if ((dr_type == R_X86_64_TPOFF64
3441
                   || dr_type == R_X86_64_TLSDESC) && indx == 0)
3442 225 jeremybenn
                outrel.r_addend = relocation - elf64_x86_64_dtpoff_base (info);
3443 24 jeremybenn
              outrel.r_info = ELF64_R_INFO (indx, dr_type);
3444
 
3445
              loc = sreloc->contents;
3446
              loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
3447
              BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
3448
                          <= sreloc->contents + sreloc->size);
3449
              bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
3450
 
3451
              if (GOT_TLS_GD_P (tls_type))
3452
                {
3453
                  if (indx == 0)
3454
                    {
3455
                      BFD_ASSERT (! unresolved_reloc);
3456
                      bfd_put_64 (output_bfd,
3457 225 jeremybenn
                                  relocation - elf64_x86_64_dtpoff_base (info),
3458
                                  htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
3459 24 jeremybenn
                    }
3460
                  else
3461
                    {
3462
                      bfd_put_64 (output_bfd, 0,
3463 225 jeremybenn
                                  htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
3464 24 jeremybenn
                      outrel.r_info = ELF64_R_INFO (indx,
3465
                                                    R_X86_64_DTPOFF64);
3466
                      outrel.r_offset += GOT_ENTRY_SIZE;
3467
                      sreloc->reloc_count++;
3468
                      loc += sizeof (Elf64_External_Rela);
3469
                      BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
3470
                                  <= sreloc->contents + sreloc->size);
3471
                      bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
3472
                    }
3473
                }
3474
 
3475
            dr_done:
3476
              if (h != NULL)
3477
                h->got.offset |= 1;
3478
              else
3479
                local_got_offsets[r_symndx] |= 1;
3480
            }
3481
 
3482
          if (off >= (bfd_vma) -2
3483
              && ! GOT_TLS_GDESC_P (tls_type))
3484
            abort ();
3485
          if (r_type == ELF64_R_TYPE (rel->r_info))
3486
            {
3487
              if (r_type == R_X86_64_GOTPC32_TLSDESC
3488
                  || r_type == R_X86_64_TLSDESC_CALL)
3489 225 jeremybenn
                relocation = htab->elf.sgotplt->output_section->vma
3490
                  + htab->elf.sgotplt->output_offset
3491 24 jeremybenn
                  + offplt + htab->sgotplt_jump_table_size;
3492
              else
3493 225 jeremybenn
                relocation = htab->elf.sgot->output_section->vma
3494
                  + htab->elf.sgot->output_offset + off;
3495 24 jeremybenn
              unresolved_reloc = FALSE;
3496
            }
3497
          else
3498
            {
3499
              bfd_vma roff = rel->r_offset;
3500
 
3501
              if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
3502
                {
3503
                  /* GD->IE transition.
3504
                     .byte 0x66; leaq foo@tlsgd(%rip), %rdi
3505
                     .word 0x6666; rex64; call __tls_get_addr@plt
3506
                     Change it into:
3507
                     movq %fs:0, %rax
3508
                     addq foo@gottpoff(%rip), %rax */
3509
                  memcpy (contents + roff - 4,
3510
                          "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
3511
                          16);
3512
 
3513 225 jeremybenn
                  relocation = (htab->elf.sgot->output_section->vma
3514
                                + htab->elf.sgot->output_offset + off
3515 24 jeremybenn
                                - roff
3516
                                - input_section->output_section->vma
3517
                                - input_section->output_offset
3518
                                - 12);
3519
                  bfd_put_32 (output_bfd, relocation,
3520
                              contents + roff + 8);
3521
                  /* Skip R_X86_64_PLT32.  */
3522
                  rel++;
3523
                  continue;
3524
                }
3525
              else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
3526
                {
3527
                  /* GDesc -> IE transition.
3528
                     It's originally something like:
3529
                     leaq x@tlsdesc(%rip), %rax
3530
 
3531
                     Change it to:
3532
                     movq x@gottpoff(%rip), %rax # before xchg %ax,%ax
3533
                   */
3534
 
3535
                  unsigned int val, type, type2;
3536
 
3537
                  type = bfd_get_8 (input_bfd, contents + roff - 3);
3538
                  type2 = bfd_get_8 (input_bfd, contents + roff - 2);
3539
                  val = bfd_get_8 (input_bfd, contents + roff - 1);
3540
 
3541
                  /* Now modify the instruction as appropriate. To
3542
                     turn a leaq into a movq in the form we use it, it
3543
                     suffices to change the second byte from 0x8d to
3544
                     0x8b.  */
3545
                  bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
3546
 
3547
                  bfd_put_32 (output_bfd,
3548 225 jeremybenn
                              htab->elf.sgot->output_section->vma
3549
                              + htab->elf.sgot->output_offset + off
3550 24 jeremybenn
                              - rel->r_offset
3551
                              - input_section->output_section->vma
3552
                              - input_section->output_offset
3553
                              - 4,
3554
                              contents + roff);
3555
                  continue;
3556
                }
3557
              else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
3558
                {
3559
                  /* GDesc -> IE transition.
3560
                     It's originally:
3561
                     call *(%rax)
3562
 
3563
                     Change it to:
3564
                     xchg %ax,%ax.  */
3565
 
3566
                  unsigned int val, type;
3567
 
3568
                  type = bfd_get_8 (input_bfd, contents + roff);
3569
                  val = bfd_get_8 (input_bfd, contents + roff + 1);
3570
                  bfd_put_8 (output_bfd, 0x66, contents + roff);
3571
                  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
3572
                  continue;
3573
                }
3574
              else
3575
                BFD_ASSERT (FALSE);
3576
            }
3577
          break;
3578
 
3579
        case R_X86_64_TLSLD:
3580
          if (! elf64_x86_64_tls_transition (info, input_bfd,
3581
                                             input_section, contents,
3582
                                             symtab_hdr, sym_hashes,
3583
                                             &r_type, GOT_UNKNOWN,
3584 225 jeremybenn
                                             rel, relend, h, r_symndx))
3585 24 jeremybenn
            return FALSE;
3586
 
3587
          if (r_type != R_X86_64_TLSLD)
3588
            {
3589
              /* LD->LE transition:
3590
                 leaq foo@tlsld(%rip), %rdi; call __tls_get_addr.
3591
                 We change it into:
3592
                 .word 0x6666; .byte 0x66; movl %fs:0, %rax.  */
3593
 
3594
              BFD_ASSERT (r_type == R_X86_64_TPOFF32);
3595
              memcpy (contents + rel->r_offset - 3,
3596
                      "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
3597
              /* Skip R_X86_64_PC32/R_X86_64_PLT32.  */
3598
              rel++;
3599
              continue;
3600
            }
3601
 
3602 225 jeremybenn
          if (htab->elf.sgot == NULL)
3603 24 jeremybenn
            abort ();
3604
 
3605
          off = htab->tls_ld_got.offset;
3606
          if (off & 1)
3607
            off &= ~1;
3608
          else
3609
            {
3610
              Elf_Internal_Rela outrel;
3611
              bfd_byte *loc;
3612
 
3613 225 jeremybenn
              if (htab->elf.srelgot == NULL)
3614 24 jeremybenn
                abort ();
3615
 
3616 225 jeremybenn
              outrel.r_offset = (htab->elf.sgot->output_section->vma
3617
                                 + htab->elf.sgot->output_offset + off);
3618 24 jeremybenn
 
3619
              bfd_put_64 (output_bfd, 0,
3620 225 jeremybenn
                          htab->elf.sgot->contents + off);
3621 24 jeremybenn
              bfd_put_64 (output_bfd, 0,
3622 225 jeremybenn
                          htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
3623 24 jeremybenn
              outrel.r_info = ELF64_R_INFO (0, R_X86_64_DTPMOD64);
3624
              outrel.r_addend = 0;
3625 225 jeremybenn
              loc = htab->elf.srelgot->contents;
3626
              loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
3627 24 jeremybenn
              bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
3628
              htab->tls_ld_got.offset |= 1;
3629
            }
3630 225 jeremybenn
          relocation = htab->elf.sgot->output_section->vma
3631
                       + htab->elf.sgot->output_offset + off;
3632 24 jeremybenn
          unresolved_reloc = FALSE;
3633
          break;
3634
 
3635
        case R_X86_64_DTPOFF32:
3636 225 jeremybenn
          if (!info->executable|| (input_section->flags & SEC_CODE) == 0)
3637
            relocation -= elf64_x86_64_dtpoff_base (info);
3638 24 jeremybenn
          else
3639 225 jeremybenn
            relocation = elf64_x86_64_tpoff (info, relocation);
3640 24 jeremybenn
          break;
3641
 
3642
        case R_X86_64_TPOFF32:
3643 225 jeremybenn
          BFD_ASSERT (info->executable);
3644
          relocation = elf64_x86_64_tpoff (info, relocation);
3645 24 jeremybenn
          break;
3646
 
3647
        default:
3648
          break;
3649
        }
3650
 
3651
      /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
3652
         because such sections are not SEC_ALLOC and thus ld.so will
3653
         not process them.  */
3654
      if (unresolved_reloc
3655
          && !((input_section->flags & SEC_DEBUGGING) != 0
3656
               && h->def_dynamic))
3657
        (*_bfd_error_handler)
3658
          (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
3659
           input_bfd,
3660
           input_section,
3661
           (long) rel->r_offset,
3662
           howto->name,
3663
           h->root.root.string);
3664
 
3665 225 jeremybenn
do_relocation:
3666 24 jeremybenn
      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
3667
                                    contents, rel->r_offset,
3668
                                    relocation, rel->r_addend);
3669
 
3670
      if (r != bfd_reloc_ok)
3671
        {
3672
          const char *name;
3673
 
3674
          if (h != NULL)
3675
            name = h->root.root.string;
3676
          else
3677
            {
3678
              name = bfd_elf_string_from_elf_section (input_bfd,
3679
                                                      symtab_hdr->sh_link,
3680
                                                      sym->st_name);
3681
              if (name == NULL)
3682
                return FALSE;
3683
              if (*name == '\0')
3684
                name = bfd_section_name (input_bfd, sec);
3685
            }
3686
 
3687
          if (r == bfd_reloc_overflow)
3688
            {
3689
              if (! ((*info->callbacks->reloc_overflow)
3690
                     (info, (h ? &h->root : NULL), name, howto->name,
3691
                      (bfd_vma) 0, input_bfd, input_section,
3692
                      rel->r_offset)))
3693
                return FALSE;
3694
            }
3695
          else
3696
            {
3697
              (*_bfd_error_handler)
3698
                (_("%B(%A+0x%lx): reloc against `%s': error %d"),
3699
                 input_bfd, input_section,
3700
                 (long) rel->r_offset, name, (int) r);
3701
              return FALSE;
3702
            }
3703
        }
3704
    }
3705
 
3706
  return TRUE;
3707
}
3708
 
3709
/* Finish up dynamic symbol handling.  We set the contents of various
3710
   dynamic sections here.  */
3711
 
3712
static bfd_boolean
3713
elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
3714
                                    struct bfd_link_info *info,
3715
                                    struct elf_link_hash_entry *h,
3716
                                    Elf_Internal_Sym *sym)
3717
{
3718
  struct elf64_x86_64_link_hash_table *htab;
3719
 
3720
  htab = elf64_x86_64_hash_table (info);
3721
 
3722
  if (h->plt.offset != (bfd_vma) -1)
3723
    {
3724
      bfd_vma plt_index;
3725
      bfd_vma got_offset;
3726
      Elf_Internal_Rela rela;
3727
      bfd_byte *loc;
3728 225 jeremybenn
      asection *plt, *gotplt, *relplt;
3729 24 jeremybenn
 
3730 225 jeremybenn
      /* When building a static executable, use .iplt, .igot.plt and
3731
         .rela.iplt sections for STT_GNU_IFUNC symbols.  */
3732
      if (htab->elf.splt != NULL)
3733
        {
3734
          plt = htab->elf.splt;
3735
          gotplt = htab->elf.sgotplt;
3736
          relplt = htab->elf.srelplt;
3737
        }
3738
      else
3739
        {
3740
          plt = htab->elf.iplt;
3741
          gotplt = htab->elf.igotplt;
3742
          relplt = htab->elf.irelplt;
3743
        }
3744
 
3745 24 jeremybenn
      /* This symbol has an entry in the procedure linkage table.  Set
3746
         it up.  */
3747 225 jeremybenn
      if ((h->dynindx == -1
3748
           && !((h->forced_local || info->executable)
3749
                && h->def_regular
3750
                && h->type == STT_GNU_IFUNC))
3751
          || plt == NULL
3752
          || gotplt == NULL
3753
          || relplt == NULL)
3754 24 jeremybenn
        abort ();
3755
 
3756
      /* Get the index in the procedure linkage table which
3757
         corresponds to this symbol.  This is the index of this symbol
3758
         in all the symbols for which we are making plt entries.  The
3759 225 jeremybenn
         first entry in the procedure linkage table is reserved.
3760
 
3761
         Get the offset into the .got table of the entry that
3762 24 jeremybenn
         corresponds to this function.  Each .got entry is GOT_ENTRY_SIZE
3763 225 jeremybenn
         bytes. The first three are reserved for the dynamic linker.
3764 24 jeremybenn
 
3765 225 jeremybenn
         For static executables, we don't reserve anything.  */
3766
 
3767
      if (plt == htab->elf.splt)
3768
        {
3769
          plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
3770
          got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
3771
        }
3772
      else
3773
        {
3774
          plt_index = h->plt.offset / PLT_ENTRY_SIZE;
3775
          got_offset = plt_index * GOT_ENTRY_SIZE;
3776
        }
3777
 
3778 24 jeremybenn
      /* Fill in the entry in the procedure linkage table.  */
3779 225 jeremybenn
      memcpy (plt->contents + h->plt.offset, elf64_x86_64_plt_entry,
3780 24 jeremybenn
              PLT_ENTRY_SIZE);
3781
 
3782
      /* Insert the relocation positions of the plt section.  The magic
3783
         numbers at the end of the statements are the positions of the
3784
         relocations in the plt section.  */
3785
      /* Put offset for jmp *name@GOTPCREL(%rip), since the
3786
         instruction uses 6 bytes, subtract this value.  */
3787
      bfd_put_32 (output_bfd,
3788 225 jeremybenn
                      (gotplt->output_section->vma
3789
                       + gotplt->output_offset
3790 24 jeremybenn
                       + got_offset
3791 225 jeremybenn
                       - plt->output_section->vma
3792
                       - plt->output_offset
3793 24 jeremybenn
                       - h->plt.offset
3794
                       - 6),
3795 225 jeremybenn
                  plt->contents + h->plt.offset + 2);
3796 24 jeremybenn
 
3797 225 jeremybenn
      /* Don't fill PLT entry for static executables.  */
3798
      if (plt == htab->elf.splt)
3799
        {
3800
          /* Put relocation index.  */
3801
          bfd_put_32 (output_bfd, plt_index,
3802
                      plt->contents + h->plt.offset + 7);
3803
          /* Put offset for jmp .PLT0.  */
3804
          bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),
3805
                      plt->contents + h->plt.offset + 12);
3806
        }
3807
 
3808 24 jeremybenn
      /* Fill in the entry in the global offset table, initially this
3809
         points to the pushq instruction in the PLT which is at offset 6.  */
3810 225 jeremybenn
      bfd_put_64 (output_bfd, (plt->output_section->vma
3811
                               + plt->output_offset
3812 24 jeremybenn
                               + h->plt.offset + 6),
3813 225 jeremybenn
                  gotplt->contents + got_offset);
3814 24 jeremybenn
 
3815
      /* Fill in the entry in the .rela.plt section.  */
3816 225 jeremybenn
      rela.r_offset = (gotplt->output_section->vma
3817
                       + gotplt->output_offset
3818 24 jeremybenn
                       + got_offset);
3819 225 jeremybenn
      if (h->dynindx == -1
3820
          || ((info->executable
3821
               || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3822
              && h->def_regular
3823
              && h->type == STT_GNU_IFUNC))
3824
        {
3825
          /* If an STT_GNU_IFUNC symbol is locally defined, generate
3826
             R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT.  */
3827
          rela.r_info = ELF64_R_INFO (0, R_X86_64_IRELATIVE);
3828
          rela.r_addend = (h->root.u.def.value
3829
                           + h->root.u.def.section->output_section->vma
3830
                           + h->root.u.def.section->output_offset);
3831
        }
3832
      else
3833
        {
3834
          rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_JUMP_SLOT);
3835
          rela.r_addend = 0;
3836
        }
3837
      loc = relplt->contents + plt_index * sizeof (Elf64_External_Rela);
3838 24 jeremybenn
      bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
3839
 
3840
      if (!h->def_regular)
3841
        {
3842
          /* Mark the symbol as undefined, rather than as defined in
3843
             the .plt section.  Leave the value if there were any
3844
             relocations where pointer equality matters (this is a clue
3845
             for the dynamic linker, to make function pointer
3846
             comparisons work between an application and shared
3847
             library), otherwise set it to zero.  If a function is only
3848
             called from a binary, there is no need to slow down
3849
             shared libraries because of that.  */
3850
          sym->st_shndx = SHN_UNDEF;
3851
          if (!h->pointer_equality_needed)
3852
            sym->st_value = 0;
3853
        }
3854
    }
3855
 
3856
  if (h->got.offset != (bfd_vma) -1
3857
      && ! GOT_TLS_GD_ANY_P (elf64_x86_64_hash_entry (h)->tls_type)
3858
      && elf64_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE)
3859
    {
3860
      Elf_Internal_Rela rela;
3861
      bfd_byte *loc;
3862
 
3863
      /* This symbol has an entry in the global offset table.  Set it
3864
         up.  */
3865 225 jeremybenn
      if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
3866 24 jeremybenn
        abort ();
3867
 
3868 225 jeremybenn
      rela.r_offset = (htab->elf.sgot->output_section->vma
3869
                       + htab->elf.sgot->output_offset
3870 24 jeremybenn
                       + (h->got.offset &~ (bfd_vma) 1));
3871
 
3872
      /* If this is a static link, or it is a -Bsymbolic link and the
3873
         symbol is defined locally or was forced to be local because
3874
         of a version file, we just want to emit a RELATIVE reloc.
3875
         The entry in the global offset table will already have been
3876
         initialized in the relocate_section function.  */
3877 225 jeremybenn
      if (h->def_regular
3878
          && h->type == STT_GNU_IFUNC)
3879 24 jeremybenn
        {
3880 225 jeremybenn
          if (info->shared)
3881
            {
3882
              /* Generate R_X86_64_GLOB_DAT.  */
3883
              goto do_glob_dat;
3884
            }
3885
          else
3886
            {
3887
              asection *plt;
3888
 
3889
              if (!h->pointer_equality_needed)
3890
                abort ();
3891
 
3892
              /* For non-shared object, we can't use .got.plt, which
3893
                 contains the real function addres if we need pointer
3894
                 equality.  We load the GOT entry with the PLT entry.  */
3895
              plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
3896
              bfd_put_64 (output_bfd, (plt->output_section->vma
3897
                                       + plt->output_offset
3898
                                       + h->plt.offset),
3899
                          htab->elf.sgot->contents + h->got.offset);
3900
              return TRUE;
3901
            }
3902
        }
3903
      else if (info->shared
3904
               && SYMBOL_REFERENCES_LOCAL (info, h))
3905
        {
3906
          if (!h->def_regular)
3907
            return FALSE;
3908 24 jeremybenn
          BFD_ASSERT((h->got.offset & 1) != 0);
3909
          rela.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
3910
          rela.r_addend = (h->root.u.def.value
3911
                           + h->root.u.def.section->output_section->vma
3912
                           + h->root.u.def.section->output_offset);
3913
        }
3914
      else
3915
        {
3916
          BFD_ASSERT((h->got.offset & 1) == 0);
3917 225 jeremybenn
do_glob_dat:
3918 24 jeremybenn
          bfd_put_64 (output_bfd, (bfd_vma) 0,
3919 225 jeremybenn
                      htab->elf.sgot->contents + h->got.offset);
3920 24 jeremybenn
          rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_GLOB_DAT);
3921
          rela.r_addend = 0;
3922
        }
3923
 
3924 225 jeremybenn
      loc = htab->elf.srelgot->contents;
3925
      loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
3926 24 jeremybenn
      bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
3927
    }
3928
 
3929
  if (h->needs_copy)
3930
    {
3931
      Elf_Internal_Rela rela;
3932
      bfd_byte *loc;
3933
 
3934
      /* This symbol needs a copy reloc.  Set it up.  */
3935
 
3936
      if (h->dynindx == -1
3937
          || (h->root.type != bfd_link_hash_defined
3938
              && h->root.type != bfd_link_hash_defweak)
3939
          || htab->srelbss == NULL)
3940
        abort ();
3941
 
3942
      rela.r_offset = (h->root.u.def.value
3943
                       + h->root.u.def.section->output_section->vma
3944
                       + h->root.u.def.section->output_offset);
3945
      rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_COPY);
3946
      rela.r_addend = 0;
3947
      loc = htab->srelbss->contents;
3948
      loc += htab->srelbss->reloc_count++ * sizeof (Elf64_External_Rela);
3949
      bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
3950
    }
3951
 
3952 225 jeremybenn
  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  SYM may
3953
     be NULL for local symbols.  */
3954
  if (sym != NULL
3955
      && (strcmp (h->root.root.string, "_DYNAMIC") == 0
3956
          || h == htab->elf.hgot))
3957 24 jeremybenn
    sym->st_shndx = SHN_ABS;
3958
 
3959
  return TRUE;
3960
}
3961
 
3962 225 jeremybenn
/* Finish up local dynamic symbol handling.  We set the contents of
3963
   various dynamic sections here.  */
3964
 
3965
static bfd_boolean
3966
elf64_x86_64_finish_local_dynamic_symbol (void **slot, void *inf)
3967
{
3968
  struct elf_link_hash_entry *h
3969
    = (struct elf_link_hash_entry *) *slot;
3970
  struct bfd_link_info *info
3971
    = (struct bfd_link_info *) inf;
3972
 
3973
  return elf64_x86_64_finish_dynamic_symbol (info->output_bfd,
3974
                                             info, h, NULL);
3975
}
3976
 
3977 24 jeremybenn
/* Used to decide how to sort relocs in an optimal manner for the
3978
   dynamic linker, before writing them out.  */
3979
 
3980
static enum elf_reloc_type_class
3981
elf64_x86_64_reloc_type_class (const Elf_Internal_Rela *rela)
3982
{
3983
  switch ((int) ELF64_R_TYPE (rela->r_info))
3984
    {
3985
    case R_X86_64_RELATIVE:
3986
      return reloc_class_relative;
3987
    case R_X86_64_JUMP_SLOT:
3988
      return reloc_class_plt;
3989
    case R_X86_64_COPY:
3990
      return reloc_class_copy;
3991
    default:
3992
      return reloc_class_normal;
3993
    }
3994
}
3995
 
3996
/* Finish up the dynamic sections.  */
3997
 
3998
static bfd_boolean
3999
elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
4000
{
4001
  struct elf64_x86_64_link_hash_table *htab;
4002
  bfd *dynobj;
4003
  asection *sdyn;
4004
 
4005
  htab = elf64_x86_64_hash_table (info);
4006
  dynobj = htab->elf.dynobj;
4007
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4008
 
4009
  if (htab->elf.dynamic_sections_created)
4010
    {
4011
      Elf64_External_Dyn *dyncon, *dynconend;
4012
 
4013 225 jeremybenn
      if (sdyn == NULL || htab->elf.sgot == NULL)
4014 24 jeremybenn
        abort ();
4015
 
4016
      dyncon = (Elf64_External_Dyn *) sdyn->contents;
4017
      dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
4018
      for (; dyncon < dynconend; dyncon++)
4019
        {
4020
          Elf_Internal_Dyn dyn;
4021
          asection *s;
4022
 
4023
          bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
4024
 
4025
          switch (dyn.d_tag)
4026
            {
4027
            default:
4028
              continue;
4029
 
4030
            case DT_PLTGOT:
4031 225 jeremybenn
              s = htab->elf.sgotplt;
4032 24 jeremybenn
              dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4033
              break;
4034
 
4035
            case DT_JMPREL:
4036 225 jeremybenn
              dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
4037 24 jeremybenn
              break;
4038
 
4039
            case DT_PLTRELSZ:
4040 225 jeremybenn
              s = htab->elf.srelplt->output_section;
4041 24 jeremybenn
              dyn.d_un.d_val = s->size;
4042
              break;
4043
 
4044
            case DT_RELASZ:
4045
              /* The procedure linkage table relocs (DT_JMPREL) should
4046
                 not be included in the overall relocs (DT_RELA).
4047
                 Therefore, we override the DT_RELASZ entry here to
4048
                 make it not include the JMPREL relocs.  Since the
4049
                 linker script arranges for .rela.plt to follow all
4050
                 other relocation sections, we don't have to worry
4051
                 about changing the DT_RELA entry.  */
4052 225 jeremybenn
              if (htab->elf.srelplt != NULL)
4053 24 jeremybenn
                {
4054 225 jeremybenn
                  s = htab->elf.srelplt->output_section;
4055 24 jeremybenn
                  dyn.d_un.d_val -= s->size;
4056
                }
4057
              break;
4058
 
4059
            case DT_TLSDESC_PLT:
4060 225 jeremybenn
              s = htab->elf.splt;
4061 24 jeremybenn
              dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
4062
                + htab->tlsdesc_plt;
4063
              break;
4064
 
4065
            case DT_TLSDESC_GOT:
4066 225 jeremybenn
              s = htab->elf.sgot;
4067 24 jeremybenn
              dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
4068
                + htab->tlsdesc_got;
4069
              break;
4070
            }
4071
 
4072
          bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
4073
        }
4074
 
4075
      /* Fill in the special first entry in the procedure linkage table.  */
4076 225 jeremybenn
      if (htab->elf.splt && htab->elf.splt->size > 0)
4077 24 jeremybenn
        {
4078
          /* Fill in the first entry in the procedure linkage table.  */
4079 225 jeremybenn
          memcpy (htab->elf.splt->contents, elf64_x86_64_plt0_entry,
4080 24 jeremybenn
                  PLT_ENTRY_SIZE);
4081
          /* Add offset for pushq GOT+8(%rip), since the instruction
4082
             uses 6 bytes subtract this value.  */
4083
          bfd_put_32 (output_bfd,
4084 225 jeremybenn
                      (htab->elf.sgotplt->output_section->vma
4085
                       + htab->elf.sgotplt->output_offset
4086 24 jeremybenn
                       + 8
4087 225 jeremybenn
                       - htab->elf.splt->output_section->vma
4088
                       - htab->elf.splt->output_offset
4089 24 jeremybenn
                       - 6),
4090 225 jeremybenn
                      htab->elf.splt->contents + 2);
4091 24 jeremybenn
          /* Add offset for jmp *GOT+16(%rip). The 12 is the offset to
4092
             the end of the instruction.  */
4093
          bfd_put_32 (output_bfd,
4094 225 jeremybenn
                      (htab->elf.sgotplt->output_section->vma
4095
                       + htab->elf.sgotplt->output_offset
4096 24 jeremybenn
                       + 16
4097 225 jeremybenn
                       - htab->elf.splt->output_section->vma
4098
                       - htab->elf.splt->output_offset
4099 24 jeremybenn
                       - 12),
4100 225 jeremybenn
                      htab->elf.splt->contents + 8);
4101 24 jeremybenn
 
4102 225 jeremybenn
          elf_section_data (htab->elf.splt->output_section)->this_hdr.sh_entsize =
4103 24 jeremybenn
            PLT_ENTRY_SIZE;
4104
 
4105
          if (htab->tlsdesc_plt)
4106
            {
4107
              bfd_put_64 (output_bfd, (bfd_vma) 0,
4108 225 jeremybenn
                          htab->elf.sgot->contents + htab->tlsdesc_got);
4109 24 jeremybenn
 
4110 225 jeremybenn
              memcpy (htab->elf.splt->contents + htab->tlsdesc_plt,
4111 24 jeremybenn
                      elf64_x86_64_plt0_entry,
4112
                      PLT_ENTRY_SIZE);
4113
 
4114
              /* Add offset for pushq GOT+8(%rip), since the
4115
                 instruction uses 6 bytes subtract this value.  */
4116
              bfd_put_32 (output_bfd,
4117 225 jeremybenn
                          (htab->elf.sgotplt->output_section->vma
4118
                           + htab->elf.sgotplt->output_offset
4119 24 jeremybenn
                           + 8
4120 225 jeremybenn
                           - htab->elf.splt->output_section->vma
4121
                           - htab->elf.splt->output_offset
4122 24 jeremybenn
                           - htab->tlsdesc_plt
4123
                           - 6),
4124 225 jeremybenn
                          htab->elf.splt->contents + htab->tlsdesc_plt + 2);
4125 24 jeremybenn
              /* Add offset for jmp *GOT+TDG(%rip), where TGD stands for
4126
                 htab->tlsdesc_got. The 12 is the offset to the end of
4127
                 the instruction.  */
4128
              bfd_put_32 (output_bfd,
4129 225 jeremybenn
                          (htab->elf.sgot->output_section->vma
4130
                           + htab->elf.sgot->output_offset
4131 24 jeremybenn
                           + htab->tlsdesc_got
4132 225 jeremybenn
                           - htab->elf.splt->output_section->vma
4133
                           - htab->elf.splt->output_offset
4134 24 jeremybenn
                           - htab->tlsdesc_plt
4135
                           - 12),
4136 225 jeremybenn
                          htab->elf.splt->contents + htab->tlsdesc_plt + 8);
4137 24 jeremybenn
            }
4138
        }
4139
    }
4140
 
4141 225 jeremybenn
  if (htab->elf.sgotplt)
4142 24 jeremybenn
    {
4143
      /* Fill in the first three entries in the global offset table.  */
4144 225 jeremybenn
      if (htab->elf.sgotplt->size > 0)
4145 24 jeremybenn
        {
4146
          /* Set the first entry in the global offset table to the address of
4147
             the dynamic section.  */
4148
          if (sdyn == NULL)
4149 225 jeremybenn
            bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents);
4150 24 jeremybenn
          else
4151
            bfd_put_64 (output_bfd,
4152
                        sdyn->output_section->vma + sdyn->output_offset,
4153 225 jeremybenn
                        htab->elf.sgotplt->contents);
4154 24 jeremybenn
          /* Write GOT[1] and GOT[2], needed for the dynamic linker.  */
4155 225 jeremybenn
          bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
4156
          bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE*2);
4157 24 jeremybenn
        }
4158
 
4159 225 jeremybenn
      elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize =
4160 24 jeremybenn
        GOT_ENTRY_SIZE;
4161
    }
4162
 
4163 225 jeremybenn
  if (htab->elf.sgot && htab->elf.sgot->size > 0)
4164
    elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
4165 24 jeremybenn
      = GOT_ENTRY_SIZE;
4166
 
4167 225 jeremybenn
  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
4168
  htab_traverse (htab->loc_hash_table,
4169
                 elf64_x86_64_finish_local_dynamic_symbol,
4170
                 info);
4171
 
4172 24 jeremybenn
  return TRUE;
4173
}
4174
 
4175
/* Return address for Ith PLT stub in section PLT, for relocation REL
4176
   or (bfd_vma) -1 if it should not be included.  */
4177
 
4178
static bfd_vma
4179
elf64_x86_64_plt_sym_val (bfd_vma i, const asection *plt,
4180
                          const arelent *rel ATTRIBUTE_UNUSED)
4181
{
4182
  return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
4183
}
4184
 
4185
/* Handle an x86-64 specific section when reading an object file.  This
4186
   is called when elfcode.h finds a section with an unknown type.  */
4187
 
4188
static bfd_boolean
4189
elf64_x86_64_section_from_shdr (bfd *abfd,
4190
                                Elf_Internal_Shdr *hdr,
4191
                                const char *name,
4192
                                int shindex)
4193
{
4194
  if (hdr->sh_type != SHT_X86_64_UNWIND)
4195
    return FALSE;
4196
 
4197
  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
4198
    return FALSE;
4199
 
4200
  return TRUE;
4201
}
4202
 
4203
/* Hook called by the linker routine which adds symbols from an object
4204
   file.  We use it to put SHN_X86_64_LCOMMON items in .lbss, instead
4205
   of .bss.  */
4206
 
4207
static bfd_boolean
4208
elf64_x86_64_add_symbol_hook (bfd *abfd,
4209 225 jeremybenn
                              struct bfd_link_info *info,
4210 24 jeremybenn
                              Elf_Internal_Sym *sym,
4211
                              const char **namep ATTRIBUTE_UNUSED,
4212
                              flagword *flagsp ATTRIBUTE_UNUSED,
4213 225 jeremybenn
                              asection **secp,
4214
                              bfd_vma *valp)
4215 24 jeremybenn
{
4216
  asection *lcomm;
4217
 
4218
  switch (sym->st_shndx)
4219
    {
4220
    case SHN_X86_64_LCOMMON:
4221
      lcomm = bfd_get_section_by_name (abfd, "LARGE_COMMON");
4222
      if (lcomm == NULL)
4223
        {
4224
          lcomm = bfd_make_section_with_flags (abfd,
4225
                                               "LARGE_COMMON",
4226
                                               (SEC_ALLOC
4227
                                                | SEC_IS_COMMON
4228
                                                | SEC_LINKER_CREATED));
4229
          if (lcomm == NULL)
4230
            return FALSE;
4231
          elf_section_flags (lcomm) |= SHF_X86_64_LARGE;
4232
        }
4233
      *secp = lcomm;
4234
      *valp = sym->st_size;
4235
      break;
4236
    }
4237 225 jeremybenn
 
4238
  if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
4239
    elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
4240
 
4241 24 jeremybenn
  return TRUE;
4242
}
4243
 
4244
 
4245
/* Given a BFD section, try to locate the corresponding ELF section
4246
   index.  */
4247
 
4248
static bfd_boolean
4249
elf64_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
4250
                                           asection *sec, int *index)
4251
{
4252
  if (sec == &_bfd_elf_large_com_section)
4253
    {
4254
      *index = SHN_X86_64_LCOMMON;
4255
      return TRUE;
4256
    }
4257
  return FALSE;
4258
}
4259
 
4260
/* Process a symbol.  */
4261
 
4262
static void
4263
elf64_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
4264
                                asymbol *asym)
4265
{
4266
  elf_symbol_type *elfsym = (elf_symbol_type *) asym;
4267
 
4268
  switch (elfsym->internal_elf_sym.st_shndx)
4269
    {
4270
    case SHN_X86_64_LCOMMON:
4271
      asym->section = &_bfd_elf_large_com_section;
4272
      asym->value = elfsym->internal_elf_sym.st_size;
4273
      /* Common symbol doesn't set BSF_GLOBAL.  */
4274
      asym->flags &= ~BSF_GLOBAL;
4275
      break;
4276
    }
4277
}
4278
 
4279
static bfd_boolean
4280
elf64_x86_64_common_definition (Elf_Internal_Sym *sym)
4281
{
4282
  return (sym->st_shndx == SHN_COMMON
4283
          || sym->st_shndx == SHN_X86_64_LCOMMON);
4284
}
4285
 
4286
static unsigned int
4287
elf64_x86_64_common_section_index (asection *sec)
4288
{
4289
  if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
4290
    return SHN_COMMON;
4291
  else
4292
    return SHN_X86_64_LCOMMON;
4293
}
4294
 
4295
static asection *
4296
elf64_x86_64_common_section (asection *sec)
4297
{
4298
  if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
4299
    return bfd_com_section_ptr;
4300
  else
4301
    return &_bfd_elf_large_com_section;
4302
}
4303
 
4304
static bfd_boolean
4305
elf64_x86_64_merge_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
4306
                           struct elf_link_hash_entry **sym_hash ATTRIBUTE_UNUSED,
4307
                           struct elf_link_hash_entry *h,
4308
                           Elf_Internal_Sym *sym,
4309
                           asection **psec,
4310
                           bfd_vma *pvalue ATTRIBUTE_UNUSED,
4311
                           unsigned int *pold_alignment ATTRIBUTE_UNUSED,
4312
                           bfd_boolean *skip ATTRIBUTE_UNUSED,
4313
                           bfd_boolean *override ATTRIBUTE_UNUSED,
4314
                           bfd_boolean *type_change_ok ATTRIBUTE_UNUSED,
4315
                           bfd_boolean *size_change_ok ATTRIBUTE_UNUSED,
4316
                           bfd_boolean *newdef ATTRIBUTE_UNUSED,
4317
                           bfd_boolean *newdyn,
4318
                           bfd_boolean *newdyncommon ATTRIBUTE_UNUSED,
4319
                           bfd_boolean *newweak ATTRIBUTE_UNUSED,
4320
                           bfd *abfd ATTRIBUTE_UNUSED,
4321
                           asection **sec,
4322
                           bfd_boolean *olddef ATTRIBUTE_UNUSED,
4323
                           bfd_boolean *olddyn,
4324
                           bfd_boolean *olddyncommon ATTRIBUTE_UNUSED,
4325
                           bfd_boolean *oldweak ATTRIBUTE_UNUSED,
4326
                           bfd *oldbfd,
4327
                           asection **oldsec)
4328
{
4329
  /* A normal common symbol and a large common symbol result in a
4330
     normal common symbol.  We turn the large common symbol into a
4331
     normal one.  */
4332
  if (!*olddyn
4333
      && h->root.type == bfd_link_hash_common
4334
      && !*newdyn
4335
      && bfd_is_com_section (*sec)
4336
      && *oldsec != *sec)
4337
    {
4338
      if (sym->st_shndx == SHN_COMMON
4339
          && (elf_section_flags (*oldsec) & SHF_X86_64_LARGE) != 0)
4340
        {
4341
          h->root.u.c.p->section
4342
            = bfd_make_section_old_way (oldbfd, "COMMON");
4343
          h->root.u.c.p->section->flags = SEC_ALLOC;
4344
        }
4345
      else if (sym->st_shndx == SHN_X86_64_LCOMMON
4346
               && (elf_section_flags (*oldsec) & SHF_X86_64_LARGE) == 0)
4347
        *psec = *sec = bfd_com_section_ptr;
4348
    }
4349
 
4350
  return TRUE;
4351
}
4352
 
4353
static int
4354
elf64_x86_64_additional_program_headers (bfd *abfd,
4355
                                         struct bfd_link_info *info ATTRIBUTE_UNUSED)
4356
{
4357
  asection *s;
4358
  int count = 0;
4359
 
4360
  /* Check to see if we need a large readonly segment.  */
4361
  s = bfd_get_section_by_name (abfd, ".lrodata");
4362
  if (s && (s->flags & SEC_LOAD))
4363
    count++;
4364
 
4365
  /* Check to see if we need a large data segment.  Since .lbss sections
4366
     is placed right after the .bss section, there should be no need for
4367
     a large data segment just because of .lbss.  */
4368
  s = bfd_get_section_by_name (abfd, ".ldata");
4369
  if (s && (s->flags & SEC_LOAD))
4370
    count++;
4371
 
4372
  return count;
4373
}
4374
 
4375
/* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
4376
 
4377
static bfd_boolean
4378
elf64_x86_64_hash_symbol (struct elf_link_hash_entry *h)
4379
{
4380
  if (h->plt.offset != (bfd_vma) -1
4381
      && !h->def_regular
4382
      && !h->pointer_equality_needed)
4383
    return FALSE;
4384
 
4385
  return _bfd_elf_hash_symbol (h);
4386
}
4387
 
4388
static const struct bfd_elf_special_section
4389
  elf64_x86_64_special_sections[]=
4390
{
4391
  { STRING_COMMA_LEN (".gnu.linkonce.lb"), -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
4392
  { STRING_COMMA_LEN (".gnu.linkonce.lr"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
4393
  { STRING_COMMA_LEN (".gnu.linkonce.lt"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR + SHF_X86_64_LARGE},
4394
  { STRING_COMMA_LEN (".lbss"),            -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
4395
  { STRING_COMMA_LEN (".ldata"),           -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
4396
  { STRING_COMMA_LEN (".lrodata"),         -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
4397
  { NULL,                       0,          0, 0,            0 }
4398
};
4399
 
4400
#define TARGET_LITTLE_SYM                   bfd_elf64_x86_64_vec
4401
#define TARGET_LITTLE_NAME                  "elf64-x86-64"
4402
#define ELF_ARCH                            bfd_arch_i386
4403
#define ELF_MACHINE_CODE                    EM_X86_64
4404
#define ELF_MAXPAGESIZE                     0x200000
4405
#define ELF_MINPAGESIZE                     0x1000
4406
#define ELF_COMMONPAGESIZE                  0x1000
4407
 
4408
#define elf_backend_can_gc_sections         1
4409
#define elf_backend_can_refcount            1
4410
#define elf_backend_want_got_plt            1
4411
#define elf_backend_plt_readonly            1
4412
#define elf_backend_want_plt_sym            0
4413
#define elf_backend_got_header_size         (GOT_ENTRY_SIZE*3)
4414
#define elf_backend_rela_normal             1
4415
 
4416
#define elf_info_to_howto                   elf64_x86_64_info_to_howto
4417
 
4418
#define bfd_elf64_bfd_link_hash_table_create \
4419
  elf64_x86_64_link_hash_table_create
4420 225 jeremybenn
#define bfd_elf64_bfd_link_hash_table_free \
4421
  elf64_x86_64_link_hash_table_free
4422 24 jeremybenn
#define bfd_elf64_bfd_reloc_type_lookup     elf64_x86_64_reloc_type_lookup
4423
#define bfd_elf64_bfd_reloc_name_lookup \
4424
  elf64_x86_64_reloc_name_lookup
4425
 
4426
#define elf_backend_adjust_dynamic_symbol   elf64_x86_64_adjust_dynamic_symbol
4427
#define elf_backend_relocs_compatible       _bfd_elf_relocs_compatible
4428
#define elf_backend_check_relocs            elf64_x86_64_check_relocs
4429
#define elf_backend_copy_indirect_symbol    elf64_x86_64_copy_indirect_symbol
4430
#define elf_backend_create_dynamic_sections elf64_x86_64_create_dynamic_sections
4431
#define elf_backend_finish_dynamic_sections elf64_x86_64_finish_dynamic_sections
4432
#define elf_backend_finish_dynamic_symbol   elf64_x86_64_finish_dynamic_symbol
4433
#define elf_backend_gc_mark_hook            elf64_x86_64_gc_mark_hook
4434
#define elf_backend_gc_sweep_hook           elf64_x86_64_gc_sweep_hook
4435
#define elf_backend_grok_prstatus           elf64_x86_64_grok_prstatus
4436
#define elf_backend_grok_psinfo             elf64_x86_64_grok_psinfo
4437
#define elf_backend_reloc_type_class        elf64_x86_64_reloc_type_class
4438
#define elf_backend_relocate_section        elf64_x86_64_relocate_section
4439
#define elf_backend_size_dynamic_sections   elf64_x86_64_size_dynamic_sections
4440
#define elf_backend_always_size_sections    elf64_x86_64_always_size_sections
4441
#define elf_backend_init_index_section      _bfd_elf_init_1_index_section
4442
#define elf_backend_plt_sym_val             elf64_x86_64_plt_sym_val
4443
#define elf_backend_object_p                elf64_x86_64_elf_object_p
4444
#define bfd_elf64_mkobject                  elf64_x86_64_mkobject
4445
 
4446
#define elf_backend_section_from_shdr \
4447
        elf64_x86_64_section_from_shdr
4448
 
4449
#define elf_backend_section_from_bfd_section \
4450
  elf64_x86_64_elf_section_from_bfd_section
4451
#define elf_backend_add_symbol_hook \
4452
  elf64_x86_64_add_symbol_hook
4453
#define elf_backend_symbol_processing \
4454
  elf64_x86_64_symbol_processing
4455
#define elf_backend_common_section_index \
4456
  elf64_x86_64_common_section_index
4457
#define elf_backend_common_section \
4458
  elf64_x86_64_common_section
4459
#define elf_backend_common_definition \
4460
  elf64_x86_64_common_definition
4461
#define elf_backend_merge_symbol \
4462
  elf64_x86_64_merge_symbol
4463
#define elf_backend_special_sections \
4464
  elf64_x86_64_special_sections
4465
#define elf_backend_additional_program_headers \
4466
  elf64_x86_64_additional_program_headers
4467
#define elf_backend_hash_symbol \
4468
  elf64_x86_64_hash_symbol
4469
 
4470 225 jeremybenn
#undef  elf_backend_post_process_headers
4471
#define elf_backend_post_process_headers  _bfd_elf_set_osabi
4472
 
4473 24 jeremybenn
#include "elf64-target.h"
4474
 
4475
/* FreeBSD support.  */
4476
 
4477
#undef  TARGET_LITTLE_SYM
4478
#define TARGET_LITTLE_SYM                   bfd_elf64_x86_64_freebsd_vec
4479
#undef  TARGET_LITTLE_NAME
4480
#define TARGET_LITTLE_NAME                  "elf64-x86-64-freebsd"
4481
 
4482
#undef  ELF_OSABI
4483
#define ELF_OSABI                           ELFOSABI_FREEBSD
4484
 
4485 225 jeremybenn
#undef  elf64_bed
4486
#define elf64_bed elf64_x86_64_fbsd_bed
4487
 
4488
#include "elf64-target.h"
4489
 
4490
/* Intel L1OM support.  */
4491
 
4492
static bfd_boolean
4493
elf64_l1om_elf_object_p (bfd *abfd)
4494
{
4495
  /* Set the right machine number for an L1OM elf64 file.  */
4496
  bfd_default_set_arch_mach (abfd, bfd_arch_l1om, bfd_mach_l1om);
4497
  return TRUE;
4498
}
4499
 
4500
#undef  TARGET_LITTLE_SYM
4501
#define TARGET_LITTLE_SYM                   bfd_elf64_l1om_vec
4502
#undef  TARGET_LITTLE_NAME
4503
#define TARGET_LITTLE_NAME                  "elf64-l1om"
4504
#undef ELF_ARCH
4505
#define ELF_ARCH                            bfd_arch_l1om
4506
 
4507
#undef  ELF_MACHINE_CODE
4508
#define ELF_MACHINE_CODE                    EM_L1OM
4509
 
4510
#undef  ELF_OSABI
4511
 
4512
#undef  elf64_bed
4513
#define elf64_bed elf64_l1om_bed
4514
 
4515
#undef elf_backend_object_p
4516
#define elf_backend_object_p                elf64_l1om_elf_object_p
4517
 
4518 24 jeremybenn
#undef  elf_backend_post_process_headers
4519
 
4520 225 jeremybenn
#include "elf64-target.h"
4521
 
4522
/* FreeBSD L1OM support.  */
4523
 
4524
#undef  TARGET_LITTLE_SYM
4525
#define TARGET_LITTLE_SYM                   bfd_elf64_l1om_freebsd_vec
4526
#undef  TARGET_LITTLE_NAME
4527
#define TARGET_LITTLE_NAME                  "elf64-l1om-freebsd"
4528
 
4529
#undef  ELF_OSABI
4530
#define ELF_OSABI                           ELFOSABI_FREEBSD
4531
 
4532 24 jeremybenn
#undef  elf64_bed
4533 225 jeremybenn
#define elf64_bed elf64_l1om_fbsd_bed
4534 24 jeremybenn
 
4535 225 jeremybenn
#undef  elf_backend_post_process_headers
4536
#define elf_backend_post_process_headers  _bfd_elf_set_osabi
4537
 
4538 24 jeremybenn
#include "elf64-target.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.