Update copyright notices
[deliverable/binutils-gdb.git] / bfd / cpu-ns32k.c
CommitLineData
252b5132 1/* BFD support for the ns32k architecture.
7898deda
NC
2 Copyright 1990, 1991, 1994, 1995, 1998, 2000
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
39static long
40ns32k_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
50long
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
80int
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
119long
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
141int
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 */
168static bfd_reloc_status_type
169do_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;
5f771d47 177 char **error_message ATTRIBUTE_UNUSED;
6e301b2b
KH
178 long (*get_data) ();
179 int (*put_data) ();
252b5132
RH
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
252b5132
RH
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
252b5132
RH
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?? */
9bd09e22 292 if (abfd->xvec->flavour == bfd_target_coff_flavour)
252b5132
RH
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
299However, Ian wrote the following, regarding removing the line below,
300which explains why it is still enabled: --djm
301
302If you put a patch like that into BFD you need to check all the COFF
303linkers. I am fairly certain that patch will break coff-i386 (e.g.,
304SCO); see coff_i386_reloc in coff-i386.c where I worked around the
305problem in a different way. There may very well be a reason that the
306code works as it does.
307
308Hmmm. The first obvious point is that bfd_perform_relocation should
309not have any tests that depend upon the flavour. It's seem like
310entirely the wrong place for such a thing. The second obvious point
311is that the current code ignores the reloc addend when producing
312relocateable output for COFF. That's peculiar. In fact, I really
313have no idea what the point of the line you want to remove is.
314
315A typical COFF reloc subtracts the old value of the symbol and adds in
316the new value to the location in the object file (if it's a pc
317relative reloc it adds the difference between the symbol value and the
318location). When relocating we need to preserve that property.
319
320BFD handles this by setting the addend to the negative of the old
321value of the symbol. Unfortunately it handles common symbols in a
322non-standard way (it doesn't subtract the old value) but that's a
323different story (we can't change it without losing backward
324compatibility with old object files) (coff-i386 does subtract the old
325value, to be compatible with existing coff-i386 targets, like SCO).
326
327So everything works fine when not producing relocateable output. When
328we are producing relocateable output, logically we should do exactly
329what we do when not producing relocateable output. Therefore, your
330patch is correct. In fact, it should probably always just set
331reloc_entry->addend to 0 for all cases, since it is, in fact, going to
332add the value into the object file. This won't hurt the COFF code,
333which doesn't use the addend; I'm not sure what it will do to other
334formats (the thing to check for would be whether any formats both use
335the addend and set partial_inplace).
336
337When I wanted to make coff-i386 produce relocateable output, I ran
338into the problem that you are running into: I wanted to remove that
339line. Rather than risk it, I made the coff-i386 relocs use a special
340function; it's coff_i386_reloc in coff-i386.c. The function
341specifically adds the addend field into the object file, knowing that
342bfd_perform_relocation is not going to. If you remove that line, then
343coff-i386.c will wind up adding the addend field in twice. It's
344trivial to fix; it just needs to be done.
345
346The problem with removing the line is just that it may break some
347working code. With BFD it's hard to be sure of anything. The right
348way to deal with this is simply to build and test at least all the
349supported COFF targets. It should be straightforward if time and disk
350space 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
593bfd_reloc_status_type
594_bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
595 get_data, put_data)
596 reloc_howto_type *howto;
5f771d47 597 bfd *input_bfd ATTRIBUTE_UNUSED;
252b5132
RH
598 bfd_vma relocation;
599 bfd_byte *location;
6e301b2b
KH
600 long (*get_data) ();
601 int (*put_data) ();
252b5132
RH
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
768bfd_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
785bfd_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
801bfd_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}
This page took 0.1029 seconds and 4 git commands to generate.