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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [pe-mips.c] - Blame information for rev 143

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

Line No. Rev Author Line
1 14 khays
/* BFD back-end for MIPS PE COFF files.
2
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3
   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
   Modified from coff-i386.c by DJ Delorie, dj@cygnus.com
6
 
7
   This file is part of BFD, the Binary File Descriptor library.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program; if not, write to the Free Software
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22
   MA 02110-1301, USA.  */
23
 
24
#define COFF_WITH_PE
25
/* pei-mips.c may have defined this to default off (0) before
26
  including this file, so don't redefine if that's the case.
27
  Otherwise we're generating objects, not executable images,
28
  so we want to define it to default on.  */
29
#ifndef COFF_LONG_SECTION_NAMES
30
#define COFF_LONG_SECTION_NAMES
31
#endif /* COFF_LONG_SECTION_NAMES */
32
#define PCRELOFFSET TRUE
33
 
34
#include "sysdep.h"
35
#include "bfd.h"
36
#include "libbfd.h"
37
#include "coff/mipspe.h"
38
#include "coff/internal.h"
39
#include "coff/pe.h"
40
#include "libcoff.h"
41
 
42
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
43
/* The page size is a guess based on ELF.  */
44
 
45
#define COFF_PAGE_SIZE 0x1000
46
 
47
/* For some reason when using mips COFF the value stored in the .text
48
   section for a reference to a common symbol is the value itself plus
49
   any desired offset.  Ian Taylor, Cygnus Support.  */
50
 
51
/* If we are producing relocatable output, we need to do some
52
   adjustments to the object file that are not done by the
53
   bfd_perform_relocation function.  This function is called by every
54
   reloc type to make any required adjustments.  */
55
 
56
static bfd_reloc_status_type
57
coff_mips_reloc (bfd *abfd,
58
                 arelent *reloc_entry,
59
                 asymbol *symbol,
60
                 void * data,
61
                 asection *input_section ATTRIBUTE_UNUSED,
62
                 bfd *output_bfd,
63
                 char **error_message ATTRIBUTE_UNUSED)
64
{
65
  symvalue diff;
66
 
67
  if (output_bfd == NULL)
68
    return bfd_reloc_continue;
69
 
70
  if (bfd_is_com_section (symbol->section))
71
    {
72
#ifndef COFF_WITH_PE
73
      /* We are relocating a common symbol.  The current value in the
74
         object file is ORIG + OFFSET, where ORIG is the value of the
75
         common symbol as seen by the object file when it was compiled
76
         (this may be zero if the symbol was undefined) and OFFSET is
77
         the offset into the common symbol (normally zero, but may be
78
         non-zero when referring to a field in a common structure).
79
         ORIG is the negative of reloc_entry->addend, which is set by
80
         the CALC_ADDEND macro below.  We want to replace the value in
81
         the object file with NEW + OFFSET, where NEW is the value of
82
         the common symbol which we are going to put in the final
83
         object file.  NEW is symbol->value.  */
84
      diff = symbol->value + reloc_entry->addend;
85
#else
86
      /* In PE mode, we do not offset the common symbol.  */
87
      diff = reloc_entry->addend;
88
#endif
89
    }
90
  else
91
    /* For some reason bfd_perform_relocation always effectively
92
       ignores the addend for a COFF target when producing
93
       relocatable output.  This seems to be always wrong for 386
94
       COFF, so we handle the addend here instead.  */
95
    diff = reloc_entry->addend;
96
 
97
#define DOIT(x) \
98
  x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + (diff >> howto->rightshift)) & howto->dst_mask))
99
 
100
    if (diff != 0)
101
      {
102
        reloc_howto_type *howto = reloc_entry->howto;
103
        unsigned char *addr = (unsigned char *) data + reloc_entry->address;
104
 
105
        switch (howto->size)
106
          {
107
          case 0:
108
            {
109
              char x = bfd_get_8 (abfd, addr);
110
 
111
              DOIT (x);
112
              bfd_put_8 (abfd, x, addr);
113
            }
114
            break;
115
 
116
          case 1:
117
            {
118
              short x = bfd_get_16 (abfd, addr);
119
 
120
              DOIT (x);
121
              bfd_put_16 (abfd, (bfd_vma) x, addr);
122
            }
123
            break;
124
 
125
          case 2:
126
            {
127
              long x = bfd_get_32 (abfd, addr);
128
 
129
              DOIT (x);
130
              bfd_put_32 (abfd, (bfd_vma) x, addr);
131
            }
132
            break;
133
 
134
          default:
135
            abort ();
136
          }
137
      }
138
 
139
  /* Now let bfd_perform_relocation finish everything up.  */
140
  return bfd_reloc_continue;
141
}
142
 
143
#ifdef COFF_WITH_PE
144
/* Return TRUE if this relocation should
145
   appear in the output .reloc section.  */
146
 
147
static bfd_boolean
148
in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto)
149
{
150
  return ! howto->pc_relative && howto->type != MIPS_R_RVA;
151
}
152
#endif
153
 
154
#ifndef PCRELOFFSET
155
#define PCRELOFFSET FALSE
156
#endif
157
 
158
static reloc_howto_type howto_table[] =
159
{
160
  /* Reloc type 0 is ignored.  The reloc reading code ensures that
161
     this is a reference to the .abs section, which will cause
162
     bfd_perform_relocation to do nothing.  */
163
  HOWTO (MIPS_R_ABSOLUTE,       /* Type.  */
164
         0,                      /* Rightshift.  */
165
         0,                      /* Size (0 = byte, 1 = short, 2 = long).  */
166
         8,                     /* Bitsize.  */
167
         FALSE,                 /* PC_relative.  */
168
         0,                      /* Bitpos. */
169
         complain_overflow_dont, /* Complain_on_overflow. */
170
         0,                      /* Special_function. */
171
         "IGNORE",              /* Name. */
172
         FALSE,                 /* Partial_inplace. */
173
         0,                      /* Src_mask. */
174
         0,                      /* Dst_mask. */
175
         FALSE),                /* Pcrel_offset. */
176
 
177
  /* A 16 bit reference to a symbol, normally from a data section.  */
178
  HOWTO (MIPS_R_REFHALF,        /* Type.  */
179
         0,                      /* Rightshift.  */
180
         1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
181
         16,                    /* Bitsize.  */
182
         FALSE,                 /* PC_relative.  */
183
         0,                      /* Bitpos. */
184
         complain_overflow_bitfield, /* Complain_on_overflow. */
185
         coff_mips_reloc,       /* Special_function. */
186
         "REFHALF",             /* Name. */
187
         TRUE,                  /* Partial_inplace. */
188
         0xffff,                /* Src_mask. */
189
         0xffff,                /* Dst_mask. */
190
         FALSE),                /* Pcrel_offset. */
191
 
192
  /* A 32 bit reference to a symbol, normally from a data section.  */
193
  HOWTO (MIPS_R_REFWORD,        /* Type.  */
194
         0,                      /* Rightshift.  */
195
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
196
         32,                    /* Bitsize.  */
197
         FALSE,                 /* PC_relative.  */
198
         0,                      /* Bitpos. */
199
         complain_overflow_bitfield, /* Complain_on_overflow. */
200
         coff_mips_reloc,       /* Special_function. */
201
         "REFWORD",             /* Name. */
202
         TRUE,                  /* Partial_inplace. */
203
         0xffffffff,            /* Src_mask. */
204
         0xffffffff,            /* Dst_mask. */
205
         FALSE),                /* Pcrel_offset. */
206
 
207
  /* A 26 bit absolute jump address.  */
208
  HOWTO (MIPS_R_JMPADDR,        /* Type.  */
209
         2,                     /* Rightshift.  */
210
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
211
         26,                    /* Bitsize.  */
212
         FALSE,                 /* PC_relative.  */
213
         0,                      /* Bitpos. */
214
         complain_overflow_dont, /* Complain_on_overflow. */
215
                                /* This needs complex overflow
216
                                   detection, because the upper four
217
                                   bits must match the PC.  */
218
         coff_mips_reloc,       /* Special_function. */
219
         "JMPADDR",             /* Name. */
220
         TRUE,                  /* Partial_inplace. */
221
         0x3ffffff,             /* Src_mask. */
222
         0x3ffffff,             /* Dst_mask. */
223
         FALSE),                /* Pcrel_offset. */
224
 
225
  /* The high 16 bits of a symbol value.  Handled by the function
226
     mips_refhi_reloc.  */
227
  HOWTO (MIPS_R_REFHI,          /* Type.  */
228
         16,                    /* Rightshift.  */
229
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
230
         16,                    /* Bitsize.  */
231
         FALSE,                 /* PC_relative.  */
232
         0,                      /* Bitpos. */
233
         complain_overflow_bitfield, /* Complain_on_overflow. */
234
         coff_mips_reloc,       /* Special_function. */
235
         "REFHI",               /* Name. */
236
         TRUE,                  /* Partial_inplace. */
237
         0xffff,                /* Src_mask. */
238
         0xffff,                /* Dst_mask. */
239
         FALSE),                /* Pcrel_offset. */
240
 
241
  /* The low 16 bits of a symbol value.  */
242
  HOWTO (MIPS_R_REFLO,          /* Type.  */
243
         0,                      /* Rightshift.  */
244
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
245
         16,                    /* Bitsize.  */
246
         FALSE,                 /* PC_relative.  */
247
         0,                      /* Bitpos. */
248
         complain_overflow_dont, /* Complain_on_overflow. */
249
         coff_mips_reloc,       /* Special_function. */
250
         "REFLO",               /* Name. */
251
         TRUE,                  /* Partial_inplace. */
252
         0xffff,                /* Src_mask. */
253
         0xffff,                /* Dst_mask. */
254
         FALSE),                /* Pcrel_offset. */
255
 
256
  /* A reference to an offset from the gp register.  Handled by the
257
     function mips_gprel_reloc.  */
258
  HOWTO (MIPS_R_GPREL,          /* Type.  */
259
         0,                      /* Rightshift.  */
260
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
261
         16,                    /* Bitsize.  */
262
         FALSE,                 /* PC_relative.  */
263
         0,                      /* Bitpos. */
264
         complain_overflow_signed, /* Complain_on_overflow. */
265
         coff_mips_reloc,       /* Special_function. */
266
         "GPREL",               /* Name. */
267
         TRUE,                  /* Partial_inplace. */
268
         0xffff,                /* Src_mask. */
269
         0xffff,                /* Dst_mask. */
270
         FALSE),                /* Pcrel_offset. */
271
 
272
  /* A reference to a literal using an offset from the gp register.
273
     Handled by the function mips_gprel_reloc.  */
274
  HOWTO (MIPS_R_LITERAL,        /* Type.  */
275
         0,                      /* Rightshift.  */
276
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
277
         16,                    /* Bitsize.  */
278
         FALSE,                 /* PC_relative.  */
279
         0,                      /* Bitpos. */
280
         complain_overflow_signed, /* Complain_on_overflow. */
281
         coff_mips_reloc,       /* Special_function. */
282
         "LITERAL",             /* Name. */
283
         TRUE,                  /* Partial_inplace. */
284
         0xffff,                /* Src_mask. */
285
         0xffff,                /* Dst_mask. */
286
         FALSE),                /* Pcrel_offset. */
287
 
288
  EMPTY_HOWTO (8),
289
  EMPTY_HOWTO (9),
290
  EMPTY_HOWTO (10),
291
  EMPTY_HOWTO (11),
292
  EMPTY_HOWTO (12),
293
  EMPTY_HOWTO (13),
294
  EMPTY_HOWTO (14),
295
  EMPTY_HOWTO (15),
296
  EMPTY_HOWTO (16),
297
  EMPTY_HOWTO (17),
298
  EMPTY_HOWTO (18),
299
  EMPTY_HOWTO (19),
300
  EMPTY_HOWTO (20),
301
  EMPTY_HOWTO (21),
302
  EMPTY_HOWTO (22),
303
  EMPTY_HOWTO (23),
304
  EMPTY_HOWTO (24),
305
  EMPTY_HOWTO (25),
306
  EMPTY_HOWTO (26),
307
  EMPTY_HOWTO (27),
308
  EMPTY_HOWTO (28),
309
  EMPTY_HOWTO (29),
310
  EMPTY_HOWTO (30),
311
  EMPTY_HOWTO (31),
312
  EMPTY_HOWTO (32),
313
  EMPTY_HOWTO (33),
314
  HOWTO (MIPS_R_RVA,            /* Type.  */
315
         0,                      /* Rightshift.  */
316
         2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
317
         32,                    /* Bitsize.  */
318
         FALSE,                 /* PC_relative.  */
319
         0,                      /* Bitpos. */
320
         complain_overflow_bitfield, /* Complain_on_overflow. */
321
         coff_mips_reloc,       /* Special_function. */
322
         "rva32",               /* Name. */
323
         TRUE,                  /* Partial_inplace. */
324
         0xffffffff,            /* Src_mask. */
325
         0xffffffff,            /* Dst_mask. */
326
         FALSE),                /* Pcrel_offset. */
327
  EMPTY_HOWTO (35),
328
  EMPTY_HOWTO (36),
329
  HOWTO (MIPS_R_PAIR,           /* 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_mips_reloc,       /* Special_function. */
337
         "PAIR",                /* Name. */
338
         TRUE,                  /* Partial_inplace. */
339
         0xffffffff,            /* Src_mask. */
340
         0xffffffff,            /* Dst_mask. */
341
         FALSE),                /* Pcrel_offset. */
342
};
343
 
344
/* Turn a howto into a reloc nunmber.  */
345
 
346
#define SELECT_RELOC(x, howto) { x.r_type = howto->type; }
347
#define BADMAG(x)              MIPSBADMAG (x)
348
 
349
/* Customize coffcode.h.  */
350
#define MIPS 1
351
 
352
#define RTYPE2HOWTO(cache_ptr, dst) \
353
            (cache_ptr)->howto = howto_table + (dst)->r_type;
354
 
355
/* Compute the addend of a reloc.  If the reloc is to a common symbol,
356
   the object file contains the value of the common symbol.  By the
357
   time this is called, the linker may be using a different symbol
358
   from a different object file with a different value.  Therefore, we
359
   hack wildly to locate the original symbol from this file so that we
360
   can make the correct adjustment.  This macro sets coffsym to the
361
   symbol from the original file, and uses it to set the addend value
362
   correctly.  If this is not a common symbol, the usual addend
363
   calculation is done, except that an additional tweak is needed for
364
   PC relative relocs.
365
   FIXME: This macro refers to symbols and asect; these are from the
366
   calling function, not the macro arguments.  */
367
 
368
#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)                \
369
  {                                                             \
370
    coff_symbol_type *coffsym = NULL;                           \
371
    if (ptr && bfd_asymbol_bfd (ptr) != abfd)                   \
372
      coffsym = (obj_symbols (abfd)                             \
373
                 + (cache_ptr->sym_ptr_ptr - symbols));         \
374
    else if (ptr)                                               \
375
      coffsym = coff_symbol_from (abfd, ptr);                   \
376
    if (coffsym != NULL                                         \
377
        && coffsym->native->u.syment.n_scnum == 0)               \
378
      cache_ptr->addend = - coffsym->native->u.syment.n_value;  \
379
    else if (ptr && bfd_asymbol_bfd (ptr) == abfd               \
380
             && ptr->section != NULL)                           \
381
      cache_ptr->addend = - (ptr->section->vma + ptr->value);   \
382
    else                                                        \
383
      cache_ptr->addend = 0;                                     \
384
    if (ptr && howto_table[reloc.r_type].pc_relative)           \
385
      cache_ptr->addend += asect->vma;                          \
386
  }
387
 
388
/* Convert an rtype to howto for the COFF backend linker.  */
389
 
390
static reloc_howto_type *
391
coff_mips_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
392
                          asection *sec,
393
                          struct internal_reloc *rel,
394
                          struct coff_link_hash_entry *h,
395
                          struct internal_syment *sym,
396
                          bfd_vma *addendp)
397
{
398
 
399
  reloc_howto_type *howto;
400
 
401
  howto = howto_table + rel->r_type;
402
 
403
#ifdef COFF_WITH_PE
404
  *addendp = 0;
405
#endif
406
 
407
  if (howto->pc_relative)
408
    *addendp += sec->vma;
409
 
410
  if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
411
    {
412
      /* This is a common symbol.  The section contents include the
413
         size (sym->n_value) as an addend.  The relocate_section
414
         function will be adding in the final value of the symbol.  We
415
         need to subtract out the current size in order to get the
416
         correct result.  */
417
 
418
      BFD_ASSERT (h != NULL);
419
 
420
#ifndef COFF_WITH_PE
421
      /* I think we *do* want to bypass this.  If we don't, I have
422
         seen some data parameters get the wrong relocation address.
423
         If I link two versions with and without this section bypassed
424
         and then do a binary comparison, the addresses which are
425
         different can be looked up in the map.  The case in which
426
         this section has been bypassed has addresses which correspond
427
         to values I can find in the map.  */
428
      *addendp -= sym->n_value;
429
#endif
430
    }
431
 
432
#ifndef COFF_WITH_PE
433
  /* If the output symbol is common (in which case this must be a
434
     relocatable link), we need to add in the final size of the
435
     common symbol.  */
436
  if (h != NULL && h->root.type == bfd_link_hash_common)
437
    *addendp += h->root.u.c.size;
438
#endif
439
 
440
#ifdef COFF_WITH_PE
441
  if (howto->pc_relative)
442
    {
443
      *addendp -= 4;
444
 
445
      /* If the symbol is defined, then the generic code is going to
446
         add back the symbol value in order to cancel out an
447
         adjustment it made to the addend.  However, we set the addend
448
         to 0 at the start of this function.  We need to adjust here,
449
         to avoid the adjustment the generic code will make.  FIXME:
450
         This is getting a bit hackish.  */
451
      if (sym != NULL && sym->n_scnum != 0)
452
        *addendp -= sym->n_value;
453
    }
454
 
455
  if (rel->r_type == MIPS_R_RVA)
456
    *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
457
#endif
458
 
459
  return howto;
460
}
461
 
462
#define coff_rtype_to_howto         coff_mips_rtype_to_howto
463
#define coff_bfd_reloc_type_lookup  coff_mips_reloc_type_lookup
464
#define coff_bfd_reloc_name_lookup coff_mips_reloc_name_lookup
465
 
466
/* Get the howto structure for a generic reloc type.  */
467
 
468
static reloc_howto_type *
469
coff_mips_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
470
                             bfd_reloc_code_real_type code)
471
{
472
  int mips_type;
473
 
474
  switch (code)
475
    {
476
    case BFD_RELOC_16:
477
      mips_type = MIPS_R_REFHALF;
478
      break;
479
    case BFD_RELOC_32:
480
    case BFD_RELOC_CTOR:
481
      mips_type = MIPS_R_REFWORD;
482
      break;
483
    case BFD_RELOC_MIPS_JMP:
484
      mips_type = MIPS_R_JMPADDR;
485
      break;
486
    case BFD_RELOC_HI16_S:
487
      mips_type = MIPS_R_REFHI;
488
      break;
489
    case BFD_RELOC_LO16:
490
      mips_type = MIPS_R_REFLO;
491
      break;
492
    case BFD_RELOC_GPREL16:
493
      mips_type = MIPS_R_GPREL;
494
      break;
495
    case BFD_RELOC_MIPS_LITERAL:
496
      mips_type = MIPS_R_LITERAL;
497
      break;
498
    case BFD_RELOC_RVA:
499
      mips_type = MIPS_R_RVA;
500
      break;
501
    default:
502
      return NULL;
503
    }
504
 
505
  return & howto_table [mips_type];
506
}
507
 
508
static reloc_howto_type *
509
coff_mips_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
510
                             const char *r_name)
511
{
512
  unsigned int i;
513
 
514
  for (i = 0;
515
       i < sizeof (howto_table) / sizeof (howto_table[0]);
516
       i++)
517
    if (howto_table[i].name != NULL
518
        && strcasecmp (howto_table[i].name, r_name) == 0)
519
      return &howto_table[i];
520
 
521
  return NULL;
522
}
523
 
524
static void
525
mips_swap_reloc_in (bfd * abfd, void * src, void * dst)
526
{
527
  static struct internal_reloc pair_prev;
528
  RELOC *reloc_src = (RELOC *) src;
529
  struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
530
 
531
  reloc_dst->r_vaddr = H_GET_32 (abfd, reloc_src->r_vaddr);
532
  reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
533
  reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type);
534
  reloc_dst->r_size = 0;
535
  reloc_dst->r_extern = 0;
536
  reloc_dst->r_offset = 0;
537
 
538
  switch (reloc_dst->r_type)
539
  {
540
  case MIPS_R_REFHI:
541
    pair_prev = *reloc_dst;
542
    break;
543
  case MIPS_R_PAIR:
544
    reloc_dst->r_offset = reloc_dst->r_symndx;
545
    if (reloc_dst->r_offset & 0x8000)
546
      reloc_dst->r_offset -= 0x10000;
547
    reloc_dst->r_symndx = pair_prev.r_symndx;
548
    break;
549
  }
550
}
551
 
552
static unsigned int
553
mips_swap_reloc_out (bfd * abfd, void * src, void * dst)
554
{
555
  static bfd_vma prev_addr = 0;
556
  struct internal_reloc *reloc_src = (struct internal_reloc *)src;
557
  struct external_reloc *reloc_dst = (struct external_reloc *)dst;
558
 
559
  switch (reloc_src->r_type)
560
    {
561
    case MIPS_R_REFHI:
562
      prev_addr = reloc_src->r_vaddr;
563
      break;
564
    case MIPS_R_REFLO:
565
      if (reloc_src->r_vaddr == prev_addr)
566
        {
567
          /* FIXME: only slightly hackish.  If we see a REFLO pointing to
568
             the same address as a REFHI, we assume this is the matching
569
             PAIR reloc and output it accordingly.  The symndx is really
570
             the low 16 bits of the addend */
571
          H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
572
          H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
573
          H_PUT_16 (abfd, MIPS_R_PAIR, reloc_dst->r_type);
574
          return RELSZ;
575
        }
576
      break;
577
    }
578
 
579
  H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
580
  H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
581
 
582
  H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
583
  return RELSZ;
584
}
585
 
586
#define coff_swap_reloc_in   mips_swap_reloc_in
587
#define coff_swap_reloc_out  mips_swap_reloc_out
588
#define NO_COFF_RELOCS
589
 
590
static bfd_boolean
591
coff_pe_mips_relocate_section (bfd *output_bfd,
592
                               struct bfd_link_info *info,
593
                               bfd *input_bfd,
594
                               asection *input_section,
595
                               bfd_byte *contents,
596
                               struct internal_reloc *relocs,
597
                               struct internal_syment *syms,
598
                               asection **sections)
599
{
600
  struct internal_reloc *rel;
601
  struct internal_reloc *rel_end;
602
  unsigned int i;
603
 
604
  if (info->relocatable)
605
    {
606
      (*_bfd_error_handler)
607
        (_("%B: `ld -r' not supported with PE MIPS objects\n"), input_bfd);
608
      bfd_set_error (bfd_error_bad_value);
609
      return FALSE;
610
    }
611
 
612
  BFD_ASSERT (input_bfd->xvec->byteorder
613
              == output_bfd->xvec->byteorder);
614
 
615
  rel = relocs;
616
  rel_end = rel + input_section->reloc_count;
617
 
618
  for (i = 0; rel < rel_end; rel++, i++)
619
    {
620
      long symndx;
621
      struct coff_link_hash_entry *h;
622
      struct internal_syment *sym;
623
      bfd_vma addend = 0;
624
      bfd_vma val, tmp, targ, src, low;
625
      reloc_howto_type *howto;
626
      unsigned char *mem = contents + rel->r_vaddr;
627
 
628
      symndx = rel->r_symndx;
629
 
630
      if (symndx == -1)
631
        {
632
          h = NULL;
633
          sym = NULL;
634
        }
635
      else
636
        {
637
          h = obj_coff_sym_hashes (input_bfd)[symndx];
638
          sym = syms + symndx;
639
        }
640
 
641
      /* COFF treats common symbols in one of two ways.  Either the
642
         size of the symbol is included in the section contents, or it
643
         is not.  We assume that the size is not included, and force
644
         the rtype_to_howto function to adjust the addend as needed.  */
645
 
646
      if (sym != NULL && sym->n_scnum != 0)
647
        addend = - sym->n_value;
648
      else
649
        addend = 0;
650
 
651
      howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
652
                                       sym, &addend);
653
      if (howto == NULL)
654
        return FALSE;
655
 
656
      /* If we are doing a relocatable link, then we can just ignore
657
         a PC relative reloc that is pcrel_offset.  It will already
658
         have the correct value.  If this is not a relocatable link,
659
         then we should ignore the symbol value.  */
660
      if (howto->pc_relative && howto->pcrel_offset)
661
        {
662
          if (info->relocatable)
663
            continue;
664
          if (sym != NULL && sym->n_scnum != 0)
665
            addend += sym->n_value;
666
        }
667
 
668
      val = 0;
669
 
670
      if (h == NULL)
671
        {
672
          asection *sec;
673
 
674
          if (symndx == -1)
675
            {
676
              sec = bfd_abs_section_ptr;
677
              val = 0;
678
            }
679
          else
680
            {
681
              sec = sections[symndx];
682
              val = (sec->output_section->vma
683
                     + sec->output_offset
684
                     + sym->n_value);
685
              if (! obj_pe (input_bfd))
686
                val -= sec->vma;
687
            }
688
        }
689
      else
690
        {
691
          if (h->root.type == bfd_link_hash_defined
692
              || h->root.type == bfd_link_hash_defweak)
693
            {
694
              asection *sec;
695
 
696
              sec = h->root.u.def.section;
697
              val = (h->root.u.def.value
698
                     + sec->output_section->vma
699
                     + sec->output_offset);
700
              }
701
 
702
          else if (! info->relocatable)
703
            {
704
              if (! ((*info->callbacks->undefined_symbol)
705
                     (info, h->root.root.string, input_bfd, input_section,
706
                      rel->r_vaddr - input_section->vma, TRUE)))
707
                return FALSE;
708
            }
709
        }
710
 
711
      src = rel->r_vaddr + input_section->output_section->vma
712
        + input_section->output_offset;
713
 
714
      /* OK, at this point the following variables are set up:
715
           src = VMA of the memory we're fixing up
716
           mem = pointer to memory we're fixing up
717
           val = VMA of what we need to refer to.  */
718
 
719
#define UI(x) (*_bfd_error_handler) (_("%B: unimplemented %s\n"), \
720
                                     input_bfd, x); \
721
              bfd_set_error (bfd_error_bad_value);
722
 
723
      switch (rel->r_type)
724
        {
725
        case MIPS_R_ABSOLUTE:
726
          /* Ignore these.  */
727
          break;
728
 
729
        case MIPS_R_REFHALF:
730
          UI ("refhalf");
731
          break;
732
 
733
        case MIPS_R_REFWORD:
734
          tmp = bfd_get_32 (input_bfd, mem);
735
          /* printf ("refword: src=%08x targ=%08x+%08x\n", src, tmp, val); */
736
          tmp += val;
737
          bfd_put_32 (input_bfd, tmp, mem);
738
          break;
739
 
740
        case MIPS_R_JMPADDR:
741
          tmp = bfd_get_32 (input_bfd, mem);
742
          targ = val + (tmp & 0x03ffffff) * 4;
743
          if ((src & 0xf0000000) != (targ & 0xf0000000))
744
            {
745
              (*_bfd_error_handler) (_("%B: jump too far away\n"), input_bfd);
746
              bfd_set_error (bfd_error_bad_value);
747
              return FALSE;
748
            }
749
          tmp &= 0xfc000000;
750
          tmp |= (targ / 4) & 0x3ffffff;
751
          bfd_put_32 (input_bfd, tmp, mem);
752
          break;
753
 
754
        case MIPS_R_REFHI:
755
          tmp = bfd_get_32 (input_bfd, mem);
756
          switch (rel[1].r_type)
757
            {
758
            case MIPS_R_PAIR:
759
              /* MS PE object */
760
              targ = val + rel[1].r_offset + ((tmp & 0xffff) << 16);
761
              break;
762
            case MIPS_R_REFLO:
763
              /* GNU COFF object */
764
              low = bfd_get_32 (input_bfd, contents + rel[1].r_vaddr);
765
              low &= 0xffff;
766
              if (low & 0x8000)
767
                low -= 0x10000;
768
              targ = val + low + ((tmp & 0xffff) << 16);
769
              break;
770
            default:
771
              (*_bfd_error_handler) (_("%B: bad pair/reflo after refhi\n"),
772
                                     input_bfd);
773
              bfd_set_error (bfd_error_bad_value);
774
              return FALSE;
775
            }
776
          tmp &= 0xffff0000;
777
          tmp |= (targ >> 16) & 0xffff;
778
          bfd_put_32 (input_bfd, tmp, mem);
779
          break;
780
 
781
        case MIPS_R_REFLO:
782
          tmp = bfd_get_32 (input_bfd, mem);
783
          targ = val + (tmp & 0xffff);
784
          /* printf ("refword: src=%08x targ=%08x\n", src, targ); */
785
          tmp &= 0xffff0000;
786
          tmp |= targ & 0xffff;
787
          bfd_put_32 (input_bfd, tmp, mem);
788
          break;
789
 
790
        case MIPS_R_GPREL:
791
        case MIPS_R_LITERAL:
792
          UI ("gprel");
793
          break;
794
 
795
        case MIPS_R_SECTION:
796
          UI ("section");
797
          break;
798
 
799
        case MIPS_R_SECREL:
800
          UI ("secrel");
801
          break;
802
 
803
        case MIPS_R_SECRELLO:
804
          UI ("secrello");
805
          break;
806
 
807
        case MIPS_R_SECRELHI:
808
          UI ("secrelhi");
809
          break;
810
 
811
        case MIPS_R_RVA:
812
          tmp = bfd_get_32 (input_bfd, mem);
813
          /* printf ("rva: src=%08x targ=%08x+%08x\n", src, tmp, val); */
814
          tmp += val
815
            - pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase;
816
          bfd_put_32 (input_bfd, tmp, mem);
817
          break;
818
 
819
        case MIPS_R_PAIR:
820
          /* ignore these */
821
          break;
822
        }
823
    }
824
 
825
  return TRUE;
826
}
827
 
828
#define coff_relocate_section coff_pe_mips_relocate_section
829
 
830
#ifdef TARGET_UNDERSCORE
831
 
832
/* If mips gcc uses underscores for symbol names, then it does not use
833
   a leading dot for local labels, so if TARGET_UNDERSCORE is defined
834
   we treat all symbols starting with L as local.  */
835
 
836
static bfd_boolean
837
coff_mips_is_local_label_name (bfd *abfd, const char *name)
838
{
839
  if (name[0] == 'L')
840
    return TRUE;
841
 
842
  return _bfd_coff_is_local_label_name (abfd, name);
843
}
844
 
845
#define coff_bfd_is_local_label_name coff_mips_is_local_label_name
846
 
847
#endif /* TARGET_UNDERSCORE */
848
 
849
#define COFF_NO_HACK_SCNHDR_SIZE
850
 
851
#ifndef bfd_pe_print_pdata
852
#define bfd_pe_print_pdata      NULL
853
#endif
854
 
855
#include "coffcode.h"
856
 
857
const bfd_target
858
#ifdef TARGET_SYM
859
  TARGET_SYM =
860
#else
861
  mipslpe_vec =
862
#endif
863
{
864
#ifdef TARGET_NAME
865
  TARGET_NAME,
866
#else
867
  "pe-mips",                    /* Name.  */
868
#endif
869
  bfd_target_coff_flavour,
870
  BFD_ENDIAN_LITTLE,            /* Data byte order is little.  */
871
  BFD_ENDIAN_LITTLE,            /* Header byte order is little.  */
872
 
873
  (HAS_RELOC | EXEC_P |         /* Object flags.  */
874
   HAS_LINENO | HAS_DEBUG |
875
   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
876
 
877
#ifndef COFF_WITH_PE
878
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags.  */
879
   | SEC_CODE | SEC_DATA),
880
#else
881
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags.  */
882
   | SEC_CODE | SEC_DATA
883
   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
884
#endif
885
 
886
#ifdef TARGET_UNDERSCORE
887
  TARGET_UNDERSCORE,            /* Leading underscore.  */
888
#else
889
  0,                             /* leading underscore */
890
#endif
891
  '/',                          /* AR_pad_char.  */
892
  15,                           /* AR_max_namelen.  */
893
 
894
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
895
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
896
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
897
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
898
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
899
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers.  */
900
 
901
  /* Note that we allow an object file to be treated as a core file as well.  */
902
  {_bfd_dummy_target, coff_object_p, /* bfd_check_format.  */
903
   bfd_generic_archive_p, coff_object_p},
904
  {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format.  */
905
   bfd_false},
906
  {bfd_false, coff_write_object_contents, /* bfd_write_contents.  */
907
   _bfd_write_archive_contents, bfd_false},
908
 
909
  BFD_JUMP_TABLE_GENERIC (coff),
910
  BFD_JUMP_TABLE_COPY (coff),
911
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
912
  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
913
  BFD_JUMP_TABLE_SYMBOLS (coff),
914
  BFD_JUMP_TABLE_RELOCS (coff),
915
  BFD_JUMP_TABLE_WRITE (coff),
916
  BFD_JUMP_TABLE_LINK (coff),
917
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
918
 
919
  NULL,
920
 
921
  COFF_SWAP_TABLE
922
};

powered by: WebSVN 2.1.0

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