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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [coff-x86_64.c] - Blame information for rev 183

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

Line No. Rev Author Line
1 14 khays
/* BFD back-end for AMD 64 COFF files.
2 148 khays
   Copyright 2006, 2007, 2008, 2009, 2010, 2011
3
   Free Software Foundation, Inc.
4 14 khays
 
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 3 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., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.
21
 
22
   Written by Kai Tietz, OneVision Software GmbH&CoKg.  */
23
 
24
#ifndef COFF_WITH_pex64
25
#define COFF_WITH_pex64
26
#endif
27
 
28
/* Note we have to make sure not to include headers twice.
29
   Not all headers are wrapped in #ifdef guards, so we define
30
   PEI_HEADERS to prevent double including here.  */
31
#ifndef PEI_HEADERS
32
#include "sysdep.h"
33
#include "bfd.h"
34
#include "libbfd.h"
35
#include "coff/x86_64.h"
36
#include "coff/internal.h"
37
#include "coff/pe.h"
38
#include "libcoff.h"
39
#include "libiberty.h"
40
#endif
41
 
42
#define BADMAG(x) AMD64BADMAG(x)
43
 
44
#ifdef COFF_WITH_pex64
45
# undef  AOUTSZ
46
# define AOUTSZ         PEPAOUTSZ
47
# define PEAOUTHDR      PEPAOUTHDR
48
#endif
49
 
50
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
51
 
52
/* The page size is a guess based on ELF.  */
53
 
54
#define COFF_PAGE_SIZE 0x1000
55
 
56
/* For some reason when using AMD COFF the value stored in the .text
57
   section for a reference to a common symbol is the value itself plus
58
   any desired offset.  Ian Taylor, Cygnus Support.  */
59
 
60
/* If we are producing relocatable output, we need to do some
61
   adjustments to the object file that are not done by the
62
   bfd_perform_relocation function.  This function is called by every
63
   reloc type to make any required adjustments.  */
64
 
65
static bfd_reloc_status_type
66
coff_amd64_reloc (bfd *abfd,
67
                  arelent *reloc_entry,
68
                  asymbol *symbol,
69
                  void * data,
70
                  asection *input_section ATTRIBUTE_UNUSED,
71
                  bfd *output_bfd,
72
                  char **error_message ATTRIBUTE_UNUSED)
73
{
74
  symvalue diff;
75
 
76
#if !defined(COFF_WITH_PE)
77
  if (output_bfd == NULL)
78
    return bfd_reloc_continue;
79
#endif
80
 
81
  if (bfd_is_com_section (symbol->section))
82
    {
83
#if !defined(COFF_WITH_PE)
84
      /* We are relocating a common symbol.  The current value in the
85
         object file is ORIG + OFFSET, where ORIG is the value of the
86
         common symbol as seen by the object file when it was compiled
87
         (this may be zero if the symbol was undefined) and OFFSET is
88
         the offset into the common symbol (normally zero, but may be
89
         non-zero when referring to a field in a common structure).
90
         ORIG is the negative of reloc_entry->addend, which is set by
91
         the CALC_ADDEND macro below.  We want to replace the value in
92
         the object file with NEW + OFFSET, where NEW is the value of
93
         the common symbol which we are going to put in the final
94
         object file.  NEW is symbol->value.  */
95
      diff = symbol->value + reloc_entry->addend;
96
#else
97
      /* In PE mode, we do not offset the common symbol.  */
98
      diff = reloc_entry->addend;
99
#endif
100
    }
101
  else
102
    {
103
      /* For some reason bfd_perform_relocation always effectively
104
         ignores the addend for a COFF target when producing
105
         relocatable output.  This seems to be always wrong for 386
106
         COFF, so we handle the addend here instead.  */
107
#if defined(COFF_WITH_PE)
108
      if (output_bfd == NULL)
109
        {
110
          reloc_howto_type *howto = reloc_entry->howto;
111
 
112
          /* Although PC relative relocations are very similar between
113
             PE and non-PE formats, but they are off by 1 << howto->size
114
             bytes. For the external relocation, PE is very different
115
             from others. See md_apply_fix3 () in gas/config/tc-amd64.c.
116
             When we link PE and non-PE object files together to
117
             generate a non-PE executable, we have to compensate it
118
             here.  */
119
          if(howto->pc_relative && howto->pcrel_offset)
120
            diff = -(1 << howto->size);
121
          else if(symbol->flags & BSF_WEAK)
122
            diff = reloc_entry->addend - symbol->value;
123
          else
124
            diff = -reloc_entry->addend;
125
        }
126
      else
127
#endif
128
        diff = reloc_entry->addend;
129
    }
130
 
131
#if defined(COFF_WITH_PE)
132
  /* FIXME: How should this case be handled?  */
133
  if (reloc_entry->howto->type == R_AMD64_IMAGEBASE
134
      && output_bfd != NULL
135
      && bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
136
    diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;
137
#endif
138
 
139
#define DOIT(x) \
140
  x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
141
 
142
    if (diff != 0)
143
      {
144
        reloc_howto_type *howto = reloc_entry->howto;
145
        unsigned char *addr = (unsigned char *) data + reloc_entry->address;
146
 
147
        switch (howto->size)
148
          {
149
          case 0:
150
            {
151
              char x = bfd_get_8 (abfd, addr);
152
              DOIT (x);
153
              bfd_put_8 (abfd, x, addr);
154
            }
155
            break;
156
 
157
          case 1:
158
            {
159
              short x = bfd_get_16 (abfd, addr);
160
              DOIT (x);
161
              bfd_put_16 (abfd, (bfd_vma) x, addr);
162
            }
163
            break;
164
 
165
          case 2:
166
            {
167
              long x = bfd_get_32 (abfd, addr);
168
              DOIT (x);
169
              bfd_put_32 (abfd, (bfd_vma) x, addr);
170
            }
171
            break;
172
          case 4:
173
            {
174
              long long x = bfd_get_64 (abfd, addr);
175
              DOIT (x);
176
              bfd_put_64 (abfd, (bfd_vma) x, addr);
177
            }
178
            break;
179
 
180
          default:
181
            abort ();
182
          }
183
      }
184
 
185
  /* Now let bfd_perform_relocation finish everything up.  */
186
  return bfd_reloc_continue;
187
}
188
 
189
#if defined(COFF_WITH_PE)
190
/* Return TRUE if this relocation should appear in the output .reloc
191
   section.  */
192
 
193
static bfd_boolean
194
in_reloc_p (bfd *abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto)
195
{
196
  return ! howto->pc_relative && howto->type != R_AMD64_IMAGEBASE
197
         && howto->type != R_AMD64_SECREL;
198
}
199
#endif /* COFF_WITH_PE */
200
 
201
#ifndef PCRELOFFSET
202
#define PCRELOFFSET TRUE
203
#endif
204
 
205
static reloc_howto_type howto_table[] =
206
{
207
  EMPTY_HOWTO (0),
208
  HOWTO (R_AMD64_DIR64,         /* type  1*/
209
         0,                      /* rightshift */
210
         4,                     /* size (0 = byte, 1 = short, 2 = long, 4 = long long) */
211
         64,                    /* bitsize */
212
         FALSE,                 /* pc_relative */
213
         0,                      /* bitpos */
214
         complain_overflow_bitfield, /* complain_on_overflow */
215
         coff_amd64_reloc,      /* special_function */
216
         "R_X86_64_64",         /* name */
217
         TRUE,                  /* partial_inplace */
218
         0xffffffffffffffffll,  /* src_mask */
219
         0xffffffffffffffffll,  /* dst_mask */
220
         TRUE),                 /* pcrel_offset */
221
  HOWTO (R_AMD64_DIR32,         /* type 2 */
222
         0,                      /* rightshift */
223
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
224
         32,                    /* bitsize */
225
         FALSE,                 /* pc_relative */
226
         0,                      /* bitpos */
227
         complain_overflow_bitfield, /* complain_on_overflow */
228
         coff_amd64_reloc,      /* special_function */
229
         "R_X86_64_32",         /* name */
230
         TRUE,                  /* partial_inplace */
231
         0xffffffff,            /* src_mask */
232
         0xffffffff,            /* dst_mask */
233
         TRUE),                 /* pcrel_offset */
234
  /* PE IMAGE_REL_AMD64_ADDR32NB relocation (3).        */
235
  HOWTO (R_AMD64_IMAGEBASE,     /* type */
236
         0,                      /* rightshift */
237
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
238
         32,                    /* bitsize */
239
         FALSE,                 /* pc_relative */
240
         0,                      /* bitpos */
241
         complain_overflow_bitfield, /* complain_on_overflow */
242
         coff_amd64_reloc,      /* special_function */
243
         "rva32",               /* name */
244
         TRUE,                  /* partial_inplace */
245
         0xffffffff,            /* src_mask */
246
         0xffffffff,            /* dst_mask */
247
         FALSE),                /* pcrel_offset */
248
  /* 32-bit longword PC relative relocation (4).  */
249
  HOWTO (R_AMD64_PCRLONG,       /* type 4 */
250
         0,                      /* rightshift */
251
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
252
         32,                    /* bitsize */
253
         TRUE,                  /* pc_relative */
254
         0,                      /* bitpos */
255
         complain_overflow_signed, /* complain_on_overflow */
256
         coff_amd64_reloc,      /* special_function */
257
         "R_X86_64_PC32",       /* name */
258
         TRUE,                  /* partial_inplace */
259
         0xffffffff,            /* src_mask */
260
         0xffffffff,            /* dst_mask */
261
         PCRELOFFSET),          /* pcrel_offset */
262
 
263
 HOWTO (R_AMD64_PCRLONG_1,      /* type 5 */
264
         0,                      /* rightshift */
265
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
266
         32,                    /* bitsize */
267
         TRUE,                  /* pc_relative */
268
         0,                      /* bitpos */
269
         complain_overflow_signed, /* complain_on_overflow */
270
         coff_amd64_reloc,      /* special_function */
271
         "DISP32+1",            /* name */
272
         TRUE,                  /* partial_inplace */
273
         0xffffffff,            /* src_mask */
274
         0xffffffff,            /* dst_mask */
275
         PCRELOFFSET),          /* pcrel_offset */
276
 HOWTO (R_AMD64_PCRLONG_2,      /* type 6 */
277
         0,                      /* rightshift */
278
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
279
         32,                    /* bitsize */
280
         TRUE,                  /* pc_relative */
281
         0,                      /* bitpos */
282
         complain_overflow_signed, /* complain_on_overflow */
283
         coff_amd64_reloc,      /* special_function */
284
         "DISP32+2",            /* name */
285
         TRUE,                  /* partial_inplace */
286
         0xffffffff,            /* src_mask */
287
         0xffffffff,            /* dst_mask */
288
         PCRELOFFSET),          /* pcrel_offset */
289
 HOWTO (R_AMD64_PCRLONG_3,      /* type 7 */
290
         0,                      /* rightshift */
291
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
292
         32,                    /* bitsize */
293
         TRUE,                  /* pc_relative */
294
         0,                      /* bitpos */
295
         complain_overflow_signed, /* complain_on_overflow */
296
         coff_amd64_reloc,      /* special_function */
297
         "DISP32+3",            /* name */
298
         TRUE,                  /* partial_inplace */
299
         0xffffffff,            /* src_mask */
300
         0xffffffff,            /* dst_mask */
301
         PCRELOFFSET),          /* pcrel_offset */
302
 HOWTO (R_AMD64_PCRLONG_4,      /* type 8 */
303
         0,                      /* rightshift */
304
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
305
         32,                    /* bitsize */
306
         TRUE,                  /* pc_relative */
307
         0,                      /* bitpos */
308
         complain_overflow_signed, /* complain_on_overflow */
309
         coff_amd64_reloc,      /* special_function */
310
         "DISP32+4",            /* name */
311
         TRUE,                  /* partial_inplace */
312
         0xffffffff,            /* src_mask */
313
         0xffffffff,            /* dst_mask */
314
         PCRELOFFSET),          /* pcrel_offset */
315
 HOWTO (R_AMD64_PCRLONG_5,      /* type 9 */
316
         0,                      /* rightshift */
317
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
318
         32,                    /* bitsize */
319
         TRUE,                  /* pc_relative */
320
         0,                      /* bitpos */
321
         complain_overflow_signed, /* complain_on_overflow */
322
         coff_amd64_reloc,      /* special_function */
323
         "DISP32+5",            /* name */
324
         TRUE,                  /* partial_inplace */
325
         0xffffffff,            /* src_mask */
326
         0xffffffff,            /* dst_mask */
327
         PCRELOFFSET),          /* pcrel_offset */
328
  EMPTY_HOWTO (10), /* R_AMD64_SECTION 10  */
329
#if defined(COFF_WITH_PE)
330
  /* 32-bit longword section relative relocation (11).  */
331
  HOWTO (R_AMD64_SECREL,        /* type */
332
         0,                      /* rightshift */
333
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
334
         32,                    /* bitsize */
335
         FALSE,                 /* pc_relative */
336
         0,                      /* bitpos */
337
         complain_overflow_bitfield, /* complain_on_overflow */
338
         coff_amd64_reloc,      /* special_function */
339
         "secrel32",            /* name */
340
         TRUE,                  /* partial_inplace */
341
         0xffffffff,            /* src_mask */
342
         0xffffffff,            /* dst_mask */
343
         TRUE),                 /* pcrel_offset */
344
#else
345
  EMPTY_HOWTO (11),
346
#endif
347
  EMPTY_HOWTO (12),
348
  EMPTY_HOWTO (13),
349
#ifndef DONT_EXTEND_AMD64
350
  HOWTO (R_AMD64_PCRQUAD,
351
         0,                     /* rightshift */
352
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
353
         64,                    /* bitsize */
354
         TRUE,                  /* pc_relative */
355
         0,                     /* bitpos */
356
         complain_overflow_signed, /* complain_on_overflow */
357
         coff_amd64_reloc,      /* special_function */
358
         "R_X86_64_PC64",       /* name */
359
         TRUE,                  /* partial_inplace */
360
         0xffffffffffffffffll,  /* src_mask */
361
         0xffffffffffffffffll,  /* dst_mask */
362
         PCRELOFFSET),           /* pcrel_offset */
363
#else
364
  EMPTY_HOWTO (14),
365
#endif
366
  /* Byte relocation (15).  */
367
  HOWTO (R_RELBYTE,             /* type */
368
         0,                      /* rightshift */
369
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
370
         8,                     /* bitsize */
371
         FALSE,                 /* pc_relative */
372
         0,                      /* bitpos */
373
         complain_overflow_bitfield, /* complain_on_overflow */
374
         coff_amd64_reloc,      /* special_function */
375
         "R_X86_64_8",          /* name */
376
         TRUE,                  /* partial_inplace */
377
         0x000000ff,            /* src_mask */
378
         0x000000ff,            /* dst_mask */
379
         PCRELOFFSET),          /* pcrel_offset */
380
  /* 16-bit word relocation (16).  */
381
  HOWTO (R_RELWORD,             /* type */
382
         0,                      /* rightshift */
383
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
384
         16,                    /* bitsize */
385
         FALSE,                 /* pc_relative */
386
         0,                      /* bitpos */
387
         complain_overflow_bitfield, /* complain_on_overflow */
388
         coff_amd64_reloc,      /* special_function */
389
         "R_X86_64_16",         /* name */
390
         TRUE,                  /* partial_inplace */
391
         0x0000ffff,            /* src_mask */
392
         0x0000ffff,            /* dst_mask */
393
         PCRELOFFSET),          /* pcrel_offset */
394
  /* 32-bit longword relocation (17).   */
395
  HOWTO (R_RELLONG,             /* type */
396
         0,                      /* rightshift */
397
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
398
         32,                    /* bitsize */
399
         FALSE,                 /* pc_relative */
400
         0,                      /* bitpos */
401
         complain_overflow_bitfield, /* complain_on_overflow */
402
         coff_amd64_reloc,      /* special_function */
403
         "R_X86_64_32S",        /* name */
404
         TRUE,                  /* partial_inplace */
405
         0xffffffff,            /* src_mask */
406
         0xffffffff,            /* dst_mask */
407
         PCRELOFFSET),          /* pcrel_offset */
408
  /* Byte PC relative relocation (18).   */
409
  HOWTO (R_PCRBYTE,             /* type */
410
         0,                      /* rightshift */
411
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
412
         8,                     /* bitsize */
413
         TRUE,                  /* pc_relative */
414
         0,                      /* bitpos */
415
         complain_overflow_signed, /* complain_on_overflow */
416
         coff_amd64_reloc,      /* special_function */
417
         "R_X86_64_PC8",        /* name */
418
         TRUE,                  /* partial_inplace */
419
         0x000000ff,            /* src_mask */
420
         0x000000ff,            /* dst_mask */
421
         PCRELOFFSET),          /* pcrel_offset */
422
  /* 16-bit word PC relative relocation (19).   */
423
  HOWTO (R_PCRWORD,             /* type */
424
         0,                      /* rightshift */
425
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
426
         16,                    /* bitsize */
427
         TRUE,                  /* pc_relative */
428
         0,                      /* bitpos */
429
         complain_overflow_signed, /* complain_on_overflow */
430
         coff_amd64_reloc,      /* special_function */
431
         "R_X86_64_PC16",       /* name */
432
         TRUE,                  /* partial_inplace */
433
         0x0000ffff,            /* src_mask */
434
         0x0000ffff,            /* dst_mask */
435
         PCRELOFFSET),          /* pcrel_offset */
436
  /* 32-bit longword PC relative relocation (20).  */
437
  HOWTO (R_PCRLONG,             /* type */
438
         0,                      /* rightshift */
439
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
440
         32,                    /* bitsize */
441
         TRUE,                  /* pc_relative */
442
         0,                      /* bitpos */
443
         complain_overflow_signed, /* complain_on_overflow */
444
         coff_amd64_reloc,      /* special_function */
445
         "R_X86_64_PC32",       /* name */
446
         TRUE,                  /* partial_inplace */
447
         0xffffffff,            /* src_mask */
448
         0xffffffff,            /* dst_mask */
449
         PCRELOFFSET)           /* pcrel_offset */
450
};
451
 
452
/* Turn a howto into a reloc  nunmber */
453
 
454
#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
455
#define I386  1                 /* Customize coffcode.h */
456
#define AMD64 1
457
 
458
#define RTYPE2HOWTO(cache_ptr, dst)             \
459
  ((cache_ptr)->howto =                         \
460
   ((dst)->r_type < ARRAY_SIZE (howto_table))   \
461
    ? howto_table + (dst)->r_type               \
462
    : NULL)
463
 
464
/* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
465
   library.  On some other COFF targets STYP_BSS is normally
466
   STYP_NOLOAD.  */
467
#define BSS_NOLOAD_IS_SHARED_LIBRARY
468
 
469
/* Compute the addend of a reloc.  If the reloc is to a common symbol,
470
   the object file contains the value of the common symbol.  By the
471
   time this is called, the linker may be using a different symbol
472
   from a different object file with a different value.  Therefore, we
473
   hack wildly to locate the original symbol from this file so that we
474
   can make the correct adjustment.  This macro sets coffsym to the
475
   symbol from the original file, and uses it to set the addend value
476
   correctly.  If this is not a common symbol, the usual addend
477
   calculation is done, except that an additional tweak is needed for
478
   PC relative relocs.
479
   FIXME: This macro refers to symbols and asect; these are from the
480
   calling function, not the macro arguments.  */
481
 
482
#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)                \
483
  {                                                             \
484
    coff_symbol_type *coffsym = NULL;                           \
485
                                                                \
486
    if (ptr && bfd_asymbol_bfd (ptr) != abfd)                   \
487
      coffsym = (obj_symbols (abfd)                             \
488
                 + (cache_ptr->sym_ptr_ptr - symbols));         \
489
    else if (ptr)                                               \
490
      coffsym = coff_symbol_from (abfd, ptr);                   \
491
                                                                \
492
    if (coffsym != NULL                                         \
493
        && coffsym->native->u.syment.n_scnum == 0)               \
494
      cache_ptr->addend = - coffsym->native->u.syment.n_value;  \
495
    else if (ptr && bfd_asymbol_bfd (ptr) == abfd               \
496
             && ptr->section != NULL)                           \
497
      cache_ptr->addend = - (ptr->section->vma + ptr->value);   \
498
    else                                                        \
499
      cache_ptr->addend = 0;                                     \
500
    if (ptr && howto_table[reloc.r_type].pc_relative)           \
501
      cache_ptr->addend += asect->vma;                          \
502
  }
503
 
504
/* We use the special COFF backend linker.  For normal AMD64 COFF, we
505
   can use the generic relocate_section routine.  For PE, we need our
506
   own routine.  */
507
 
508
#if !defined(COFF_WITH_PE)
509
 
510
#define coff_relocate_section _bfd_coff_generic_relocate_section
511
 
512
#else /* COFF_WITH_PE */
513
 
514
/* The PE relocate section routine.  The only difference between this
515
   and the regular routine is that we don't want to do anything for a
516
   relocatable link.  */
517
 
518
static bfd_boolean
519
coff_pe_amd64_relocate_section (bfd *output_bfd,
520
                                struct bfd_link_info *info,
521
                                bfd *input_bfd,
522
                                asection *input_section,
523
                                bfd_byte *contents,
524
                                struct internal_reloc *relocs,
525
                                struct internal_syment *syms,
526
                                asection **sections)
527
{
528
  if (info->relocatable)
529
    return TRUE;
530
 
531
  return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,input_section, contents,relocs, syms, sections);
532
}
533
 
534
#define coff_relocate_section coff_pe_amd64_relocate_section
535
 
536
#endif /* COFF_WITH_PE */
537
 
538
/* Convert an rtype to howto for the COFF backend linker.  */
539
 
540
static reloc_howto_type *
541
coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
542
                           asection *sec,
543
                           struct internal_reloc *rel,
544
                           struct coff_link_hash_entry *h,
545
                           struct internal_syment *sym,
546
                           bfd_vma *addendp)
547
{
548
  reloc_howto_type *howto;
549
 
550
  if (rel->r_type >= ARRAY_SIZE (howto_table))
551
    {
552
      bfd_set_error (bfd_error_bad_value);
553
      return NULL;
554
    }
555
  howto = howto_table + rel->r_type;
556
 
557
#if defined(COFF_WITH_PE)
558
  /* Cancel out code in _bfd_coff_generic_relocate_section.  */
559
  *addendp = 0;
560
  if (rel->r_type >= R_AMD64_PCRLONG_1 && rel->r_type <= R_AMD64_PCRLONG_5)
561
    {
562
      *addendp -= (bfd_vma)(rel->r_type - R_AMD64_PCRLONG);
563
      rel->r_type = R_AMD64_PCRLONG;
564
    }
565
#endif
566
 
567
  if (howto->pc_relative)
568
    *addendp += sec->vma;
569
 
570
  if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
571
    {
572
      /* This is a common symbol.  The section contents include the
573
         size (sym->n_value) as an addend.  The relocate_section
574
         function will be adding in the final value of the symbol.  We
575
         need to subtract out the current size in order to get the
576
         correct result.  */
577
      BFD_ASSERT (h != NULL);
578
 
579
#if !defined(COFF_WITH_PE)
580
      /* I think we *do* want to bypass this.  If we don't, I have
581
         seen some data parameters get the wrong relocation address.
582
         If I link two versions with and without this section bypassed
583
         and then do a binary comparison, the addresses which are
584
         different can be looked up in the map.  The case in which
585
         this section has been bypassed has addresses which correspond
586
         to values I can find in the map.  */
587
      *addendp -= sym->n_value;
588
#endif
589
    }
590
 
591
#if !defined(COFF_WITH_PE)
592
  /* If the output symbol is common (in which case this must be a
593
     relocatable link), we need to add in the final size of the
594
     common symbol.  */
595
  if (h != NULL && h->root.type == bfd_link_hash_common)
596
    *addendp += h->root.u.c.size;
597
#endif
598
 
599
#if defined(COFF_WITH_PE)
600
  if (howto->pc_relative)
601
    {
602
      *addendp -= 4;
603
 
604
      /* If the symbol is defined, then the generic code is going to
605
         add back the symbol value in order to cancel out an
606
         adjustment it made to the addend.  However, we set the addend
607
         to 0 at the start of this function.  We need to adjust here,
608
         to avoid the adjustment the generic code will make.  FIXME:
609
         This is getting a bit hackish.  */
610
      if (sym != NULL && sym->n_scnum != 0)
611
        *addendp -= sym->n_value;
612
    }
613
 
614
  if (rel->r_type == R_AMD64_IMAGEBASE
615
      && (bfd_get_flavour (sec->output_section->owner) == bfd_target_coff_flavour))
616
    *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
617
 
618
  if (rel->r_type == R_AMD64_SECREL)
619
    {
620
      bfd_vma osect_vma;
621
 
622 166 khays
      if (h && (h->root.type == bfd_link_hash_defined
623
                || h->root.type == bfd_link_hash_defweak))
624 14 khays
        osect_vma = h->root.u.def.section->output_section->vma;
625
      else
626
        {
627
          asection *s;
628
          int i;
629
 
630
          /* Sigh, the only way to get the section to offset against
631
             is to find it the hard way.  */
632
          for (s = abfd->sections, i = 1; i < sym->n_scnum; i++)
633
            s = s->next;
634
 
635
          osect_vma = s->output_section->vma;
636
        }
637
 
638
      *addendp -= osect_vma;
639
    }
640
#endif
641
 
642
  return howto;
643
}
644
 
645
#define coff_bfd_reloc_type_lookup coff_amd64_reloc_type_lookup
646
#define coff_bfd_reloc_name_lookup coff_amd64_reloc_name_lookup
647
 
648
static reloc_howto_type *
649
coff_amd64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
650
{
651
  switch (code)
652
    {
653
    case BFD_RELOC_RVA:
654
      return howto_table + R_AMD64_IMAGEBASE;
655
    case BFD_RELOC_32:
656
      return howto_table + R_AMD64_DIR32;
657
    case BFD_RELOC_64:
658
      return howto_table + R_AMD64_DIR64;
659
    case BFD_RELOC_64_PCREL:
660
#ifndef DONT_EXTEND_AMD64
661
      return howto_table + R_AMD64_PCRQUAD;
662
#else
663
      /* Fall through.  */
664
#endif
665
    case BFD_RELOC_32_PCREL:
666
      return howto_table + R_AMD64_PCRLONG;
667
    case BFD_RELOC_X86_64_32S:
668
      return howto_table + R_RELLONG;
669
    case BFD_RELOC_16:
670
      return howto_table + R_RELWORD;
671
    case BFD_RELOC_16_PCREL:
672
      return howto_table + R_PCRWORD;
673
    case BFD_RELOC_8:
674
      return howto_table + R_RELBYTE;
675
    case BFD_RELOC_8_PCREL:
676
      return howto_table + R_PCRBYTE;
677
#if defined(COFF_WITH_PE)
678
    case BFD_RELOC_32_SECREL:
679
      return howto_table + R_AMD64_SECREL;
680
#endif
681
    default:
682
      BFD_FAIL ();
683
      return 0;
684
    }
685
}
686
 
687
static reloc_howto_type *
688
coff_amd64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
689
                              const char *r_name)
690
{
691
  unsigned int i;
692
 
693
  for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
694
    if (howto_table[i].name != NULL
695
        && strcasecmp (howto_table[i].name, r_name) == 0)
696
      return &howto_table[i];
697
 
698
  return NULL;
699
}
700
 
701
#define coff_rtype_to_howto coff_amd64_rtype_to_howto
702
 
703
#ifdef TARGET_UNDERSCORE
704
 
705
/* If amd64 gcc uses underscores for symbol names, then it does not use
706
   a leading dot for local labels, so if TARGET_UNDERSCORE is defined
707
   we treat all symbols starting with L as local.  */
708
 
709
static bfd_boolean
710
coff_amd64_is_local_label_name (bfd *abfd, const char *name)
711
{
712
  if (name[0] == 'L')
713
    return TRUE;
714
 
715
  return _bfd_coff_is_local_label_name (abfd, name);
716
}
717
 
718
#define coff_bfd_is_local_label_name coff_amd64_is_local_label_name
719
 
720
#endif /* TARGET_UNDERSCORE */
721
 
722
#ifndef bfd_pe_print_pdata
723
#define bfd_pe_print_pdata   NULL
724
#endif
725
 
726
#include "coffcode.h"
727
 
728
#ifdef PE
729
#define amd64coff_object_p pe_bfd_object_p
730
#else
731
#define amd64coff_object_p coff_object_p
732
#endif
733
 
734
const bfd_target
735
#ifdef TARGET_SYM
736
  TARGET_SYM =
737
#else
738
  x86_64coff_vec =
739
#endif
740
{
741
#ifdef TARGET_NAME
742
  TARGET_NAME,
743
#else
744
 "coff-x86-64",                 /* Name.  */
745
#endif
746
  bfd_target_coff_flavour,
747
  BFD_ENDIAN_LITTLE,            /* Data byte order is little.  */
748
  BFD_ENDIAN_LITTLE,            /* Header byte order is little.  */
749
 
750
  (HAS_RELOC | EXEC_P |         /* Object flags.  */
751
   HAS_LINENO | HAS_DEBUG |
752
   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
753
 
754
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags.  */
755
#if defined(COFF_WITH_PE)
756
   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY
757
#endif
758
   | SEC_CODE | SEC_DATA),
759
 
760
#ifdef TARGET_UNDERSCORE
761
  TARGET_UNDERSCORE,            /* Leading underscore.  */
762
#else
763
  0,                             /* Leading underscore.  */
764
#endif
765
  '/',                          /* Ar_pad_char.  */
766
  15,                           /* Ar_max_namelen.  */
767 148 khays
  0,                             /* match priority.  */
768 14 khays
 
769
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
770
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
771
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
772
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
773
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
774
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs.  */
775
 
776
  /* Note that we allow an object file to be treated as a core file as well.  */
777
  { _bfd_dummy_target, amd64coff_object_p, /* BFD_check_format.  */
778
    bfd_generic_archive_p, amd64coff_object_p },
779
  { bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format.  */
780
    bfd_false },
781
  { bfd_false, coff_write_object_contents, /* bfd_write_contents.  */
782
   _bfd_write_archive_contents, bfd_false },
783
 
784
  BFD_JUMP_TABLE_GENERIC (coff),
785
  BFD_JUMP_TABLE_COPY (coff),
786
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
787
  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
788
  BFD_JUMP_TABLE_SYMBOLS (coff),
789
  BFD_JUMP_TABLE_RELOCS (coff),
790
  BFD_JUMP_TABLE_WRITE (coff),
791
  BFD_JUMP_TABLE_LINK (coff),
792
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
793
 
794
  NULL,
795
 
796
  COFF_SWAP_TABLE
797
};

powered by: WebSVN 2.1.0

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