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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [coff-x86_64.c] - Blame information for rev 301

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

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

powered by: WebSVN 2.1.0

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