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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [elf64-x86-64.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* X86-64 specific support for 64-bit ELF
2
   Copyright 2000, 2001 Free Software Foundation, Inc.
3
   Contributed by Jan Hubicka <jh@suse.cz>.
4
 
5
This file is part of BFD, the Binary File Descriptor library.
6
 
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
#include "bfd.h"
22
#include "sysdep.h"
23
#include "libbfd.h"
24
#include "elf-bfd.h"
25
 
26
#include "elf/x86-64.h"
27
 
28
/* We use only the RELA entries.  */
29
#define USE_RELA
30
 
31
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
32
#define MINUS_ONE (~ (bfd_vma) 0)
33
 
34
/* The relocation "howto" table.  Order of fields:
35
   type, size, bitsize, pc_relative, complain_on_overflow,
36
   special_function, name, partial_inplace, src_mask, dst_pack, pcrel_offset.  */
37
static reloc_howto_type x86_64_elf_howto_table[] =
38
{
39
  HOWTO(R_X86_64_NONE, 0, 0, 0, false, 0, complain_overflow_dont,
40
        bfd_elf_generic_reloc, "R_X86_64_NONE", false, 0x00000000, 0x00000000,
41
        false),
42
  HOWTO(R_X86_64_64, 0, 4, 64, false, 0, complain_overflow_bitfield,
43
        bfd_elf_generic_reloc, "R_X86_64_64", false, MINUS_ONE, MINUS_ONE,
44
        false),
45
  HOWTO(R_X86_64_PC32, 0, 4, 32, true, 0, complain_overflow_signed,
46
        bfd_elf_generic_reloc, "R_X86_64_PC32", false, 0xffffffff, 0xffffffff,
47
        true),
48
  HOWTO(R_X86_64_GOT32, 0, 4, 32, false, 0, complain_overflow_signed,
49
        bfd_elf_generic_reloc, "R_X86_64_GOT32", false, 0xffffffff, 0xffffffff,
50
        false),
51
  HOWTO(R_X86_64_PLT32, 0, 4, 32, true, 0, complain_overflow_signed,
52
        bfd_elf_generic_reloc, "R_X86_64_PLT32", false, 0xffffffff, 0xffffffff,
53
        true),
54
  HOWTO(R_X86_64_COPY, 0, 4, 32, false, 0, complain_overflow_bitfield,
55
        bfd_elf_generic_reloc, "R_X86_64_COPY", false, 0xffffffff, 0xffffffff,
56
        false),
57
  HOWTO(R_X86_64_GLOB_DAT, 0, 4, 64, false, 0, complain_overflow_bitfield,
58
        bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", false, MINUS_ONE,
59
        MINUS_ONE, false),
60
  HOWTO(R_X86_64_JUMP_SLOT, 0, 4, 64, false, 0, complain_overflow_bitfield,
61
        bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", false, MINUS_ONE,
62
        MINUS_ONE, false),
63
  HOWTO(R_X86_64_RELATIVE, 0, 4, 64, false, 0, complain_overflow_bitfield,
64
        bfd_elf_generic_reloc, "R_X86_64_RELATIVE", false, MINUS_ONE,
65
        MINUS_ONE, false),
66
  HOWTO(R_X86_64_GOTPCREL, 0, 4, 32, true,0 , complain_overflow_signed,
67
        bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", false, 0xffffffff,
68
        0xffffffff, true),
69
  HOWTO(R_X86_64_32, 0, 4, 32, false, 0, complain_overflow_unsigned,
70
        bfd_elf_generic_reloc, "R_X86_64_32", false, 0xffffffff, 0xffffffff,
71
        false),
72
  HOWTO(R_X86_64_32S, 0, 4, 32, false, 0, complain_overflow_signed,
73
        bfd_elf_generic_reloc, "R_X86_64_32S", false, 0xffffffff, 0xffffffff,
74
        false),
75
  HOWTO(R_X86_64_16, 0, 1, 16, false, 0, complain_overflow_bitfield,
76
        bfd_elf_generic_reloc, "R_X86_64_16", false, 0xffff, 0xffff, false),
77
  HOWTO(R_X86_64_PC16,0, 1, 16, true, 0, complain_overflow_bitfield,
78
        bfd_elf_generic_reloc, "R_X86_64_PC16", false, 0xffff, 0xffff, true),
79
  HOWTO(R_X86_64_8, 0, 0, 8, false, 0, complain_overflow_signed,
80
        bfd_elf_generic_reloc, "R_X86_64_8", false, 0xff, 0xff, false),
81
  HOWTO(R_X86_64_PC8, 0, 0, 8, true, 0, complain_overflow_signed,
82
        bfd_elf_generic_reloc, "R_X86_64_PC8", false, 0xff, 0xff, true),
83
 
84
/* GNU extension to record C++ vtable hierarchy.  */
85
  HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, false, 0, complain_overflow_dont,
86
         NULL, "R_X86_64_GNU_VTINHERIT", false, 0, 0, false),
87
 
88
/* GNU extension to record C++ vtable member usage.  */
89
  HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, false, 0, complain_overflow_dont,
90
         _bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", false, 0, 0,
91
         false)
92
};
93
 
94
/* Map BFD relocs to the x86_64 elf relocs.  */
95
struct elf_reloc_map
96
{
97
  bfd_reloc_code_real_type bfd_reloc_val;
98
  unsigned char elf_reloc_val;
99
};
100
 
101
static CONST struct elf_reloc_map x86_64_reloc_map[] =
102
{
103
  { BFD_RELOC_NONE,             R_X86_64_NONE, },
104
  { BFD_RELOC_64,               R_X86_64_64,   },
105
  { BFD_RELOC_32_PCREL,         R_X86_64_PC32, },
106
  { BFD_RELOC_X86_64_GOT32,     R_X86_64_GOT32,},
107
  { BFD_RELOC_X86_64_PLT32,     R_X86_64_PLT32,},
108
  { BFD_RELOC_X86_64_COPY,      R_X86_64_COPY, },
109
  { BFD_RELOC_X86_64_GLOB_DAT,  R_X86_64_GLOB_DAT, },
110
  { BFD_RELOC_X86_64_JUMP_SLOT, R_X86_64_JUMP_SLOT, },
111
  { BFD_RELOC_X86_64_RELATIVE,  R_X86_64_RELATIVE, },
112
  { BFD_RELOC_X86_64_GOTPCREL,  R_X86_64_GOTPCREL, },
113
  { BFD_RELOC_32,               R_X86_64_32, },
114
  { BFD_RELOC_X86_64_32S,       R_X86_64_32S, },
115
  { BFD_RELOC_16,               R_X86_64_16, },
116
  { BFD_RELOC_16_PCREL,         R_X86_64_PC16, },
117
  { BFD_RELOC_8,                R_X86_64_8, },
118
  { BFD_RELOC_8_PCREL,          R_X86_64_PC8, },
119
  { BFD_RELOC_VTABLE_INHERIT,   R_X86_64_GNU_VTINHERIT, },
120
  { BFD_RELOC_VTABLE_ENTRY,     R_X86_64_GNU_VTENTRY, },
121
};
122
 
123
static reloc_howto_type *elf64_x86_64_reloc_type_lookup
124
  PARAMS ((bfd *, bfd_reloc_code_real_type));
125
static void elf64_x86_64_info_to_howto
126
  PARAMS ((bfd *, arelent *, Elf64_Internal_Rela *));
127
static struct bfd_link_hash_table *elf64_x86_64_link_hash_table_create
128
  PARAMS ((bfd *));
129
 
130
static struct bfd_hash_entry *elf64_x86_64_link_hash_newfunc
131
  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
132
static boolean elf64_x86_64_adjust_dynamic_symbol
133
  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
134
 
135
static boolean elf64_x86_64_size_dynamic_sections
136
  PARAMS ((bfd *, struct bfd_link_info *));
137
static boolean elf64_x86_64_relocate_section
138
  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
139
         Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
140
static boolean elf64_x86_64_finish_dynamic_symbol
141
  PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
142
           Elf_Internal_Sym *sym));
143
static boolean elf64_x86_64_finish_dynamic_sections
144
  PARAMS ((bfd *, struct bfd_link_info *));
145
 
146
/* Given a BFD reloc type, return a HOWTO structure.  */
147
static reloc_howto_type *
148
elf64_x86_64_reloc_type_lookup (abfd, code)
149
     bfd *abfd ATTRIBUTE_UNUSED;
150
     bfd_reloc_code_real_type code;
151
{
152
  unsigned int i;
153
  for (i = 0; i < sizeof (x86_64_reloc_map) / sizeof (struct elf_reloc_map);
154
       i++)
155
    {
156
      if (x86_64_reloc_map[i].bfd_reloc_val == code)
157
        return &x86_64_elf_howto_table[(int)
158
                                       x86_64_reloc_map[i].elf_reloc_val];
159
    }
160
  return 0;
161
}
162
 
163
/* Given an x86_64 ELF reloc type, fill in an arelent structure.  */
164
 
165
static void
166
elf64_x86_64_info_to_howto (abfd, cache_ptr, dst)
167
     bfd *abfd ATTRIBUTE_UNUSED;
168
     arelent *cache_ptr;
169
     Elf64_Internal_Rela *dst;
170
{
171
  unsigned r_type, i;
172
 
173
  r_type = ELF64_R_TYPE (dst->r_info);
174
  if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT)
175
    {
176
      BFD_ASSERT (r_type <= (unsigned int) R_X86_64_PC8);
177
      i = r_type;
178
    }
179
  else
180
    {
181
      BFD_ASSERT (r_type < (unsigned int) R_X86_64_max);
182
      i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_PC8 - 1);
183
    }
184
  cache_ptr->howto = &x86_64_elf_howto_table[i];
185
  BFD_ASSERT (r_type == cache_ptr->howto->type);
186
}
187
 
188
/* Functions for the x86-64 ELF linker.  */
189
 
190
/* The name of the dynamic interpreter.  This is put in the .interp
191
   section.  */
192
 
193
#define ELF_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
194
 
195
/* The size in bytes of an entry in the global offset table.  */
196
 
197
#define GOT_ENTRY_SIZE 8
198
 
199
/* The size in bytes of an entry in the procedure linkage table.  */
200
 
201
#define PLT_ENTRY_SIZE 16
202
 
203
/* The first entry in a procedure linkage table looks like this.  See the
204
   SVR4 ABI i386 supplement and the x86-64 ABI to see how this works.  */
205
 
206
static const bfd_byte elf64_x86_64_plt0_entry[PLT_ENTRY_SIZE] =
207
{
208
  0xff, 0x35, 8, 0, 0, 0,  /* pushq GOT+8(%rip)  */
209
  0xff, 0x25, 16, 0, 0, 0, /* jmpq *GOT+16(%rip) */
210
  0x90, 0x90, 0x90, 0x90        /* pad out to 16 bytes with nops.  */
211
};
212
 
213
/* Subsequent entries in a procedure linkage table look like this.  */
214
 
215
static const bfd_byte elf64_x86_64_plt_entry[PLT_ENTRY_SIZE] =
216
{
217
  0xff, 0x25,   /* jmpq *name@GOTPC(%rip) */
218
  0, 0, 0, 0,       /* replaced with offset to this symbol in .got.  */
219
  0x68,         /* pushq immediate */
220
  0, 0, 0, 0,       /* replaced with index into relocation table.  */
221
  0xe9,         /* jmp relative */
222
  0, 0, 0, 0        /* replaced with offset to start of .plt0.  */
223
};
224
 
225
/* The x86-64 linker needs to keep track of the number of relocs that
226
   it decides to copy in check_relocs for each symbol.  This is so
227
   that it can discard PC relative relocs if it doesn't need them when
228
   linking with -Bsymbolic.  We store the information in a field
229
   extending the regular ELF linker hash table.  */
230
 
231
/* This structure keeps track of the number of PC relative relocs we
232
   have copied for a given symbol.  */
233
 
234
struct elf64_x86_64_pcrel_relocs_copied
235
{
236
  /* Next section.  */
237
  struct elf64_x86_64_pcrel_relocs_copied *next;
238
  /* A section in dynobj.  */
239
  asection *section;
240
  /* Number of relocs copied in this section.  */
241
  bfd_size_type count;
242
};
243
 
244
/* x86-64 ELF linker hash entry.  */
245
 
246
struct elf64_x86_64_link_hash_entry
247
{
248
  struct elf_link_hash_entry root;
249
 
250
  /* Number of PC relative relocs copied for this symbol.  */
251
  struct elf64_x86_64_pcrel_relocs_copied *pcrel_relocs_copied;
252
};
253
 
254
/* x86-64  ELF linker hash table.  */
255
 
256
struct elf64_x86_64_link_hash_table
257
{
258
  struct elf_link_hash_table root;
259
};
260
 
261
/* Declare this now that the above structures are defined.  */
262
 
263
static boolean elf64_x86_64_discard_copies
264
  PARAMS ((struct elf64_x86_64_link_hash_entry *, PTR));
265
 
266
/* Traverse an x86-64 ELF linker hash table.  */
267
 
268
#define elf64_x86_64_link_hash_traverse(table, func, info)              \
269
  (elf_link_hash_traverse                                               \
270
   (&(table)->root,                                                     \
271
    (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func),  \
272
    (info)))
273
 
274
/* Get the x86-64 ELF linker hash table from a link_info structure.  */
275
 
276
#define elf64_x86_64_hash_table(p) \
277
  ((struct elf64_x86_64_link_hash_table *) ((p)->hash))
278
 
279
/* Create an entry in an x86-64 ELF linker hash table.  */
280
 
281
static struct bfd_hash_entry *
282
elf64_x86_64_link_hash_newfunc (entry, table, string)
283
     struct bfd_hash_entry *entry;
284
     struct bfd_hash_table *table;
285
     const char *string;
286
{
287
  struct elf64_x86_64_link_hash_entry *ret =
288
    (struct elf64_x86_64_link_hash_entry *) entry;
289
 
290
  /* Allocate the structure if it has not already been allocated by a
291
     subclass.  */
292
  if (ret == (struct elf64_x86_64_link_hash_entry *) NULL)
293
    ret = ((struct elf64_x86_64_link_hash_entry *)
294
           bfd_hash_allocate (table,
295
                              sizeof (struct elf64_x86_64_link_hash_entry)));
296
  if (ret == (struct elf64_x86_64_link_hash_entry *) NULL)
297
    return (struct bfd_hash_entry *) ret;
298
 
299
  /* Call the allocation method of the superclass.  */
300
  ret = ((struct elf64_x86_64_link_hash_entry *)
301
         _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
302
                                     table, string));
303
  if (ret != (struct elf64_x86_64_link_hash_entry *) NULL)
304
    {
305
      ret->pcrel_relocs_copied = NULL;
306
    }
307
 
308
  return (struct bfd_hash_entry *) ret;
309
}
310
 
311
/* Create an X86-64 ELF linker hash table.  */
312
 
313
static struct bfd_link_hash_table *
314
elf64_x86_64_link_hash_table_create (abfd)
315
     bfd *abfd;
316
{
317
  struct elf64_x86_64_link_hash_table *ret;
318
 
319
  ret = ((struct elf64_x86_64_link_hash_table *)
320
         bfd_alloc (abfd, sizeof (struct elf64_x86_64_link_hash_table)));
321
  if (ret == (struct elf64_x86_64_link_hash_table *) NULL)
322
    return NULL;
323
 
324
  if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
325
                                       elf64_x86_64_link_hash_newfunc))
326
    {
327
      bfd_release (abfd, ret);
328
      return NULL;
329
    }
330
 
331
  return &ret->root.root;
332
}
333
 
334
boolean
335
elf64_x86_64_elf_object_p (abfd)
336
     bfd *abfd;
337
{
338
  /* Set the right machine number for an x86-64 elf64 file.  */
339
  bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
340
  return true;
341
}
342
 
343
/* Look through the relocs for a section during the first phase, and
344
   allocate space in the global offset table or procedure linkage
345
   table.  */
346
 
347
static boolean
348
elf64_x86_64_check_relocs (abfd, info, sec, relocs)
349
     bfd *abfd;
350
     struct bfd_link_info *info;
351
     asection *sec;
352
     const Elf_Internal_Rela *relocs;
353
{
354
  bfd *dynobj;
355
  Elf_Internal_Shdr *symtab_hdr;
356
  struct elf_link_hash_entry **sym_hashes;
357
  bfd_signed_vma *local_got_refcounts;
358
  const Elf_Internal_Rela *rel;
359
  const Elf_Internal_Rela *rel_end;
360
  asection *sgot;
361
  asection *srelgot;
362
  asection *sreloc;
363
 
364
  if (info->relocateable)
365
    return true;
366
 
367
  dynobj = elf_hash_table (info)->dynobj;
368
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
369
  sym_hashes = elf_sym_hashes (abfd);
370
  local_got_refcounts = elf_local_got_refcounts (abfd);
371
 
372
  sgot = srelgot = sreloc = NULL;
373
  rel_end = relocs + sec->reloc_count;
374
  for (rel = relocs; rel < rel_end; rel++)
375
    {
376
      unsigned long r_symndx;
377
      struct elf_link_hash_entry *h;
378
 
379
      r_symndx = ELF64_R_SYM (rel->r_info);
380
      if (r_symndx < symtab_hdr->sh_info)
381
        h = NULL;
382
      else
383
        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
384
 
385
      /* Some relocs require a global offset table.  */
386
      if (dynobj == NULL)
387
        {
388
          switch (ELF64_R_TYPE (rel->r_info))
389
            {
390
            case R_X86_64_GOT32:
391
            case R_X86_64_GOTPCREL:
392
              elf_hash_table (info)->dynobj = dynobj = abfd;
393
              if (! _bfd_elf_create_got_section (dynobj, info))
394
                return false;
395
              break;
396
            }
397
        }
398
 
399
      switch (ELF64_R_TYPE (rel->r_info))
400
        {
401
        case R_X86_64_GOTPCREL:
402
        case R_X86_64_GOT32:
403
          /* This symbol requires a global offset table entry.  */
404
 
405
          if (sgot == NULL)
406
            {
407
              sgot = bfd_get_section_by_name (dynobj, ".got");
408
              BFD_ASSERT (sgot != NULL);
409
            }
410
 
411
          if (srelgot == NULL && (h != NULL || info->shared))
412
            {
413
              srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
414
              if (srelgot == NULL)
415
                {
416
                  srelgot = bfd_make_section (dynobj, ".rela.got");
417
                  if (srelgot == NULL
418
                      || ! bfd_set_section_flags (dynobj, srelgot,
419
                                                  (SEC_ALLOC
420
                                                   | SEC_LOAD
421
                                                   | SEC_HAS_CONTENTS
422
                                                   | SEC_IN_MEMORY
423
                                                   | SEC_LINKER_CREATED
424
                                                   | SEC_READONLY))
425
                      || ! bfd_set_section_alignment (dynobj, srelgot, 3))
426
                    return false;
427
                }
428
            }
429
 
430
          if (h != NULL)
431
            {
432
              if (h->got.refcount == -1)
433
                {
434
                  h->got.refcount = 1;
435
 
436
                  /* Make sure this symbol is output as a dynamic symbol.  */
437
                  if (h->dynindx == -1)
438
                    {
439
                      if (! bfd_elf64_link_record_dynamic_symbol (info, h))
440
                        return false;
441
                    }
442
 
443
                  sgot->_raw_size += GOT_ENTRY_SIZE;
444
                  srelgot->_raw_size += sizeof (Elf64_External_Rela);
445
                }
446
              else
447
                h->got.refcount += 1;
448
            }
449
          else
450
            {
451
              /* This is a global offset table entry for a local symbol.  */
452
              if (local_got_refcounts == NULL)
453
                {
454
                  size_t size;
455
 
456
                  size = symtab_hdr->sh_info * sizeof (bfd_signed_vma);
457
                  local_got_refcounts = ((bfd_signed_vma *)
458
                                         bfd_alloc (abfd, size));
459
                  if (local_got_refcounts == NULL)
460
                    return false;
461
                  elf_local_got_refcounts (abfd) = local_got_refcounts;
462
                  memset (local_got_refcounts, -1, size);
463
                }
464
              if (local_got_refcounts[r_symndx] == -1)
465
                {
466
                  local_got_refcounts[r_symndx] = 1;
467
 
468
                  sgot->_raw_size += GOT_ENTRY_SIZE;
469
                  if (info->shared)
470
                    {
471
                      /* If we are generating a shared object, we need to
472
                         output a R_X86_64_RELATIVE reloc so that the dynamic
473
                         linker can adjust this GOT entry.  */
474
                      srelgot->_raw_size += sizeof (Elf64_External_Rela);
475
                    }
476
                }
477
              else
478
                local_got_refcounts[r_symndx] += 1;
479
            }
480
          break;
481
 
482
        case R_X86_64_PLT32:
483
          /* This symbol requires a procedure linkage table entry.  We
484
             actually build the entry in adjust_dynamic_symbol,
485
             because this might be a case of linking PIC code which is
486
             never referenced by a dynamic object, in which case we
487
             don't need to generate a procedure linkage table entry
488
             after all.  */
489
 
490
          /* If this is a local symbol, we resolve it directly without
491
             creating a procedure linkage table entry.  */
492
          if (h == NULL)
493
            continue;
494
 
495
          h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
496
          if (h->plt.refcount == -1)
497
            h->plt.refcount = 1;
498
          else
499
            h->plt.refcount += 1;
500
          break;
501
 
502
        case R_X86_64_8:
503
        case R_X86_64_16:
504
        case R_X86_64_32:
505
        case R_X86_64_64:
506
        case R_X86_64_32S:
507
        case R_X86_64_PC32:
508
          if (h != NULL)
509
            h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
510
 
511
          /* If we are creating a shared library, and this is a reloc
512
             against a global symbol, or a non PC relative reloc
513
             against a local symbol, then we need to copy the reloc
514
             into the shared library.  However, if we are linking with
515
             -Bsymbolic, we do not need to copy a reloc against a
516
             global symbol which is defined in an object we are
517
             including in the link (i.e., DEF_REGULAR is set).  At
518
             this point we have not seen all the input files, so it is
519
             possible that DEF_REGULAR is not set now but will be set
520
             later (it is never cleared).  We account for that
521
             possibility below by storing information in the
522
             pcrel_relocs_copied field of the hash table entry.
523
             A similar situation occurs when creating shared libraries
524
             and symbol visibility changes render the symbol local.  */
525
          if (info->shared
526
              && (sec->flags & SEC_ALLOC) != 0
527
              && (((ELF64_R_TYPE (rel->r_info) != R_X86_64_PC8)
528
                  && (ELF64_R_TYPE (rel->r_info) != R_X86_64_PC16)
529
                  && (ELF64_R_TYPE (rel->r_info) != R_X86_64_PC32))
530
                  || (h != NULL
531
                      && (! info->symbolic
532
                          || (h->elf_link_hash_flags
533
                              & ELF_LINK_HASH_DEF_REGULAR) == 0))))
534
            {
535
              /* When creating a shared object, we must copy these
536
                 reloc types into the output file.  We create a reloc
537
                 section in dynobj and make room for this reloc.  */
538
              if (sreloc == NULL)
539
                {
540
                  const char *name;
541
 
542
                  name = (bfd_elf_string_from_elf_section
543
                          (abfd,
544
                           elf_elfheader (abfd)->e_shstrndx,
545
                           elf_section_data (sec)->rel_hdr.sh_name));
546
                  if (name == NULL)
547
                    return false;
548
 
549
                  BFD_ASSERT (strncmp (name, ".rela", 5) == 0
550
                              && strcmp (bfd_get_section_name (abfd, sec),
551
                                         name + 5) == 0);
552
 
553
                  sreloc = bfd_get_section_by_name (dynobj, name);
554
                  if (sreloc == NULL)
555
                    {
556
                      flagword flags;
557
 
558
                      sreloc = bfd_make_section (dynobj, name);
559
                      flags = (SEC_HAS_CONTENTS | SEC_READONLY
560
                               | SEC_IN_MEMORY | SEC_LINKER_CREATED);
561
                      if ((sec->flags & SEC_ALLOC) != 0)
562
                        flags |= SEC_ALLOC | SEC_LOAD;
563
                      if (sreloc == NULL
564
                          || ! bfd_set_section_flags (dynobj, sreloc, flags)
565
                          || ! bfd_set_section_alignment (dynobj, sreloc, 3))
566
                        return false;
567
                    }
568
                }
569
 
570
              sreloc->_raw_size += sizeof (Elf64_External_Rela);
571
 
572
              /* If this is a global symbol, we count the number of PC
573
                 relative relocations we have entered for this symbol,
574
                 so that we can discard them later as necessary.  Note
575
                 that this function is only called if we are using an
576
                 elf64_x86_64 linker hash table, which means that h is
577
                 really a pointer to an elf64_x86_64_link_hash_entry.  */
578
              if (h != NULL
579
                  && ((ELF64_R_TYPE (rel->r_info) == R_X86_64_PC8)
580
                      || (ELF64_R_TYPE (rel->r_info) == R_X86_64_PC16)
581
                      || (ELF64_R_TYPE (rel->r_info) == R_X86_64_PC32)))
582
                {
583
                  struct elf64_x86_64_link_hash_entry *eh;
584
                  struct elf64_x86_64_pcrel_relocs_copied *p;
585
 
586
                  eh = (struct elf64_x86_64_link_hash_entry *) h;
587
 
588
                  for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
589
                    if (p->section == sreloc)
590
                      break;
591
 
592
                  if (p == NULL)
593
                    {
594
                      p = ((struct elf64_x86_64_pcrel_relocs_copied *)
595
                           bfd_alloc (dynobj, sizeof *p));
596
                      if (p == NULL)
597
                        return false;
598
                      p->next = eh->pcrel_relocs_copied;
599
                      eh->pcrel_relocs_copied = p;
600
                      p->section = sreloc;
601
                      p->count = 0;
602
                    }
603
 
604
                  ++p->count;
605
                }
606
            }
607
          break;
608
 
609
          /* This relocation describes the C++ object vtable hierarchy.
610
             Reconstruct it for later use during GC.  */
611
        case R_X86_64_GNU_VTINHERIT:
612
          if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
613
            return false;
614
          break;
615
 
616
          /* This relocation describes which C++ vtable entries are actually
617
             used.  Record for later use during GC.  */
618
        case R_X86_64_GNU_VTENTRY:
619
          if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend))
620
            return false;
621
          break;
622
        }
623
    }
624
 
625
  return true;
626
}
627
 
628
/* Return the section that should be marked against GC for a given
629
   relocation.  */
630
 
631
static asection *
632
elf64_x86_64_gc_mark_hook (abfd, info, rel, h, sym)
633
     bfd *abfd;
634
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
635
     Elf_Internal_Rela *rel ATTRIBUTE_UNUSED;
636
     struct elf_link_hash_entry *h;
637
     Elf_Internal_Sym *sym;
638
{
639
  if (h != NULL)
640
    {
641
      switch (ELF64_R_TYPE (rel->r_info))
642
        {
643
        case R_X86_64_GNU_VTINHERIT:
644
        case R_X86_64_GNU_VTENTRY:
645
          break;
646
 
647
        default:
648
          switch (h->root.type)
649
            {
650
            case bfd_link_hash_defined:
651
            case bfd_link_hash_defweak:
652
              return h->root.u.def.section;
653
 
654
            case bfd_link_hash_common:
655
              return h->root.u.c.p->section;
656
 
657
            default:
658
              break;
659
            }
660
        }
661
    }
662
  else
663
    {
664
      if (!(elf_bad_symtab (abfd)
665
            && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
666
          && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
667
                && sym->st_shndx != SHN_COMMON))
668
        {
669
          return bfd_section_from_elf_index (abfd, sym->st_shndx);
670
        }
671
    }
672
 
673
  return NULL;
674
}
675
 
676
/* Update the got entry reference counts for the section being removed.  */
677
 
678
static boolean
679
elf64_x86_64_gc_sweep_hook (abfd, info, sec, relocs)
680
     bfd *abfd;
681
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
682
     asection *sec;
683
     const Elf_Internal_Rela *relocs;
684
{
685
  Elf_Internal_Shdr *symtab_hdr;
686
  struct elf_link_hash_entry **sym_hashes;
687
  bfd_signed_vma *local_got_refcounts;
688
  const Elf_Internal_Rela *rel, *relend;
689
  unsigned long r_symndx;
690
  struct elf_link_hash_entry *h;
691
  bfd *dynobj;
692
  asection *sgot;
693
  asection *srelgot;
694
 
695
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
696
  sym_hashes = elf_sym_hashes (abfd);
697
  local_got_refcounts = elf_local_got_refcounts (abfd);
698
 
699
  dynobj = elf_hash_table (info)->dynobj;
700
  if (dynobj == NULL)
701
    return true;
702
 
703
  sgot = bfd_get_section_by_name (dynobj, ".got");
704
  srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
705
 
706
  relend = relocs + sec->reloc_count;
707
  for (rel = relocs; rel < relend; rel++)
708
    switch (ELF64_R_TYPE (rel->r_info))
709
      {
710
      case R_X86_64_GOT32:
711
      case R_X86_64_GOTPCREL:
712
        r_symndx = ELF64_R_SYM (rel->r_info);
713
        if (r_symndx >= symtab_hdr->sh_info)
714
          {
715
            h = sym_hashes[r_symndx - symtab_hdr->sh_info];
716
            if (h->got.refcount > 0)
717
              {
718
                h->got.refcount -= 1;
719
                if (h->got.refcount == 0)
720
                  {
721
                    sgot->_raw_size -= GOT_ENTRY_SIZE;
722
                    srelgot->_raw_size -= sizeof (Elf64_External_Rela);
723
                  }
724
              }
725
          }
726
        else if (local_got_refcounts != NULL)
727
          {
728
            if (local_got_refcounts[r_symndx] > 0)
729
              {
730
                local_got_refcounts[r_symndx] -= 1;
731
                if (local_got_refcounts[r_symndx] == 0)
732
                  {
733
                    sgot->_raw_size -= GOT_ENTRY_SIZE;
734
                    if (info->shared)
735
                      srelgot->_raw_size -= sizeof (Elf64_External_Rela);
736
                  }
737
              }
738
          }
739
        break;
740
 
741
      case R_X86_64_PLT32:
742
        r_symndx = ELF64_R_SYM (rel->r_info);
743
        if (r_symndx >= symtab_hdr->sh_info)
744
          {
745
            h = sym_hashes[r_symndx - symtab_hdr->sh_info];
746
            if (h->plt.refcount > 0)
747
              h->plt.refcount -= 1;
748
          }
749
        break;
750
 
751
      default:
752
        break;
753
      }
754
 
755
  return true;
756
}
757
 
758
/* Adjust a symbol defined by a dynamic object and referenced by a
759
   regular object.  The current definition is in some section of the
760
   dynamic object, but we're not including those sections.  We have to
761
   change the definition to something the rest of the link can
762
   understand.  */
763
 
764
static boolean
765
elf64_x86_64_adjust_dynamic_symbol (info, h)
766
     struct bfd_link_info *info;
767
     struct elf_link_hash_entry *h;
768
{
769
  bfd *dynobj;
770
  asection *s;
771
  unsigned int power_of_two;
772
 
773
  dynobj = elf_hash_table (info)->dynobj;
774
 
775
  /* Make sure we know what is going on here.  */
776
  BFD_ASSERT (dynobj != NULL
777
              && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
778
                  || h->weakdef != NULL
779
                  || ((h->elf_link_hash_flags
780
                       & ELF_LINK_HASH_DEF_DYNAMIC) != 0
781
                      && (h->elf_link_hash_flags
782
                          & ELF_LINK_HASH_REF_REGULAR) != 0
783
                      && (h->elf_link_hash_flags
784
                          & ELF_LINK_HASH_DEF_REGULAR) == 0)));
785
 
786
  /* If this is a function, put it in the procedure linkage table.  We
787
     will fill in the contents of the procedure linkage table later,
788
     when we know the address of the .got section.  */
789
  if (h->type == STT_FUNC
790
      || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
791
    {
792
      if ((! info->shared
793
           && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
794
           && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
795
          || (info->shared && h->plt.refcount <= 0))
796
        {
797
          /* This case can occur if we saw a PLT32 reloc in an input
798
             file, but the symbol was never referred to by a dynamic
799
             object, or if all references were garbage collected.  In
800
             such a case, we don't actually need to build a procedure
801
             linkage table, and we can just do a PC32 reloc instead.  */
802
          h->plt.offset = (bfd_vma) -1;
803
          h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
804
          return true;
805
        }
806
 
807
      /* Make sure this symbol is output as a dynamic symbol.  */
808
      if (h->dynindx == -1)
809
        {
810
          if (! bfd_elf64_link_record_dynamic_symbol (info, h))
811
            return false;
812
        }
813
 
814
      s = bfd_get_section_by_name (dynobj, ".plt");
815
      BFD_ASSERT (s != NULL);
816
 
817
      /* If this is the first .plt entry, make room for the special
818
         first entry.  */
819
      if (s->_raw_size == 0)
820
        s->_raw_size = PLT_ENTRY_SIZE;
821
 
822
      /* If this symbol is not defined in a regular file, and we are
823
         not generating a shared library, then set the symbol to this
824
         location in the .plt.  This is required to make function
825
         pointers compare as equal between the normal executable and
826
         the shared library.  */
827
      if (! info->shared
828
          && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
829
        {
830
          h->root.u.def.section = s;
831
          h->root.u.def.value = s->_raw_size;
832
        }
833
 
834
      h->plt.offset = s->_raw_size;
835
 
836
      /* Make room for this entry.  */
837
      s->_raw_size += PLT_ENTRY_SIZE;
838
 
839
      /* We also need to make an entry in the .got.plt section, which
840
         will be placed in the .got section by the linker script.  */
841
      s = bfd_get_section_by_name (dynobj, ".got.plt");
842
      BFD_ASSERT (s != NULL);
843
      s->_raw_size += GOT_ENTRY_SIZE;
844
 
845
      /* We also need to make an entry in the .rela.plt section.  */
846
      s = bfd_get_section_by_name (dynobj, ".rela.plt");
847
      BFD_ASSERT (s != NULL);
848
      s->_raw_size += sizeof (Elf64_External_Rela);
849
 
850
      return true;
851
    }
852
 
853
  /* If this is a weak symbol, and there is a real definition, the
854
     processor independent code will have arranged for us to see the
855
     real definition first, and we can just use the same value.  */
856
  if (h->weakdef != NULL)
857
    {
858
      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
859
                  || h->weakdef->root.type == bfd_link_hash_defweak);
860
      h->root.u.def.section = h->weakdef->root.u.def.section;
861
      h->root.u.def.value = h->weakdef->root.u.def.value;
862
      return true;
863
    }
864
 
865
  /* This is a reference to a symbol defined by a dynamic object which
866
     is not a function.  */
867
 
868
  /* If we are creating a shared library, we must presume that the
869
     only references to the symbol are via the global offset table.
870
     For such cases we need not do anything here; the relocations will
871
     be handled correctly by relocate_section.  */
872
  if (info->shared)
873
    return true;
874
 
875
  /* If there are no references to this symbol that do not use the
876
     GOT, we don't need to generate a copy reloc.  */
877
  if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0)
878
    return true;
879
 
880
  /* We must allocate the symbol in our .dynbss section, which will
881
     become part of the .bss section of the executable.  There will be
882
     an entry for this symbol in the .dynsym section.  The dynamic
883
     object will contain position independent code, so all references
884
     from the dynamic object to this symbol will go through the global
885
     offset table.  The dynamic linker will use the .dynsym entry to
886
     determine the address it must put in the global offset table, so
887
     both the dynamic object and the regular object will refer to the
888
     same memory location for the variable.  */
889
 
890
  s = bfd_get_section_by_name (dynobj, ".dynbss");
891
  BFD_ASSERT (s != NULL);
892
 
893
  /* We must generate a R_X86_64_COPY reloc to tell the dynamic linker
894
     to copy the initial value out of the dynamic object and into the
895
     runtime process image.  We need to remember the offset into the
896
     .rela.bss section we are going to use.  */
897
  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
898
    {
899
      asection *srel;
900
 
901
      srel = bfd_get_section_by_name (dynobj, ".rela.bss");
902
      BFD_ASSERT (srel != NULL);
903
      srel->_raw_size += sizeof (Elf64_External_Rela);
904
      h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
905
    }
906
 
907
  /* We need to figure out the alignment required for this symbol.  I
908
     have no idea how ELF linkers handle this.  16-bytes is the size
909
     of the largest type that requires hard alignment -- long double.  */
910
  /* FIXME: This is VERY ugly. Should be fixed for all architectures using
911
     this construct.  */
912
  power_of_two = bfd_log2 (h->size);
913
  if (power_of_two > 4)
914
    power_of_two = 4;
915
 
916
  /* Apply the required alignment.  */
917
  s->_raw_size = BFD_ALIGN (s->_raw_size, (bfd_size_type) (1 << power_of_two));
918
  if (power_of_two > bfd_get_section_alignment (dynobj, s))
919
    {
920
      if (! bfd_set_section_alignment (dynobj, s, power_of_two))
921
        return false;
922
    }
923
 
924
  /* Define the symbol as being at this point in the section.  */
925
  h->root.u.def.section = s;
926
  h->root.u.def.value = s->_raw_size;
927
 
928
  /* Increment the section size to make room for the symbol.  */
929
  s->_raw_size += h->size;
930
 
931
  return true;
932
}
933
 
934
/* Set the sizes of the dynamic sections.  */
935
 
936
static boolean
937
elf64_x86_64_size_dynamic_sections (output_bfd, info)
938
     bfd *output_bfd;
939
     struct bfd_link_info *info;
940
{
941
  bfd *dynobj;
942
  asection *s;
943
  boolean plt;
944
  boolean relocs;
945
  boolean reltext;
946
 
947
  dynobj = elf_hash_table (info)->dynobj;
948
  BFD_ASSERT (dynobj != NULL);
949
 
950
  if (elf_hash_table (info)->dynamic_sections_created)
951
    {
952
      /* Set the contents of the .interp section to the interpreter.  */
953
      if (! info->shared)
954
        {
955
          s = bfd_get_section_by_name (dynobj, ".interp");
956
          BFD_ASSERT (s != NULL);
957
          s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
958
          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
959
        }
960
    }
961
  else
962
    {
963
      /* We may have created entries in the .rela.got section.
964
         However, if we are not creating the dynamic sections, we will
965
         not actually use these entries.  Reset the size of .rela.got,
966
         which will cause it to get stripped from the output file
967
         below.  */
968
      s = bfd_get_section_by_name (dynobj, ".rela.got");
969
      if (s != NULL)
970
        s->_raw_size = 0;
971
    }
972
 
973
  /* If this is a -Bsymbolic shared link, then we need to discard all
974
     PC relative relocs against symbols defined in a regular object.
975
     We allocated space for them in the check_relocs routine, but we
976
     will not fill them in in the relocate_section routine.  */
977
  if (info->shared)
978
    elf64_x86_64_link_hash_traverse (elf64_x86_64_hash_table (info),
979
                                     elf64_x86_64_discard_copies,
980
                                     (PTR) info);
981
 
982
  /* The check_relocs and adjust_dynamic_symbol entry points have
983
     determined the sizes of the various dynamic sections.  Allocate
984
     memory for them.  */
985
  plt = relocs = reltext = false;
986
  for (s = dynobj->sections; s != NULL; s = s->next)
987
    {
988
      const char *name;
989
      boolean strip;
990
 
991
      if ((s->flags & SEC_LINKER_CREATED) == 0)
992
        continue;
993
 
994
      /* It's OK to base decisions on the section name, because none
995
         of the dynobj section names depend upon the input files.  */
996
      name = bfd_get_section_name (dynobj, s);
997
 
998
      strip = false;
999
      if (strcmp (name, ".plt") == 0)
1000
        {
1001
          if (s->_raw_size == 0)
1002
            {
1003
              /* Strip this section if we don't need it; see the
1004
                 comment below.  */
1005
              strip = true;
1006
            }
1007
          else
1008
            {
1009
              /* Remember whether there is a PLT.  */
1010
              plt = true;
1011
            }
1012
        }
1013
      else if (strncmp (name, ".rela", 5) == 0)
1014
        {
1015
          if (s->_raw_size == 0)
1016
            {
1017
              /* If we don't need this section, strip it from the
1018
                 output file.  This is mostly to handle .rela.bss and
1019
                 .rela.plt.  We must create both sections in
1020
                 create_dynamic_sections, because they must be created
1021
                 before the linker maps input sections to output
1022
                 sections.  The linker does that before
1023
                 adjust_dynamic_symbol is called, and it is that
1024
                 function which decides whether anything needs to go
1025
                 into these sections.  */
1026
              strip = true;
1027
            }
1028
          else
1029
            {
1030
              asection *target;
1031
 
1032
              /* Remember whether there are any reloc sections other
1033
                 than .rela.plt.  */
1034
              if (strcmp (name, ".rela.plt") != 0)
1035
                {
1036
                  const char *outname;
1037
 
1038
                  relocs = true;
1039
 
1040
                  /* If this relocation section applies to a read only
1041
                     section, then we probably need a DT_TEXTREL
1042
                     entry.  The entries in the .rela.plt section
1043
                     really apply to the .got section, which we
1044
                     created ourselves and so know is not readonly.  */
1045
                  outname = bfd_get_section_name (output_bfd,
1046
                                                  s->output_section);
1047
                  target = bfd_get_section_by_name (output_bfd, outname + 5);
1048
                  if (target != NULL
1049
                      && (target->flags & SEC_READONLY) != 0
1050
                      && (target->flags & SEC_ALLOC) != 0)
1051
                    reltext = true;
1052
                }
1053
 
1054
              /* We use the reloc_count field as a counter if we need
1055
                 to copy relocs into the output file.  */
1056
              s->reloc_count = 0;
1057
            }
1058
        }
1059
      else if (strncmp (name, ".got", 4) != 0)
1060
        {
1061
          /* It's not one of our sections, so don't allocate space.  */
1062
          continue;
1063
        }
1064
 
1065
      if (strip)
1066
        {
1067
          _bfd_strip_section_from_output (info, s);
1068
          continue;
1069
        }
1070
 
1071
      /* Allocate memory for the section contents.  We use bfd_zalloc
1072
         here in case unused entries are not reclaimed before the
1073
         section's contents are written out.  This should not happen,
1074
         but this way if it does, we get a R_X86_64_NONE reloc instead
1075
         of garbage.  */
1076
      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
1077
      if (s->contents == NULL && s->_raw_size != 0)
1078
        return false;
1079
    }
1080
 
1081
  if (elf_hash_table (info)->dynamic_sections_created)
1082
    {
1083
      /* Add some entries to the .dynamic section.  We fill in the
1084
         values later, in elf64_x86_64_finish_dynamic_sections, but we
1085
         must add the entries now so that we get the correct size for
1086
         the .dynamic section.  The DT_DEBUG entry is filled in by the
1087
         dynamic linker and used by the debugger.  */
1088
      if (! info->shared)
1089
        {
1090
          if (! bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0))
1091
            return false;
1092
        }
1093
 
1094
      if (plt)
1095
        {
1096
          if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0)
1097
              || ! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0)
1098
              || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
1099
              || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0))
1100
            return false;
1101
        }
1102
 
1103
      if (relocs)
1104
        {
1105
          if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0)
1106
              || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0)
1107
              || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT,
1108
                                                sizeof (Elf64_External_Rela)))
1109
            return false;
1110
        }
1111
 
1112
      if (reltext)
1113
        {
1114
          if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))
1115
            return false;
1116
          info->flags |= DF_TEXTREL;
1117
        }
1118
    }
1119
 
1120
  return true;
1121
}
1122
 
1123
/* This function is called via elf64_x86_64_link_hash_traverse if we are
1124
   creating a shared object.  In the -Bsymbolic case, it discards the
1125
   space allocated to copy PC relative relocs against symbols which
1126
   are defined in regular objects.  For the normal non-symbolic case,
1127
   we also discard space for relocs that have become local due to
1128
   symbol visibility changes.  We allocated space for them in the
1129
   check_relocs routine, but we won't fill them in in the
1130
   relocate_section routine.  */
1131
 
1132
static boolean
1133
elf64_x86_64_discard_copies (h, inf)
1134
     struct elf64_x86_64_link_hash_entry *h;
1135
     PTR inf;
1136
{
1137
  struct elf64_x86_64_pcrel_relocs_copied *s;
1138
  struct bfd_link_info *info = (struct bfd_link_info *) inf;
1139
 
1140
  /* If a symbol has been forced local or we have found a regular
1141
     definition for the symbolic link case, then we won't be needing
1142
     any relocs.  */
1143
  if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
1144
      && ((h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0
1145
          || info->symbolic))
1146
    {
1147
      for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
1148
        s->section->_raw_size -= s->count * sizeof (Elf64_External_Rela);
1149
    }
1150
 
1151
  return true;
1152
}
1153
 
1154
/* Relocate an x86_64 ELF section.  */
1155
 
1156
static boolean
1157
elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
1158
                               contents, relocs, local_syms, local_sections)
1159
     bfd *output_bfd;
1160
     struct bfd_link_info *info;
1161
     bfd *input_bfd;
1162
     asection *input_section;
1163
     bfd_byte *contents;
1164
     Elf_Internal_Rela *relocs;
1165
     Elf_Internal_Sym *local_syms;
1166
     asection **local_sections;
1167
{
1168
  bfd *dynobj;
1169
  Elf_Internal_Shdr *symtab_hdr;
1170
  struct elf_link_hash_entry **sym_hashes;
1171
  bfd_vma *local_got_offsets;
1172
  asection *sgot;
1173
  asection *splt;
1174
  asection *sreloc;
1175
  Elf_Internal_Rela *rela;
1176
  Elf_Internal_Rela *relend;
1177
 
1178
  dynobj = elf_hash_table (info)->dynobj;
1179
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1180
  sym_hashes = elf_sym_hashes (input_bfd);
1181
  local_got_offsets = elf_local_got_offsets (input_bfd);
1182
 
1183
  sreloc = splt = sgot = NULL;
1184
  if (dynobj != NULL)
1185
    {
1186
      splt = bfd_get_section_by_name (dynobj, ".plt");
1187
      sgot = bfd_get_section_by_name (dynobj, ".got");
1188
    }
1189
 
1190
  rela = relocs;
1191
  relend = relocs + input_section->reloc_count;
1192
  for (; rela < relend; rela++)
1193
    {
1194
      int r_type;
1195
      reloc_howto_type *howto;
1196
      unsigned long r_symndx;
1197
      struct elf_link_hash_entry *h;
1198
      Elf_Internal_Sym *sym;
1199
      asection *sec;
1200
      bfd_vma relocation;
1201
      bfd_reloc_status_type r;
1202
      unsigned int indx;
1203
 
1204
      r_type = ELF64_R_TYPE (rela->r_info);
1205
      if (r_type == (int) R_X86_64_GNU_VTINHERIT
1206
          || r_type == (int) R_X86_64_GNU_VTENTRY)
1207
        continue;
1208
 
1209
      if ((indx = (unsigned) r_type) >= R_X86_64_max)
1210
        {
1211
          bfd_set_error (bfd_error_bad_value);
1212
          return false;
1213
        }
1214
      howto = x86_64_elf_howto_table + indx;
1215
 
1216
      r_symndx = ELF64_R_SYM (rela->r_info);
1217
 
1218
      if (info->relocateable)
1219
        {
1220
          /* This is a relocateable link.  We don't have to change
1221
             anything, unless the reloc is against a section symbol,
1222
             in which case we have to adjust according to where the
1223
             section symbol winds up in the output section.  */
1224
          if (r_symndx < symtab_hdr->sh_info)
1225
            {
1226
              sym = local_syms + r_symndx;
1227
              if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1228
                {
1229
                  sec = local_sections[r_symndx];
1230
                  rela->r_addend += sec->output_offset + sym->st_value;
1231
                }
1232
            }
1233
 
1234
          continue;
1235
        }
1236
 
1237
      /* This is a final link.  */
1238
      h = NULL;
1239
      sym = NULL;
1240
      sec = NULL;
1241
      if (r_symndx < symtab_hdr->sh_info)
1242
        {
1243
          sym = local_syms + r_symndx;
1244
          sec = local_sections[r_symndx];
1245
          relocation = (sec->output_section->vma
1246
                        + sec->output_offset
1247
                        + sym->st_value);
1248
        }
1249
      else
1250
        {
1251
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1252
          while (h->root.type == bfd_link_hash_indirect
1253
                 || h->root.type == bfd_link_hash_warning)
1254
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
1255
          if (h->root.type == bfd_link_hash_defined
1256
              || h->root.type == bfd_link_hash_defweak)
1257
            {
1258
              sec = h->root.u.def.section;
1259
              if ((r_type == R_X86_64_PLT32
1260
                   && splt != NULL
1261
                   && h->plt.offset != (bfd_vma) -1)
1262
                  || ((r_type == R_X86_64_GOT32 || r_type == R_X86_64_GOTPCREL)
1263
                      && elf_hash_table (info)->dynamic_sections_created
1264
                      && (!info->shared
1265
                          || (! info->symbolic && h->dynindx != -1)
1266
                          || (h->elf_link_hash_flags
1267
                              & ELF_LINK_HASH_DEF_REGULAR) == 0))
1268
                  || (info->shared
1269
                      && ((! info->symbolic && h->dynindx != -1)
1270
                          || (h->elf_link_hash_flags
1271
                              & ELF_LINK_HASH_DEF_REGULAR) == 0)
1272
                      && (r_type == R_X86_64_8
1273
                          || r_type == R_X86_64_16
1274
                          || r_type == R_X86_64_32
1275
                          || r_type == R_X86_64_64
1276
                          || r_type == R_X86_64_PC8
1277
                          || r_type == R_X86_64_PC16
1278
                          || r_type == R_X86_64_PC32)
1279
                      && ((input_section->flags & SEC_ALLOC) != 0
1280
                          /* DWARF will emit R_X86_64_32 relocations in its
1281
                             sections against symbols defined externally
1282
                             in shared libraries.  We can't do anything
1283
                             with them here.  */
1284
                          || ((input_section->flags & SEC_DEBUGGING) != 0
1285
                              && (h->elf_link_hash_flags
1286
                                  & ELF_LINK_HASH_DEF_DYNAMIC) != 0))))
1287
                {
1288
                  /* In these cases, we don't need the relocation
1289
                     value.  We check specially because in some
1290
                     obscure cases sec->output_section will be NULL.  */
1291
                  relocation = 0;
1292
                }
1293
              else if (sec->output_section == NULL)
1294
                {
1295
                  (*_bfd_error_handler)
1296
                    (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
1297
                     bfd_get_filename (input_bfd), h->root.root.string,
1298
                     bfd_get_section_name (input_bfd, input_section));
1299
                  relocation = 0;
1300
                }
1301
              else
1302
                relocation = (h->root.u.def.value
1303
                              + sec->output_section->vma
1304
                              + sec->output_offset);
1305
            }
1306
          else if (h->root.type == bfd_link_hash_undefweak)
1307
            relocation = 0;
1308
          else if (info->shared && !info->symbolic && !info->no_undefined
1309
                   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
1310
            relocation = 0;
1311
          else
1312
            {
1313
              if (! ((*info->callbacks->undefined_symbol)
1314
                     (info, h->root.root.string, input_bfd,
1315
                      input_section, rela->r_offset,
1316
                      (!info->shared || info->no_undefined
1317
                       || ELF_ST_VISIBILITY (h->other)))))
1318
                return false;
1319
              relocation = 0;
1320
            }
1321
        }
1322
 
1323
      /* When generating a shared object, the relocations handled here are
1324
         copied into the output file to be resolved at run time.  */
1325
      switch (r_type)
1326
        {
1327
        case R_X86_64_GOT32:
1328
          /* Relocation is to the entry for this symbol in the global
1329
             offset table.  */
1330
        case R_X86_64_GOTPCREL:
1331
          /* Use global offset table as symbol value.  */
1332
          BFD_ASSERT (sgot != NULL);
1333
 
1334
          if (h != NULL)
1335
            {
1336
              bfd_vma off = h->got.offset;
1337
              BFD_ASSERT (off != (bfd_vma) -1);
1338
 
1339
              if (! elf_hash_table (info)->dynamic_sections_created
1340
                  || (info->shared
1341
                      && (info->symbolic || h->dynindx == -1)
1342
                      && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
1343
                {
1344
                  /* This is actually a static link, or it is a -Bsymbolic
1345
                     link and the symbol is defined locally, or the symbol
1346
                     was forced to be local because of a version file.  We
1347
                     must initialize this entry in the global offset table.
1348
                     Since the offset must always be a multiple of 8, we
1349
                     use the least significant bit to record whether we
1350
                     have initialized it already.
1351
 
1352
                     When doing a dynamic link, we create a .rela.got
1353
                     relocation entry to initialize the value.  This is
1354
                     done in the finish_dynamic_symbol routine.  */
1355
                  if ((off & 1) != 0)
1356
                    off &= ~1;
1357
                  else
1358
                    {
1359
                      bfd_put_64 (output_bfd, relocation,
1360
                                  sgot->contents + off);
1361
                      h->got.offset |= 1;
1362
                    }
1363
                }
1364
              if (r_type == R_X86_64_GOTPCREL)
1365
                relocation = sgot->output_section->vma + sgot->output_offset + off;
1366
              else
1367
                relocation = sgot->output_offset + off;
1368
            }
1369
          else
1370
            {
1371
              bfd_vma off;
1372
 
1373
              BFD_ASSERT (local_got_offsets != NULL
1374
                          && local_got_offsets[r_symndx] != (bfd_vma) -1);
1375
 
1376
              off = local_got_offsets[r_symndx];
1377
 
1378
              /* The offset must always be a multiple of 8.  We use
1379
                 the least significant bit to record whether we have
1380
                 already generated the necessary reloc.  */
1381
              if ((off & 1) != 0)
1382
                off &= ~1;
1383
              else
1384
                {
1385
                  bfd_put_64 (output_bfd, relocation, sgot->contents + off);
1386
 
1387
                  if (info->shared)
1388
                    {
1389
                      asection *srelgot;
1390
                      Elf_Internal_Rela outrel;
1391
 
1392
                      /* We need to generate a R_X86_64_RELATIVE reloc
1393
                         for the dynamic linker.  */
1394
                      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
1395
                      BFD_ASSERT (srelgot != NULL);
1396
 
1397
                      outrel.r_offset = (sgot->output_section->vma
1398
                                         + sgot->output_offset
1399
                                         + off);
1400
                      outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
1401
                      outrel.r_addend = relocation;
1402
                      bfd_elf64_swap_reloca_out (output_bfd, &outrel,
1403
                                                 (((Elf64_External_Rela *)
1404
                                                   srelgot->contents)
1405
                                                  + srelgot->reloc_count));
1406
                      ++srelgot->reloc_count;
1407
                    }
1408
 
1409
                  local_got_offsets[r_symndx] |= 1;
1410
                }
1411
 
1412
              if (r_type == R_X86_64_GOTPCREL)
1413
                relocation = sgot->output_section->vma + sgot->output_offset + off;
1414
              else
1415
                relocation = sgot->output_offset + off;
1416
            }
1417
 
1418
          break;
1419
 
1420
        case R_X86_64_PLT32:
1421
          /* Relocation is to the entry for this symbol in the
1422
             procedure linkage table.  */
1423
 
1424
          /* Resolve a PLT32 reloc against a local symbol directly,
1425
             without using the procedure linkage table.  */
1426
          if (h == NULL)
1427
            break;
1428
 
1429
          if (h->plt.offset == (bfd_vma) -1 || splt == NULL)
1430
            {
1431
              /* We didn't make a PLT entry for this symbol.  This
1432
                 happens when statically linking PIC code, or when
1433
                 using -Bsymbolic.  */
1434
              break;
1435
            }
1436
 
1437
          relocation = (splt->output_section->vma
1438
                        + splt->output_offset
1439
                        + h->plt.offset);
1440
          break;
1441
 
1442
        case R_X86_64_PC8:
1443
        case R_X86_64_PC16:
1444
        case R_X86_64_PC32:
1445
          if (h == NULL || h->dynindx == -1
1446
              || (info->symbolic
1447
                  && h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
1448
            break;
1449
          /* Fall through.  */
1450
        case R_X86_64_8:
1451
        case R_X86_64_16:
1452
        case R_X86_64_32:
1453
        case R_X86_64_64:
1454
          /* FIXME: The ABI says the linker should make sure the value is
1455
             the same when it's zeroextended to 64 bit.  */
1456
          if (info->shared && (input_section->flags & SEC_ALLOC) != 0)
1457
            {
1458
              Elf_Internal_Rela outrel;
1459
              boolean skip, relocate;
1460
 
1461
              /* When generating a shared object, these relocations
1462
                 are copied into the output file to be resolved at run
1463
                 time.  */
1464
 
1465
              if (sreloc == NULL)
1466
                {
1467
                  const char *name;
1468
 
1469
                  name = (bfd_elf_string_from_elf_section
1470
                          (input_bfd,
1471
                           elf_elfheader (input_bfd)->e_shstrndx,
1472
                           elf_section_data (input_section)->rel_hdr.sh_name));
1473
                  if (name == NULL)
1474
                    return false;
1475
 
1476
                  BFD_ASSERT (strncmp (name, ".rela", 5) == 0
1477
                              && strcmp (bfd_get_section_name (input_bfd,
1478
                                                               input_section),
1479
                                         name + 5) == 0);
1480
 
1481
                  sreloc = bfd_get_section_by_name (dynobj, name);
1482
                  BFD_ASSERT (sreloc != NULL);
1483
                }
1484
 
1485
              skip = false;
1486
 
1487
              if (elf_section_data (input_section)->stab_info == NULL)
1488
                outrel.r_offset = rela->r_offset;
1489
              else
1490
                {
1491
                  bfd_vma off;
1492
 
1493
                  off = (_bfd_stab_section_offset
1494
                         (output_bfd, &elf_hash_table (info)->stab_info,
1495
                          input_section,
1496
                          &elf_section_data (input_section)->stab_info,
1497
                          rela->r_offset));
1498
                  if (off == (bfd_vma) -1)
1499
                    skip = true;
1500
                  outrel.r_offset = off;
1501
                }
1502
 
1503
              outrel.r_offset += (input_section->output_section->vma
1504
                                  + input_section->output_offset);
1505
 
1506
              if (skip)
1507
                {
1508
                  memset (&outrel, 0, sizeof outrel);
1509
                  relocate = false;
1510
                }
1511
              /* h->dynindx may be -1 if this symbol was marked to
1512
                 become local.  */
1513
              else if (h != NULL
1514
                       && ((! info->symbolic && h->dynindx != -1)
1515
                           || (h->elf_link_hash_flags
1516
                               & ELF_LINK_HASH_DEF_REGULAR) == 0))
1517
                {
1518
                  BFD_ASSERT (h->dynindx != -1);
1519
                  relocate = false;
1520
                  outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
1521
                  outrel.r_addend = relocation + rela->r_addend;
1522
                }
1523
              else
1524
                {
1525
                  if (r_type == R_X86_64_64)
1526
                    {
1527
                      relocate = true;
1528
                      outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
1529
                      outrel.r_addend = relocation + rela->r_addend;
1530
                    }
1531
                  else
1532
                    {
1533
                      long indx;
1534
 
1535
                      if (h == NULL)
1536
                        sec = local_sections[r_symndx];
1537
                      else
1538
                        {
1539
                          BFD_ASSERT (h->root.type == bfd_link_hash_defined
1540
                                      || (h->root.type
1541
                                          == bfd_link_hash_defweak));
1542
                          sec = h->root.u.def.section;
1543
                        }
1544
                      if (sec != NULL && bfd_is_abs_section (sec))
1545
                        indx = 0;
1546
                      else if (sec == NULL || sec->owner == NULL)
1547
                        {
1548
                          bfd_set_error (bfd_error_bad_value);
1549
                          return false;
1550
                        }
1551
                      else
1552
                        {
1553
                          asection *osec;
1554
 
1555
                          osec = sec->output_section;
1556
                          indx = elf_section_data (osec)->dynindx;
1557
                          BFD_ASSERT (indx > 0);
1558
                        }
1559
 
1560
                      relocate = false;
1561
                      outrel.r_info = ELF64_R_INFO (indx, r_type);
1562
                      outrel.r_addend = relocation + rela->r_addend;
1563
                    }
1564
 
1565
                }
1566
 
1567
              bfd_elf64_swap_reloca_out (output_bfd, &outrel,
1568
                                        (((Elf64_External_Rela *)
1569
                                          sreloc->contents)
1570
                                         + sreloc->reloc_count));
1571
              ++sreloc->reloc_count;
1572
 
1573
              /* If this reloc is against an external symbol, we do
1574
                 not want to fiddle with the addend.  Otherwise, we
1575
                 need to include the symbol value so that it becomes
1576
                 an addend for the dynamic reloc.  */
1577
              if (! relocate)
1578
                continue;
1579
            }
1580
 
1581
          break;
1582
 
1583
        default:
1584
          break;
1585
        }
1586
 
1587
      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1588
                                    contents, rela->r_offset,
1589
                                    relocation, rela->r_addend);
1590
 
1591
      if (r != bfd_reloc_ok)
1592
        {
1593
          switch (r)
1594
            {
1595
            default:
1596
            case bfd_reloc_outofrange:
1597
              abort ();
1598
            case bfd_reloc_overflow:
1599
              {
1600
                const char *name;
1601
 
1602
                if (h != NULL)
1603
                  name = h->root.root.string;
1604
                else
1605
                  {
1606
                    name = bfd_elf_string_from_elf_section (input_bfd,
1607
                                                            symtab_hdr->sh_link,
1608
                                                            sym->st_name);
1609
                    if (name == NULL)
1610
                      return false;
1611
                    if (*name == '\0')
1612
                      name = bfd_section_name (input_bfd, sec);
1613
                  }
1614
                if (! ((*info->callbacks->reloc_overflow)
1615
                       (info, name, howto->name, (bfd_vma) 0,
1616
                        input_bfd, input_section, rela->r_offset)))
1617
                  return false;
1618
              }
1619
              break;
1620
            }
1621
        }
1622
    }
1623
 
1624
  return true;
1625
}
1626
 
1627
/* Finish up dynamic symbol handling.  We set the contents of various
1628
   dynamic sections here.  */
1629
 
1630
static boolean
1631
elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym)
1632
     bfd *output_bfd;
1633
     struct bfd_link_info *info;
1634
     struct elf_link_hash_entry *h;
1635
     Elf_Internal_Sym *sym;
1636
{
1637
  bfd *dynobj;
1638
 
1639
  dynobj = elf_hash_table (info)->dynobj;
1640
 
1641
  if (h->plt.offset != (bfd_vma) -1)
1642
    {
1643
      asection *splt;
1644
      asection *sgot;
1645
      asection *srela;
1646
      bfd_vma plt_index;
1647
      bfd_vma got_offset;
1648
      Elf_Internal_Rela rela;
1649
 
1650
      /* This symbol has an entry in the procedure linkage table.  Set
1651
         it up.  */
1652
 
1653
      BFD_ASSERT (h->dynindx != -1);
1654
 
1655
      splt = bfd_get_section_by_name (dynobj, ".plt");
1656
      sgot = bfd_get_section_by_name (dynobj, ".got.plt");
1657
      srela = bfd_get_section_by_name (dynobj, ".rela.plt");
1658
      BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
1659
 
1660
      /* Get the index in the procedure linkage table which
1661
         corresponds to this symbol.  This is the index of this symbol
1662
         in all the symbols for which we are making plt entries.  The
1663
         first entry in the procedure linkage table is reserved.  */
1664
      plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
1665
 
1666
      /* Get the offset into the .got table of the entry that
1667
         corresponds to this function.  Each .got entry is GOT_ENTRY_SIZE
1668
         bytes. The first three are reserved for the dynamic linker.  */
1669
      got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
1670
 
1671
      /* Fill in the entry in the procedure linkage table.  */
1672
      memcpy (splt->contents + h->plt.offset, elf64_x86_64_plt_entry,
1673
              PLT_ENTRY_SIZE);
1674
 
1675
      /* Insert the relocation positions of the plt section.  The magic
1676
         numbers at the end of the statements are the positions of the
1677
         relocations in the plt section.  */
1678
      /* Put offset for jmp *name@GOTPCREL(%rip), since the
1679
         instruction uses 6 bytes, subtract this value.  */
1680
      bfd_put_32 (output_bfd,
1681
                      (sgot->output_section->vma
1682
                       + sgot->output_offset
1683
                       + got_offset
1684
                       - splt->output_section->vma
1685
                       - splt->output_offset
1686
                       - h->plt.offset
1687
                       - 6),
1688
                  splt->contents + h->plt.offset + 2);
1689
      /* Put relocation index.  */
1690
      bfd_put_32 (output_bfd, plt_index,
1691
                  splt->contents + h->plt.offset + 7);
1692
      /* Put offset for jmp .PLT0.  */
1693
      bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),
1694
                  splt->contents + h->plt.offset + 12);
1695
 
1696
      /* Fill in the entry in the global offset table, initially this
1697
         points to the pushq instruction in the PLT which is at offset 6.  */
1698
      bfd_put_64 (output_bfd, (splt->output_section->vma + splt->output_offset
1699
                               + h->plt.offset + 6),
1700
                  sgot->contents + got_offset);
1701
 
1702
      /* Fill in the entry in the .rela.plt section.  */
1703
      rela.r_offset = (sgot->output_section->vma
1704
                       + sgot->output_offset
1705
                       + got_offset);
1706
      rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_JUMP_SLOT);
1707
      rela.r_addend = 0;
1708
      bfd_elf64_swap_reloca_out (output_bfd, &rela,
1709
                                 ((Elf64_External_Rela *) srela->contents
1710
                                  + plt_index));
1711
 
1712
      if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
1713
        {
1714
          /* Mark the symbol as undefined, rather than as defined in
1715
             the .plt section.  Leave the value alone.  */
1716
          sym->st_shndx = SHN_UNDEF;
1717
          /* If the symbol is weak, we do need to clear the value.
1718
             Otherwise, the PLT entry would provide a definition for
1719
             the symbol even if the symbol wasn't defined anywhere,
1720
             and so the symbol would never be NULL.  */
1721
          if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK)
1722
              == 0)
1723
            sym->st_value = 0;
1724
        }
1725
    }
1726
 
1727
  if (h->got.offset != (bfd_vma) -1)
1728
    {
1729
      asection *sgot;
1730
      asection *srela;
1731
      Elf_Internal_Rela rela;
1732
 
1733
      /* This symbol has an entry in the global offset table.  Set it
1734
         up.  */
1735
 
1736
      sgot = bfd_get_section_by_name (dynobj, ".got");
1737
      srela = bfd_get_section_by_name (dynobj, ".rela.got");
1738
      BFD_ASSERT (sgot != NULL && srela != NULL);
1739
 
1740
      rela.r_offset = (sgot->output_section->vma
1741
                       + sgot->output_offset
1742
                       + (h->got.offset &~ 1));
1743
 
1744
      /* If this is a static link, or it is a -Bsymbolic link and the
1745
         symbol is defined locally or was forced to be local because
1746
         of a version file, we just want to emit a RELATIVE reloc.
1747
         The entry in the global offset table will already have been
1748
         initialized in the relocate_section function.  */
1749
      if (! elf_hash_table (info)->dynamic_sections_created
1750
          || (info->shared
1751
              && (info->symbolic || h->dynindx == -1)
1752
              && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
1753
        {
1754
          BFD_ASSERT((h->got.offset & 1) != 0);
1755
          rela.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
1756
          rela.r_addend = (h->root.u.def.value
1757
                           + h->root.u.def.section->output_section->vma
1758
                           + h->root.u.def.section->output_offset);
1759
        }
1760
      else
1761
        {
1762
          BFD_ASSERT((h->got.offset & 1) == 0);
1763
          bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
1764
          rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_GLOB_DAT);
1765
          rela.r_addend = 0;
1766
        }
1767
 
1768
      bfd_elf64_swap_reloca_out (output_bfd, &rela,
1769
                                 ((Elf64_External_Rela *) srela->contents
1770
                                  + srela->reloc_count));
1771
      ++srela->reloc_count;
1772
    }
1773
 
1774
  if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
1775
    {
1776
      asection *s;
1777
      Elf_Internal_Rela rela;
1778
 
1779
      /* This symbol needs a copy reloc.  Set it up.  */
1780
 
1781
      BFD_ASSERT (h->dynindx != -1
1782
                  && (h->root.type == bfd_link_hash_defined
1783
                      || h->root.type == bfd_link_hash_defweak));
1784
 
1785
      s = bfd_get_section_by_name (h->root.u.def.section->owner,
1786
                                   ".rela.bss");
1787
      BFD_ASSERT (s != NULL);
1788
 
1789
      rela.r_offset = (h->root.u.def.value
1790
                       + h->root.u.def.section->output_section->vma
1791
                       + h->root.u.def.section->output_offset);
1792
      rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_COPY);
1793
      rela.r_addend = 0;
1794
      bfd_elf64_swap_reloca_out (output_bfd, &rela,
1795
                                 ((Elf64_External_Rela *) s->contents
1796
                                  + s->reloc_count));
1797
      ++s->reloc_count;
1798
    }
1799
 
1800
  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
1801
  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
1802
      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
1803
    sym->st_shndx = SHN_ABS;
1804
 
1805
  return true;
1806
}
1807
 
1808
/* Finish up the dynamic sections.  */
1809
 
1810
static boolean
1811
elf64_x86_64_finish_dynamic_sections (output_bfd, info)
1812
     bfd *output_bfd;
1813
     struct bfd_link_info *info;
1814
{
1815
  bfd *dynobj;
1816
  asection *sdyn;
1817
  asection *sgot;
1818
 
1819
  dynobj = elf_hash_table (info)->dynobj;
1820
 
1821
  sgot = bfd_get_section_by_name (dynobj, ".got.plt");
1822
  BFD_ASSERT (sgot != NULL);
1823
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
1824
 
1825
  if (elf_hash_table (info)->dynamic_sections_created)
1826
    {
1827
      asection *splt;
1828
      Elf64_External_Dyn *dyncon, *dynconend;
1829
 
1830
      BFD_ASSERT (sdyn != NULL);
1831
 
1832
      dyncon = (Elf64_External_Dyn *) sdyn->contents;
1833
      dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
1834
      for (; dyncon < dynconend; dyncon++)
1835
        {
1836
          Elf_Internal_Dyn dyn;
1837
          const char *name;
1838
          asection *s;
1839
 
1840
          bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
1841
 
1842
          switch (dyn.d_tag)
1843
            {
1844
            default:
1845
              continue;
1846
 
1847
            case DT_PLTGOT:
1848
              name = ".got";
1849
              goto get_vma;
1850
 
1851
            case DT_JMPREL:
1852
              name = ".rela.plt";
1853
 
1854
            get_vma:
1855
              s = bfd_get_section_by_name (output_bfd, name);
1856
              BFD_ASSERT (s != NULL);
1857
              dyn.d_un.d_ptr = s->vma;
1858
              break;
1859
 
1860
            case DT_RELASZ:
1861
              /* FIXME: This comment and code is from elf64-alpha.c:  */
1862
              /* My interpretation of the TIS v1.1 ELF document indicates
1863
                 that RELASZ should not include JMPREL.  This is not what
1864
                 the rest of the BFD does.  It is, however, what the
1865
                 glibc ld.so wants.  Do this fixup here until we found
1866
                 out who is right.  */
1867
              s = bfd_get_section_by_name (output_bfd, ".rela.plt");
1868
              if (s)
1869
                {
1870
                  /* Subtract JMPREL size from RELASZ.  */
1871
                  dyn.d_un.d_val -=
1872
                    (s->_cooked_size ? s->_cooked_size : s->_raw_size);
1873
                }
1874
              break;
1875
 
1876
            case DT_PLTRELSZ:
1877
              s = bfd_get_section_by_name (output_bfd, ".rela.plt");
1878
              BFD_ASSERT (s != NULL);
1879
              dyn.d_un.d_val =
1880
                (s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size);
1881
              break;
1882
            }
1883
          bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
1884
        }
1885
 
1886
      /* Initialize the contents of the .plt section.  */
1887
      splt = bfd_get_section_by_name (dynobj, ".plt");
1888
      BFD_ASSERT (splt != NULL);
1889
      if (splt->_raw_size > 0)
1890
        {
1891
          /* Fill in the first entry in the procedure linkage table.  */
1892
          memcpy (splt->contents, elf64_x86_64_plt0_entry, PLT_ENTRY_SIZE);
1893
          /* Add offset for pushq GOT+8(%rip), since the instruction
1894
             uses 6 bytes subtract this value.  */
1895
          bfd_put_32 (output_bfd,
1896
                      (sgot->output_section->vma
1897
                       + sgot->output_offset
1898
                       + 8
1899
                       - splt->output_section->vma
1900
                       - splt->output_offset
1901
                       - 6),
1902
                      splt->contents + 2);
1903
          /* Add offset for jmp *GOT+16(%rip). The 12 is the offset to
1904
             the end of the instruction.  */
1905
          bfd_put_32 (output_bfd,
1906
                      (sgot->output_section->vma
1907
                       + sgot->output_offset
1908
                       + 16
1909
                       - splt->output_section->vma
1910
                       - splt->output_offset
1911
                       - 12),
1912
                      splt->contents + 8);
1913
 
1914
        }
1915
 
1916
      elf_section_data (splt->output_section)->this_hdr.sh_entsize =
1917
        PLT_ENTRY_SIZE;
1918
    }
1919
 
1920
  /* Set the first entry in the global offset table to the address of
1921
     the dynamic section.  */
1922
  if (sgot->_raw_size > 0)
1923
    {
1924
      if (sdyn == NULL)
1925
        bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents);
1926
      else
1927
        bfd_put_64 (output_bfd,
1928
                    sdyn->output_section->vma + sdyn->output_offset,
1929
                    sgot->contents);
1930
      /* Write GOT[1] and GOT[2], needed for the dynamic linker.  */
1931
      bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + GOT_ENTRY_SIZE);
1932
      bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + GOT_ENTRY_SIZE*2);
1933
    }
1934
 
1935
  elf_section_data (sgot->output_section)->this_hdr.sh_entsize =
1936
    GOT_ENTRY_SIZE;
1937
 
1938
  return true;
1939
}
1940
 
1941
#define TARGET_LITTLE_SYM                   bfd_elf64_x86_64_vec
1942
#define TARGET_LITTLE_NAME                  "elf64-x86-64"
1943
#define ELF_ARCH                            bfd_arch_i386
1944
#define ELF_MACHINE_CODE                    EM_X86_64
1945
#define ELF_MAXPAGESIZE                     0x100000
1946
 
1947
#define elf_backend_can_gc_sections         1
1948
#define elf_backend_want_got_plt            1
1949
#define elf_backend_plt_readonly            1
1950
#define elf_backend_want_plt_sym            0
1951
#define elf_backend_got_header_size         (GOT_ENTRY_SIZE*3)
1952
#define elf_backend_plt_header_size         PLT_ENTRY_SIZE
1953
 
1954
#define elf_info_to_howto                   elf64_x86_64_info_to_howto
1955
 
1956
#define bfd_elf64_bfd_final_link            _bfd_elf64_gc_common_final_link
1957
#define bfd_elf64_bfd_link_hash_table_create \
1958
  elf64_x86_64_link_hash_table_create
1959
#define bfd_elf64_bfd_reloc_type_lookup     elf64_x86_64_reloc_type_lookup
1960
 
1961
#define elf_backend_adjust_dynamic_symbol   elf64_x86_64_adjust_dynamic_symbol
1962
#define elf_backend_check_relocs            elf64_x86_64_check_relocs
1963
#define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
1964
#define elf_backend_finish_dynamic_sections \
1965
  elf64_x86_64_finish_dynamic_sections
1966
#define elf_backend_finish_dynamic_symbol   elf64_x86_64_finish_dynamic_symbol
1967
#define elf_backend_gc_mark_hook            elf64_x86_64_gc_mark_hook
1968
#define elf_backend_gc_sweep_hook           elf64_x86_64_gc_sweep_hook
1969
#define elf_backend_relocate_section        elf64_x86_64_relocate_section
1970
#define elf_backend_size_dynamic_sections   elf64_x86_64_size_dynamic_sections
1971
#define elf_backend_object_p                elf64_x86_64_elf_object_p
1972
 
1973
#include "elf64-target.h"

powered by: WebSVN 2.1.0

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