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