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