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