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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [cpu-ns32k.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* BFD support for the ns32k architecture.
2
   Copyright 1990, 1991, 1994, 1995, 1998, 2000
3
   Free Software Foundation, Inc.
4
   Almost totally rewritten by Ian Dall from initial work
5
   by Andrew Cagney.
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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
 
23
#include "bfd.h"
24
#include "sysdep.h"
25
#include "libbfd.h"
26
#include "ns32k.h"
27
 
28
#define N(machine, printable, d, next)  \
29
{  32, 32, 8, bfd_arch_ns32k, machine, "ns32k",printable,3,d,bfd_default_compatible,bfd_default_scan, next, }
30
 
31
static const bfd_arch_info_type arch_info_struct[] =
32
{
33
  N(32532,"ns32k:32532",true, 0), /* the word ns32k will match this too */
34
};
35
 
36
const bfd_arch_info_type bfd_ns32k_arch =
37
  N(32032,"ns32k:32032",false, &arch_info_struct[0]);
38
 
39
static long
40
ns32k_sign_extend(value, bits)
41
     int value;
42
     int bits;
43
{
44
  value = value & ((1 << bits) - 1);
45
  return (value & (1 << (bits-1))
46
          ? value | (~((1 << bits) - 1))
47
          : value);
48
}
49
 
50
long
51
_bfd_ns32k_get_displacement(buffer, offset, size)
52
     bfd_byte *buffer;
53
     long offset;
54
     long size;
55
{
56
  long value;
57
  buffer += offset;
58
  switch (size)
59
    {
60
    case 1:
61
      value = ns32k_sign_extend (*buffer, 7);
62
      break;
63
    case 2:
64
      value = ns32k_sign_extend(*buffer++, 6);
65
      value = (value << 8) | (0xff & *buffer);
66
      break;
67
    case 4:
68
      value = ns32k_sign_extend(*buffer++, 6);
69
      value = (value << 8) | (0xff & *buffer++);
70
      value = (value << 8) | (0xff & *buffer++);
71
      value = (value << 8) | (0xff & *buffer);
72
      break;
73
    default:
74
      abort ();
75
      return 0;
76
    }
77
  return value;
78
}
79
 
80
int
81
_bfd_ns32k_put_displacement(value, buffer, offset, size)
82
     long value;
83
     bfd_byte *buffer;
84
     long offset;
85
     long size;
86
{
87
  buffer += offset;
88
  switch (size)
89
    {
90
    case 1:
91
      if (value < -64 || value > 63)
92
        return -1;
93
      value&=0x7f;
94
      *buffer++=value;
95
      break;
96
    case 2:
97
      if (value < -8192 || value > 8191)
98
        return -1;
99
      value&=0x3fff;
100
      value|=0x8000;
101
      *buffer++=(value>>8);
102
      *buffer++=value;
103
      break;
104
    case 4:
105
      if (value < -0x1f000000 || value >= 0x20000000)
106
        return -1;
107
      value|=0xc0000000;
108
      *buffer++=(value>>24);
109
      *buffer++=(value>>16);
110
      *buffer++=(value>>8);
111
      *buffer++=value;
112
      break;
113
    default:
114
      return -1;
115
  }
116
  return 0;
117
}
118
 
119
long
120
_bfd_ns32k_get_immediate (buffer, offset, size)
121
     bfd_byte *buffer;
122
     long offset;
123
     long size;
124
{
125
  long value = 0;
126
  buffer += offset;
127
  switch (size)
128
    {
129
    case 4:
130
      value = (value << 8) | (*buffer++ & 0xff);
131
    case 3:
132
      value = (value << 8) | (*buffer++ & 0xff);
133
    case 2:
134
      value = (value << 8) | (*buffer++ & 0xff);
135
    case 1:
136
      value = (value << 8) | (*buffer++ & 0xff);
137
    }
138
  return value;
139
}
140
 
141
int
142
_bfd_ns32k_put_immediate (value, buffer, offset, size)
143
     long value;
144
     bfd_byte *buffer;
145
     long offset;
146
     long size;
147
{
148
  buffer += offset + size - 1;
149
  switch (size)
150
    {
151
    case 4:
152
      *buffer-- = (value & 0xff); value >>= 8;
153
    case 3:
154
      *buffer-- = (value & 0xff); value >>= 8;
155
    case 2:
156
      *buffer-- = (value & 0xff); value >>= 8;
157
    case 1:
158
      *buffer-- = (value & 0xff); value >>= 8;
159
    }
160
  return 0;
161
}
162
 
163
/* This is just like the standard perform_relocation except we
164
 * use get_data and put_data which know about the ns32k
165
 * storage methods.
166
 * This is probably a lot more complicated than it needs to be!
167
 */
168
static bfd_reloc_status_type
169
do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
170
                error_message, get_data, put_data)
171
     bfd *abfd;
172
     arelent *reloc_entry;
173
     struct symbol_cache_entry *symbol;
174
     PTR data;
175
     asection *input_section;
176
     bfd *output_bfd;
177
     char **error_message ATTRIBUTE_UNUSED;
178
     long (*get_data) ();
179
     int (*put_data) ();
180
{
181
  int overflow = 0;
182
  bfd_vma relocation;
183
  bfd_reloc_status_type flag = bfd_reloc_ok;
184
  bfd_size_type addr = reloc_entry->address;
185
  bfd_vma output_base = 0;
186
  reloc_howto_type *howto = reloc_entry->howto;
187
  asection *reloc_target_output_section;
188
 
189
  if ((symbol->section == &bfd_abs_section)
190
      && output_bfd != (bfd *) NULL)
191
    {
192
      reloc_entry->address += input_section->output_offset;
193
      return bfd_reloc_ok;
194
    }
195
 
196
  /* If we are not producing relocateable output, return an error if
197
     the symbol is not defined.  An undefined weak symbol is
198
     considered to have a value of zero (SVR4 ABI, p. 4-27).  */
199
  if (symbol->section == &bfd_und_section
200
      && (symbol->flags & BSF_WEAK) == 0
201
      && output_bfd == (bfd *) NULL)
202
    flag = bfd_reloc_undefined;
203
 
204
  /* Is the address of the relocation really within the section?  */
205
  if (reloc_entry->address > input_section->_cooked_size)
206
    return bfd_reloc_outofrange;
207
 
208
  /* Work out which section the relocation is targetted at and the
209
     initial relocation command value.  */
210
 
211
  /* Get symbol value.  (Common symbols are special.)  */
212
  if (bfd_is_com_section (symbol->section))
213
    relocation = 0;
214
  else
215
    relocation = symbol->value;
216
 
217
  reloc_target_output_section = symbol->section->output_section;
218
 
219
  /* Convert input-section-relative symbol value to absolute.  */
220
  if (output_bfd && howto->partial_inplace == false)
221
    output_base = 0;
222
  else
223
    output_base = reloc_target_output_section->vma;
224
 
225
  relocation += output_base + symbol->section->output_offset;
226
 
227
  /* Add in supplied addend.  */
228
  relocation += reloc_entry->addend;
229
 
230
  /* Here the variable relocation holds the final address of the
231
     symbol we are relocating against, plus any addend.  */
232
 
233
  if (howto->pc_relative == true)
234
    {
235
      /* This is a PC relative relocation.  We want to set RELOCATION
236
         to the distance between the address of the symbol and the
237
         location.  RELOCATION is already the address of the symbol.
238
 
239
         We start by subtracting the address of the section containing
240
         the location.
241
 
242
         If pcrel_offset is set, we must further subtract the position
243
         of the location within the section.  Some targets arrange for
244
         the addend to be the negative of the position of the location
245
         within the section; for example, i386-aout does this.  For
246
         i386-aout, pcrel_offset is false.  Some other targets do not
247
         include the position of the location; for example, m88kbcs,
248
         or ELF.  For those targets, pcrel_offset is true.
249
 
250
         If we are producing relocateable output, then we must ensure
251
         that this reloc will be correctly computed when the final
252
         relocation is done.  If pcrel_offset is false we want to wind
253
         up with the negative of the location within the section,
254
         which means we must adjust the existing addend by the change
255
         in the location within the section.  If pcrel_offset is true
256
         we do not want to adjust the existing addend at all.
257
 
258
         FIXME: This seems logical to me, but for the case of
259
         producing relocateable output it is not what the code
260
         actually does.  I don't want to change it, because it seems
261
         far too likely that something will break.  */
262
 
263
      relocation -=
264
        input_section->output_section->vma + input_section->output_offset;
265
 
266
      if (howto->pcrel_offset == true)
267
        relocation -= reloc_entry->address;
268
    }
269
 
270
  if (output_bfd != (bfd *) NULL)
271
    {
272
      if (howto->partial_inplace == false)
273
        {
274
          /* This is a partial relocation, and we want to apply the relocation
275
             to the reloc entry rather than the raw data. Modify the reloc
276
             inplace to reflect what we now know.  */
277
          reloc_entry->addend = relocation;
278
          reloc_entry->address += input_section->output_offset;
279
          return flag;
280
        }
281
      else
282
        {
283
          /* This is a partial relocation, but inplace, so modify the
284
             reloc record a bit.
285
 
286
             If we've relocated with a symbol with a section, change
287
             into a ref to the section belonging to the symbol.  */
288
 
289
          reloc_entry->address += input_section->output_offset;
290
 
291
          /* WTF?? */
292
          if (abfd->xvec->flavour == bfd_target_coff_flavour)
293
            {
294
#if 1
295
              /* For m68k-coff, the addend was being subtracted twice during
296
                 relocation with -r.  Removing the line below this comment
297
                 fixes that problem; see PR 2953.
298
 
299
However, Ian wrote the following, regarding removing the line below,
300
which explains why it is still enabled:  --djm
301
 
302
If you put a patch like that into BFD you need to check all the COFF
303
linkers.  I am fairly certain that patch will break coff-i386 (e.g.,
304
SCO); see coff_i386_reloc in coff-i386.c where I worked around the
305
problem in a different way.  There may very well be a reason that the
306
code works as it does.
307
 
308
Hmmm.  The first obvious point is that bfd_perform_relocation should
309
not have any tests that depend upon the flavour.  It's seem like
310
entirely the wrong place for such a thing.  The second obvious point
311
is that the current code ignores the reloc addend when producing
312
relocateable output for COFF.  That's peculiar.  In fact, I really
313
have no idea what the point of the line you want to remove is.
314
 
315
A typical COFF reloc subtracts the old value of the symbol and adds in
316
the new value to the location in the object file (if it's a pc
317
relative reloc it adds the difference between the symbol value and the
318
location).  When relocating we need to preserve that property.
319
 
320
BFD handles this by setting the addend to the negative of the old
321
value of the symbol.  Unfortunately it handles common symbols in a
322
non-standard way (it doesn't subtract the old value) but that's a
323
different story (we can't change it without losing backward
324
compatibility with old object files) (coff-i386 does subtract the old
325
value, to be compatible with existing coff-i386 targets, like SCO).
326
 
327
So everything works fine when not producing relocateable output.  When
328
we are producing relocateable output, logically we should do exactly
329
what we do when not producing relocateable output.  Therefore, your
330
patch is correct.  In fact, it should probably always just set
331
reloc_entry->addend to 0 for all cases, since it is, in fact, going to
332
add the value into the object file.  This won't hurt the COFF code,
333
which doesn't use the addend; I'm not sure what it will do to other
334
formats (the thing to check for would be whether any formats both use
335
the addend and set partial_inplace).
336
 
337
When I wanted to make coff-i386 produce relocateable output, I ran
338
into the problem that you are running into: I wanted to remove that
339
line.  Rather than risk it, I made the coff-i386 relocs use a special
340
function; it's coff_i386_reloc in coff-i386.c.  The function
341
specifically adds the addend field into the object file, knowing that
342
bfd_perform_relocation is not going to.  If you remove that line, then
343
coff-i386.c will wind up adding the addend field in twice.  It's
344
trivial to fix; it just needs to be done.
345
 
346
The problem with removing the line is just that it may break some
347
working code.  With BFD it's hard to be sure of anything.  The right
348
way to deal with this is simply to build and test at least all the
349
supported COFF targets.  It should be straightforward if time and disk
350
space consuming.  For each target:
351
    1) build the linker
352
    2) generate some executable, and link it using -r (I would
353
       probably use paranoia.o and link against newlib/libc.a, which
354
       for all the supported targets would be available in
355
       /usr/cygnus/progressive/H-host/target/lib/libc.a).
356
    3) make the change to reloc.c
357
    4) rebuild the linker
358
    5) repeat step 2
359
    6) if the resulting object files are the same, you have at least
360
       made it no worse
361
    7) if they are different you have to figure out which version is
362
       right
363
*/
364
              relocation -= reloc_entry->addend;
365
#endif
366
              reloc_entry->addend = 0;
367
            }
368
          else
369
            {
370
              reloc_entry->addend = relocation;
371
            }
372
        }
373
    }
374
  else
375
    {
376
      reloc_entry->addend = 0;
377
    }
378
 
379
  /* FIXME: This overflow checking is incomplete, because the value
380
     might have overflowed before we get here.  For a correct check we
381
     need to compute the value in a size larger than bitsize, but we
382
     can't reasonably do that for a reloc the same size as a host
383
     machine word.
384
     FIXME: We should also do overflow checking on the result after
385
     adding in the value contained in the object file.  */
386
  if (howto->complain_on_overflow != complain_overflow_dont)
387
    {
388
      bfd_vma check;
389
 
390
      /* Get the value that will be used for the relocation, but
391
         starting at bit position zero.  */
392
      if (howto->rightshift > howto->bitpos)
393
        check = relocation >> (howto->rightshift - howto->bitpos);
394
      else
395
        check = relocation << (howto->bitpos - howto->rightshift);
396
      switch (howto->complain_on_overflow)
397
        {
398
        case complain_overflow_signed:
399
          {
400
            /* Assumes two's complement.  */
401
            bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
402
            bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
403
 
404
            /* The above right shift is incorrect for a signed value.
405
               Fix it up by forcing on the upper bits.  */
406
            if (howto->rightshift > howto->bitpos
407
                && (bfd_signed_vma) relocation < 0)
408
              check |= ((bfd_vma) - 1
409
                        & ~((bfd_vma) - 1
410
                            >> (howto->rightshift - howto->bitpos)));
411
            if ((bfd_signed_vma) check > reloc_signed_max
412
                || (bfd_signed_vma) check < reloc_signed_min)
413
              flag = bfd_reloc_overflow;
414
          }
415
          break;
416
        case complain_overflow_unsigned:
417
          {
418
            /* Assumes two's complement.  This expression avoids
419
               overflow if howto->bitsize is the number of bits in
420
               bfd_vma.  */
421
            bfd_vma reloc_unsigned_max =
422
            (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
423
 
424
            if ((bfd_vma) check > reloc_unsigned_max)
425
              flag = bfd_reloc_overflow;
426
          }
427
          break;
428
        case complain_overflow_bitfield:
429
          {
430
            /* Assumes two's complement.  This expression avoids
431
               overflow if howto->bitsize is the number of bits in
432
               bfd_vma.  */
433
            bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
434
 
435
            if (((bfd_vma) check & ~reloc_bits) != 0
436
                && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
437
              {
438
                /* The above right shift is incorrect for a signed
439
                   value.  See if turning on the upper bits fixes the
440
                   overflow.  */
441
                if (howto->rightshift > howto->bitpos
442
                    && (bfd_signed_vma) relocation < 0)
443
                  {
444
                    check |= ((bfd_vma) - 1
445
                              & ~((bfd_vma) - 1
446
                                  >> (howto->rightshift - howto->bitpos)));
447
                    if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
448
                      flag = bfd_reloc_overflow;
449
                  }
450
                else
451
                  flag = bfd_reloc_overflow;
452
              }
453
          }
454
          break;
455
        default:
456
          abort ();
457
        }
458
    }
459
 
460
  /*
461
    Either we are relocating all the way, or we don't want to apply
462
    the relocation to the reloc entry (probably because there isn't
463
    any room in the output format to describe addends to relocs)
464
    */
465
 
466
  /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
467
     (OSF version 1.3, compiler version 3.11).  It miscompiles the
468
     following program:
469
 
470
     struct str
471
     {
472
       unsigned int i0;
473
     } s = { 0 };
474
 
475
     int
476
     main ()
477
     {
478
       unsigned long x;
479
 
480
       x = 0x100000000;
481
       x <<= (unsigned long) s.i0;
482
       if (x == 0)
483
         printf ("failed\n");
484
       else
485
         printf ("succeeded (%lx)\n", x);
486
     }
487
     */
488
 
489
  relocation >>= (bfd_vma) howto->rightshift;
490
 
491
  /* Shift everything up to where it's going to be used */
492
 
493
  relocation <<= (bfd_vma) howto->bitpos;
494
 
495
  /* Wait for the day when all have the mask in them */
496
 
497
  /* What we do:
498
     i instruction to be left alone
499
     o offset within instruction
500
     r relocation offset to apply
501
     S src mask
502
     D dst mask
503
     N ~dst mask
504
     A part 1
505
     B part 2
506
     R result
507
 
508
     Do this:
509
     i i i i i o o o o o        from bfd_get<size>
510
     and           S S S S S    to get the size offset we want
511
     +   r r r r r r r r r r  to get the final value to place
512
     and           D D D D D  to chop to right size
513
     -----------------------
514
     A A A A A
515
     And this:
516
     ...   i i i i i o o o o o  from bfd_get<size>
517
     and   N N N N N            get instruction
518
     -----------------------
519
     ...   B B B B B
520
 
521
     And then:
522
     B B B B B
523
     or              A A A A A
524
     -----------------------
525
     R R R R R R R R R R        put into bfd_put<size>
526
     */
527
 
528
#define DOIT(x) \
529
  x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))
530
 
531
  switch (howto->size)
532
    {
533
    case 0:
534
      {
535
        char x = get_data (data, addr, 1);
536
        DOIT (x);
537
        overflow = put_data(x, data, addr, 1);
538
      }
539
      break;
540
 
541
    case 1:
542
      if (relocation)
543
        {
544
          short x = get_data (data, addr, 2);
545
          DOIT (x);
546
          overflow = put_data(x, (unsigned char *) data, addr, 2);
547
        }
548
      break;
549
    case 2:
550
      if (relocation)
551
        {
552
          long x = get_data (data, addr, 4);
553
          DOIT (x);
554
          overflow = put_data(x, data, addr, 4);
555
        }
556
      break;
557
    case -2:
558
      {
559
        long  x = get_data(data, addr, 4);
560
        relocation = -relocation;
561
        DOIT(x);
562
        overflow = put_data(x, data , addr, 4);
563
      }
564
      break;
565
 
566
    case 3:
567
      /* Do nothing */
568
      break;
569
 
570
    case 4:
571
#ifdef BFD64
572
      if (relocation)
573
        {
574
          bfd_vma x = get_data (data, addr, 8);
575
          DOIT (x);
576
          overflow = put_data(x, data, addr, 8);
577
        }
578
#else
579
      abort ();
580
#endif
581
      break;
582
    default:
583
      return bfd_reloc_other;
584
    }
585
  if ((howto->complain_on_overflow != complain_overflow_dont) && overflow)
586
    return bfd_reloc_overflow;
587
 
588
  return flag;
589
}
590
 
591
/* Relocate a given location using a given value and howto.  */
592
 
593
bfd_reloc_status_type
594
_bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
595
                              get_data, put_data)
596
     reloc_howto_type *howto;
597
     bfd *input_bfd ATTRIBUTE_UNUSED;
598
     bfd_vma relocation;
599
     bfd_byte *location;
600
     long (*get_data) ();
601
     int (*put_data) ();
602
{
603
  int size;
604
  bfd_vma x;
605
  boolean overflow;
606
 
607
  /* If the size is negative, negate RELOCATION.  This isn't very
608
     general.  */
609
  if (howto->size < 0)
610
    relocation = -relocation;
611
 
612
  /* Get the value we are going to relocate.  */
613
  size = bfd_get_reloc_size (howto);
614
  switch (size)
615
    {
616
    default:
617
    case 0:
618
      abort ();
619
    case 1:
620
    case 2:
621
    case 4:
622
#ifdef BFD64
623
    case 8:
624
#endif
625
      x = get_data (location, 0, size);
626
      break;
627
    }
628
 
629
  /* Check for overflow.  FIXME: We may drop bits during the addition
630
     which we don't check for.  We must either check at every single
631
     operation, which would be tedious, or we must do the computations
632
     in a type larger than bfd_vma, which would be inefficient.  */
633
  overflow = false;
634
  if (howto->complain_on_overflow != complain_overflow_dont)
635
    {
636
      bfd_vma check;
637
      bfd_signed_vma signed_check;
638
      bfd_vma add;
639
      bfd_signed_vma signed_add;
640
 
641
      if (howto->rightshift == 0)
642
        {
643
          check = relocation;
644
          signed_check = (bfd_signed_vma) relocation;
645
        }
646
      else
647
        {
648
          /* Drop unwanted bits from the value we are relocating to.  */
649
          check = relocation >> howto->rightshift;
650
 
651
          /* If this is a signed value, the rightshift just dropped
652
             leading 1 bits (assuming twos complement).  */
653
          if ((bfd_signed_vma) relocation >= 0)
654
            signed_check = check;
655
          else
656
            signed_check = (check
657
                            | ((bfd_vma) - 1
658
                               & ~((bfd_vma) - 1 >> howto->rightshift)));
659
        }
660
 
661
      /* Get the value from the object file.  */
662
      add = x & howto->src_mask;
663
 
664
      /* Get the value from the object file with an appropriate sign.
665
         The expression involving howto->src_mask isolates the upper
666
         bit of src_mask.  If that bit is set in the value we are
667
         adding, it is negative, and we subtract out that number times
668
         two.  If src_mask includes the highest possible bit, then we
669
         can not get the upper bit, but that does not matter since
670
         signed_add needs no adjustment to become negative in that
671
         case.  */
672
      signed_add = add;
673
      if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
674
        signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
675
 
676
      /* Add the value from the object file, shifted so that it is a
677
         straight number.  */
678
      if (howto->bitpos == 0)
679
        {
680
          check += add;
681
          signed_check += signed_add;
682
        }
683
      else
684
        {
685
          check += add >> howto->bitpos;
686
 
687
          /* For the signed case we use ADD, rather than SIGNED_ADD,
688
             to avoid warnings from SVR4 cc.  This is OK since we
689
             explictly handle the sign bits.  */
690
          if (signed_add >= 0)
691
            signed_check += add >> howto->bitpos;
692
          else
693
            signed_check += ((add >> howto->bitpos)
694
                             | ((bfd_vma) - 1
695
                                & ~((bfd_vma) - 1 >> howto->bitpos)));
696
        }
697
 
698
      switch (howto->complain_on_overflow)
699
        {
700
        case complain_overflow_signed:
701
          {
702
            /* Assumes two's complement.  */
703
            bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
704
            bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
705
 
706
            if (signed_check > reloc_signed_max
707
                || signed_check < reloc_signed_min)
708
              overflow = true;
709
          }
710
          break;
711
        case complain_overflow_unsigned:
712
          {
713
            /* Assumes two's complement.  This expression avoids
714
               overflow if howto->bitsize is the number of bits in
715
               bfd_vma.  */
716
            bfd_vma reloc_unsigned_max =
717
            (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
718
 
719
            if (check > reloc_unsigned_max)
720
              overflow = true;
721
          }
722
          break;
723
        case complain_overflow_bitfield:
724
          {
725
            /* Assumes two's complement.  This expression avoids
726
               overflow if howto->bitsize is the number of bits in
727
               bfd_vma.  */
728
            bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
729
 
730
            if ((check & ~reloc_bits) != 0
731
                && (((bfd_vma) signed_check & ~reloc_bits)
732
                    != (-1 & ~reloc_bits)))
733
              overflow = true;
734
          }
735
          break;
736
        default:
737
          abort ();
738
        }
739
    }
740
 
741
  /* Put RELOCATION in the right bits.  */
742
  relocation >>= (bfd_vma) howto->rightshift;
743
  relocation <<= (bfd_vma) howto->bitpos;
744
 
745
  /* Add RELOCATION to the right bits of X.  */
746
  x = ((x & ~howto->dst_mask)
747
       | (((x & howto->src_mask) + relocation) & howto->dst_mask));
748
 
749
  /* Put the relocated value back in the object file.  */
750
  switch (size)
751
    {
752
    default:
753
    case 0:
754
      abort ();
755
    case 1:
756
    case 2:
757
    case 4:
758
#ifdef BFD64
759
    case 8:
760
#endif
761
      put_data(x, location, 0, size);
762
      break;
763
    }
764
 
765
  return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
766
}
767
 
768
bfd_reloc_status_type
769
_bfd_ns32k_reloc_disp (abfd, reloc_entry, symbol, data, input_section,
770
                       output_bfd, error_message)
771
     bfd *abfd;
772
     arelent *reloc_entry;
773
     struct symbol_cache_entry *symbol;
774
     PTR data;
775
     asection *input_section;
776
     bfd *output_bfd;
777
     char **error_message;
778
{
779
  return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
780
                         output_bfd, error_message,
781
                         _bfd_ns32k_get_displacement,
782
                         _bfd_ns32k_put_displacement);
783
}
784
 
785
bfd_reloc_status_type
786
_bfd_ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section,
787
                      output_bfd, error_message)
788
     bfd *abfd;
789
     arelent *reloc_entry;
790
     struct symbol_cache_entry *symbol;
791
     PTR data;
792
     asection *input_section;
793
     bfd *output_bfd;
794
     char **error_message;
795
{
796
  return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
797
                         output_bfd, error_message, _bfd_ns32k_get_immediate,
798
                         _bfd_ns32k_put_immediate);
799
}
800
 
801
bfd_reloc_status_type
802
_bfd_ns32k_final_link_relocate (howto, input_bfd, input_section, contents,
803
                                address, value, addend)
804
     reloc_howto_type *howto;
805
     bfd *input_bfd;
806
     asection *input_section;
807
     bfd_byte *contents;
808
     bfd_vma address;
809
     bfd_vma value;
810
     bfd_vma addend;
811
{
812
  bfd_vma relocation;
813
 
814
  /* Sanity check the address.  */
815
  if (address > input_section->_cooked_size)
816
    return bfd_reloc_outofrange;
817
 
818
  /* This function assumes that we are dealing with a basic relocation
819
     against a symbol.  We want to compute the value of the symbol to
820
     relocate to.  This is just VALUE, the value of the symbol, plus
821
     ADDEND, any addend associated with the reloc.  */
822
  relocation = value + addend;
823
 
824
  /* If the relocation is PC relative, we want to set RELOCATION to
825
     the distance between the symbol (currently in RELOCATION) and the
826
     location we are relocating.  Some targets (e.g., i386-aout)
827
     arrange for the contents of the section to be the negative of the
828
     offset of the location within the section; for such targets
829
     pcrel_offset is false.  Other targets (e.g., m88kbcs or ELF)
830
     simply leave the contents of the section as zero; for such
831
     targets pcrel_offset is true.  If pcrel_offset is false we do not
832
     need to subtract out the offset of the location within the
833
     section (which is just ADDRESS).  */
834
  if (howto->pc_relative)
835
    {
836
      relocation -= (input_section->output_section->vma
837
                     + input_section->output_offset);
838
      if (howto->pcrel_offset)
839
        relocation -= address;
840
    }
841
 
842
  return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation,
843
                                       contents + address);
844
}

powered by: WebSVN 2.1.0

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