Changeset 609 for branches/GNU/src/binutils/bfd/cpu-ns32k.c
- Timestamp:
- Aug 16, 2003, 6:59:22 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GNU/src/binutils/bfd/cpu-ns32k.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.1.1.2
r608 r609 1 1 /* BFD support for the ns32k architecture. 2 Copyright 1990, 1991, 1994, 1995, 1998, 2000 2 Copyright 1990, 1991, 1994, 1995, 1998, 2000, 2001, 2002 3 3 Free Software Foundation, Inc. 4 4 Almost totally rewritten by Ian Dall from initial work 5 5 by Andrew Cagney. 6 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 modify10 it under the terms of the GNU General Public License as published by11 the Free Software Foundation; either version 2 of the License, or12 (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 of16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the17 GNU General Public License for more details.18 19 You should have received a copy of the GNU General Public License20 along with this program; if not, write to the Free Software21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */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 22 23 23 #include "bfd.h" … … 31 31 static const bfd_arch_info_type arch_info_struct[] = 32 32 { 33 N(32532,"ns32k:32532", true, 0), /* the word ns32k will match this too*/33 N(32532,"ns32k:32532",TRUE, 0), /* The word ns32k will match this too. */ 34 34 }; 35 35 36 36 const bfd_arch_info_type bfd_ns32k_arch = 37 N(32032,"ns32k:32032",false, &arch_info_struct[0]); 38 39 static long 40 ns32k_sign_extend(value, bits) 41 int value; 42 int bits; 43 { 44 value = value & ((1 << bits) - 1); 45 return (value & (1 << (bits-1)) 46 ? value | (~((1 << bits) - 1)) 47 : value); 48 } 49 50 long 51 _bfd_ns32k_get_displacement(buffer, offset, size) 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 symbol_cache_entry *, 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) 52 47 bfd_byte *buffer; 53 long offset; 54 long size; 55 { 56 long value; 57 buffer += offset; 48 int size; 49 { 50 bfd_signed_vma value; 51 58 52 switch (size) 59 53 { 60 54 case 1: 61 value = ns32k_sign_extend (*buffer, 7); 62 break; 55 value = ((*buffer & 0x7f) ^ 0x40) - 0x40; 56 break; 57 63 58 case 2: 64 value = ns32k_sign_extend(*buffer++, 6);59 value = ((*buffer++ & 0x3f) ^ 0x20) - 0x20; 65 60 value = (value << 8) | (0xff & *buffer); 66 61 break; 62 67 63 case 4: 68 value = ns32k_sign_extend(*buffer++, 6);64 value = ((*buffer++ & 0x3f) ^ 0x20) - 0x20; 69 65 value = (value << 8) | (0xff & *buffer++); 70 66 value = (value << 8) | (0xff & *buffer++); 71 67 value = (value << 8) | (0xff & *buffer); 72 68 break; 69 73 70 default: 74 71 abort (); 75 72 return 0; 76 73 } 74 77 75 return value; 78 76 } 79 77 80 int 81 _bfd_ns32k_put_displacement (value, buffer, offset, size)82 longvalue;78 void 79 _bfd_ns32k_put_displacement (value, buffer, size) 80 bfd_vma value; 83 81 bfd_byte *buffer; 84 long offset; 85 long size; 86 { 87 buffer += offset; 82 int size; 83 { 88 84 switch (size) 89 85 { 90 86 case 1: 91 if (value < -64 || value > 63) 92 return -1; 93 value&=0x7f; 94 *buffer++=value; 95 break; 87 value &= 0x7f; 88 *buffer++ = value; 89 break; 90 96 91 case 2: 97 if (value < -8192 || value > 8191) 98 return -1; 99 value&=0x3fff; 100 value|=0x8000; 101 *buffer++=(value>>8); 102 *buffer++=value; 103 break; 92 value &= 0x3fff; 93 value |= 0x8000; 94 *buffer++ = (value >> 8); 95 *buffer++ = value; 96 break; 97 104 98 case 4: 105 if (value < -0x1f000000 || value >= 0x20000000) 106 return -1; 107 value|=0xc0000000; 108 *buffer++=(value>>24); 109 *buffer++=(value>>16); 110 *buffer++=(value>>8); 111 *buffer++=value; 112 break; 113 default: 114 return -1; 99 value |= (bfd_vma) 0xc0000000; 100 *buffer++ = (value >> 24); 101 *buffer++ = (value >> 16); 102 *buffer++ = (value >> 8); 103 *buffer++ = value; 104 break; 115 105 } 116 return 0;106 return; 117 107 } 118 108 119 long 120 _bfd_ns32k_get_immediate (buffer, offset,size)109 bfd_vma 110 _bfd_ns32k_get_immediate (buffer, size) 121 111 bfd_byte *buffer; 122 long offset; 123 long size; 124 { 125 long value = 0; 126 buffer += offset; 112 int size; 113 { 114 bfd_vma value = 0; 115 127 116 switch (size) 128 117 { 129 118 case 4: 130 119 value = (value << 8) | (*buffer++ & 0xff); 131 case 3:132 120 value = (value << 8) | (*buffer++ & 0xff); 133 121 case 2: … … 135 123 case 1: 136 124 value = (value << 8) | (*buffer++ & 0xff); 125 break; 126 default: 127 abort (); 137 128 } 138 129 return value; 139 130 } 140 131 141 int 142 _bfd_ns32k_put_immediate (value, buffer, offset,size)143 longvalue;132 void 133 _bfd_ns32k_put_immediate (value, buffer, size) 134 bfd_vma value; 144 135 bfd_byte *buffer; 145 long offset; 146 long size; 147 { 148 buffer += offset + size - 1; 136 int size; 137 { 138 buffer += size - 1; 149 139 switch (size) 150 140 { 151 141 case 4: 152 142 *buffer-- = (value & 0xff); value >>= 8; 153 case 3:154 143 *buffer-- = (value & 0xff); value >>= 8; 155 144 case 2: … … 158 147 *buffer-- = (value & 0xff); value >>= 8; 159 148 } 160 return 0;161 149 } 162 150 163 151 /* This is just like the standard perform_relocation except we 164 * use get_data and put_data which know about the ns32k165 * storage methods.166 * This is probably a lot more complicated than it needs to be!167 */ 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 168 156 static bfd_reloc_status_type 169 157 do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, … … 176 164 bfd *output_bfd; 177 165 char **error_message ATTRIBUTE_UNUSED; 178 long (*get_data) ();179 int (*put_data) ();166 bfd_vma (*get_data) PARAMS ((bfd_byte *, int)); 167 void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int)); 180 168 { 181 169 int overflow = 0; … … 186 174 reloc_howto_type *howto = reloc_entry->howto; 187 175 asection *reloc_target_output_section; 176 bfd_byte *location; 188 177 189 178 if ((symbol->section == &bfd_abs_section) … … 218 207 219 208 /* Convert input-section-relative symbol value to absolute. */ 220 if (output_bfd && howto->partial_inplace == false)209 if (output_bfd != NULL && ! howto->partial_inplace) 221 210 output_base = 0; 222 211 else … … 231 220 symbol we are relocating against, plus any addend. */ 232 221 233 if (howto->pc_relative == true)222 if (howto->pc_relative) 234 223 { 235 224 /* This is a PC relative relocation. We want to set RELOCATION … … 244 233 the addend to be the negative of the position of the location 245 234 within the section; for example, i386-aout does this. For 246 i386-aout, pcrel_offset is false. Some other targets do not235 i386-aout, pcrel_offset is FALSE. Some other targets do not 247 236 include the position of the location; for example, m88kbcs, 248 or ELF. For those targets, pcrel_offset is true.237 or ELF. For those targets, pcrel_offset is TRUE. 249 238 250 239 If we are producing relocateable output, then we must ensure 251 240 that this reloc will be correctly computed when the final 252 relocation is done. If pcrel_offset is falsewe want to wind241 relocation is done. If pcrel_offset is FALSE we want to wind 253 242 up with the negative of the location within the section, 254 243 which means we must adjust the existing addend by the change 255 in the location within the section. If pcrel_offset is true244 in the location within the section. If pcrel_offset is TRUE 256 245 we do not want to adjust the existing addend at all. 257 246 … … 260 249 actually does. I don't want to change it, because it seems 261 250 far too likely that something will break. */ 262 263 251 relocation -= 264 252 input_section->output_section->vma + input_section->output_offset; 265 253 266 if (howto->pcrel_offset == true)254 if (howto->pcrel_offset) 267 255 relocation -= reloc_entry->address; 268 256 } … … 270 258 if (output_bfd != (bfd *) NULL) 271 259 { 272 if ( howto->partial_inplace == false)260 if (! howto->partial_inplace) 273 261 { 274 262 /* This is a partial relocation, and we want to apply the relocation … … 297 285 fixes that problem; see PR 2953. 298 286 299 However, Ian wrote the following, regarding removing the line below, 300 which explains why it is still enabled: --djm 301 302 If you put a patch like that into BFD you need to check all the COFF 303 linkers. I am fairly certain that patch will break coff-i386 (e.g., 304 SCO); see coff_i386_reloc in coff-i386.c where I worked around the 305 problem in a different way. There may very well be a reason that the 306 code works as it does. 307 308 Hmmm. The first obvious point is that bfd_perform_relocation should 309 not have any tests that depend upon the flavour. It's seem like 310 entirely the wrong place for such a thing. The second obvious point 311 is that the current code ignores the reloc addend when producing 312 relocateable output for COFF. That's peculiar. In fact, I really 313 have no idea what the point of the line you want to remove is. 314 315 A typical COFF reloc subtracts the old value of the symbol and adds in 316 the new value to the location in the object file (if it's a pc 317 relative reloc it adds the difference between the symbol value and the 318 location). When relocating we need to preserve that property. 319 320 BFD handles this by setting the addend to the negative of the old 321 value of the symbol. Unfortunately it handles common symbols in a 322 non-standard way (it doesn't subtract the old value) but that's a 323 different story (we can't change it without losing backward 324 compatibility with old object files) (coff-i386 does subtract the old 325 value, to be compatible with existing coff-i386 targets, like SCO). 326 327 So everything works fine when not producing relocateable output. When 328 we are producing relocateable output, logically we should do exactly 329 what we do when not producing relocateable output. Therefore, your 330 patch is correct. In fact, it should probably always just set 331 reloc_entry->addend to 0 for all cases, since it is, in fact, going to 332 add the value into the object file. This won't hurt the COFF code, 333 which doesn't use the addend; I'm not sure what it will do to other 334 formats (the thing to check for would be whether any formats both use 335 the addend and set partial_inplace). 336 337 When I wanted to make coff-i386 produce relocateable output, I ran 338 into the problem that you are running into: I wanted to remove that 339 line. Rather than risk it, I made the coff-i386 relocs use a special 340 function; it's coff_i386_reloc in coff-i386.c. The function 341 specifically adds the addend field into the object file, knowing that 342 bfd_perform_relocation is not going to. If you remove that line, then 343 coff-i386.c will wind up adding the addend field in twice. It's 344 trivial to fix; it just needs to be done. 345 346 The problem with removing the line is just that it may break some 347 working code. With BFD it's hard to be sure of anything. The right 348 way to deal with this is simply to build and test at least all the 349 supported COFF targets. It should be straightforward if time and disk 350 space consuming. For each target: 351 1) build the linker 352 2) generate some executable, and link it using -r (I would 353 probably use paranoia.o and link against newlib/libc.a, which 354 for all the supported targets would be available in 355 /usr/cygnus/progressive/H-host/target/lib/libc.a). 356 3) make the change to reloc.c 357 4) rebuild the linker 358 5) repeat step 2 359 6) if the resulting object files are the same, you have at least 360 made it no worse 361 7) if they are different you have to figure out which version is 362 right 363 */ 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 relocateable 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 relocateable 319 output. When we are producing relocateable output, logically 320 we should do exactly what we do when not producing 321 relocateable 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 relocateable 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. */ 364 357 relocation -= reloc_entry->addend; 365 358 #endif … … 434 427 435 428 if (((bfd_vma) check & ~reloc_bits) != 0 436 && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) 429 && (((bfd_vma) check & ~reloc_bits) 430 != (-(bfd_vma) 1 & ~reloc_bits))) 437 431 { 438 432 /* The above right shift is incorrect for a signed … … 445 439 & ~((bfd_vma) - 1 446 440 >> (howto->rightshift - howto->bitpos))); 447 if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) 441 if (((bfd_vma) check & ~reloc_bits) 442 != (-(bfd_vma) 1 & ~reloc_bits)) 448 443 flag = bfd_reloc_overflow; 449 444 } … … 458 453 } 459 454 460 /* 461 Either we are relocating all the way, or we don't want to apply 462 the relocation to the reloc entry (probably because there isn't 463 any room in the output format to describe addends to relocs) 464 */ 455 /* Either we are relocating all the way, or we don't want to apply 456 the relocation to the reloc entry (probably because there isn't 457 any room in the output format to describe addends to relocs). */ 465 458 466 459 /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler … … 489 482 relocation >>= (bfd_vma) howto->rightshift; 490 483 491 /* Shift everything up to where it's going to be used */ 492 484 /* Shift everything up to where it's going to be used. */ 493 485 relocation <<= (bfd_vma) howto->bitpos; 494 486 495 /* Wait for the day when all have the mask in them */487 /* Wait for the day when all have the mask in them. */ 496 488 497 489 /* What we do: … … 523 515 or A A A A A 524 516 ----------------------- 525 R R R R R R R R R R put into bfd_put<size> 526 */ 517 R R R R R R R R R R put into bfd_put<size>. */ 527 518 528 519 #define DOIT(x) \ 529 520 x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) 530 521 522 location = (bfd_byte *) data + addr; 531 523 switch (howto->size) 532 524 { 533 525 case 0: 534 526 { 535 char x = get_data (data, addr, 1);527 bfd_vma x = get_data (location, 1); 536 528 DOIT (x); 537 overflow = put_data(x, data, addr, 1);529 put_data ((bfd_vma) x, location, 1); 538 530 } 539 531 break; … … 542 534 if (relocation) 543 535 { 544 short x = get_data (data, addr, 2);536 bfd_vma x = get_data (location, 2); 545 537 DOIT (x); 546 overflow = put_data(x, (unsigned char *) data, addr, 2);538 put_data ((bfd_vma) x, location, 2); 547 539 } 548 540 break; … … 550 542 if (relocation) 551 543 { 552 long x = get_data (data, addr, 4);544 bfd_vma x = get_data (location, 4); 553 545 DOIT (x); 554 overflow = put_data(x, data, addr, 4);546 put_data ((bfd_vma) x, location, 4); 555 547 } 556 548 break; 557 549 case -2: 558 550 { 559 long x = get_data(data, addr, 4);551 bfd_vma x = get_data (location, 4); 560 552 relocation = -relocation; 561 553 DOIT(x); 562 overflow = put_data(x, data , addr, 4);554 put_data ((bfd_vma) x, location, 4); 563 555 } 564 556 break; 565 557 566 558 case 3: 567 /* Do nothing */559 /* Do nothing. */ 568 560 break; 569 561 … … 572 564 if (relocation) 573 565 { 574 bfd_vma x = get_data ( data, addr, 8);566 bfd_vma x = get_data (location, 8); 575 567 DOIT (x); 576 overflow = put_data(x, data, addr, 8);568 put_data (x, location, 8); 577 569 } 578 570 #else … … 592 584 593 585 bfd_reloc_status_type 594 _bfd_do_ns32k_reloc_contents ( 586 _bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation, location, 595 587 get_data, put_data) 596 588 reloc_howto_type *howto; … … 598 590 bfd_vma relocation; 599 591 bfd_byte *location; 600 long (*get_data) ();601 int (*put_data) ();592 bfd_vma (*get_data) PARAMS ((bfd_byte *, int)); 593 void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int)); 602 594 { 603 595 int size; 604 596 bfd_vma x; 605 b oolean overflow;597 bfd_boolean overflow; 606 598 607 599 /* If the size is negative, negate RELOCATION. This isn't very … … 623 615 case 8: 624 616 #endif 625 x = get_data (location, 0,size);617 x = get_data (location, size); 626 618 break; 627 619 } … … 631 623 operation, which would be tedious, or we must do the computations 632 624 in a type larger than bfd_vma, which would be inefficient. */ 633 overflow = false;625 overflow = FALSE; 634 626 if (howto->complain_on_overflow != complain_overflow_dont) 635 627 { … … 706 698 if (signed_check > reloc_signed_max 707 699 || signed_check < reloc_signed_min) 708 overflow = true;700 overflow = TRUE; 709 701 } 710 702 break; … … 718 710 719 711 if (check > reloc_unsigned_max) 720 overflow = true;712 overflow = TRUE; 721 713 } 722 714 break; … … 730 722 if ((check & ~reloc_bits) != 0 731 723 && (((bfd_vma) signed_check & ~reloc_bits) 732 != (- 1 & ~reloc_bits)))733 overflow = true;724 != (-(bfd_vma) 1 & ~reloc_bits))) 725 overflow = TRUE; 734 726 } 735 727 break; … … 759 751 case 8: 760 752 #endif 761 put_data (x, location, 0, size);753 put_data (x, location, size); 762 754 break; 763 755 } … … 827 819 arrange for the contents of the section to be the negative of the 828 820 offset of the location within the section; for such targets 829 pcrel_offset is false. Other targets (e.g., m88kbcs or ELF)821 pcrel_offset is FALSE. Other targets (e.g., m88kbcs or ELF) 830 822 simply leave the contents of the section as zero; for such 831 targets pcrel_offset is true. If pcrel_offset is falsewe do not823 targets pcrel_offset is TRUE. If pcrel_offset is FALSE we do not 832 824 need to subtract out the offset of the location within the 833 825 section (which is just ADDRESS). */ -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.