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