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