| OLD | NEW |
| 1 /* BFD support for the ns32k architecture. | 1 /* BFD support for the ns32k architecture. |
| 2 Copyright 1990, 1991, 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, | 2 Copyright 1990, 1991, 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, |
| 3 2004, 2005, 2007 Free Software Foundation, Inc. | 3 2004, 2005, 2007, 2012 Free Software Foundation, Inc. |
| 4 Almost totally rewritten by Ian Dall from initial work | 4 Almost totally rewritten by Ian Dall from initial work |
| 5 by Andrew Cagney. | 5 by Andrew Cagney. |
| 6 | 6 |
| 7 This file is part of BFD, the Binary File Descriptor library. | 7 This file is part of BFD, the Binary File Descriptor library. |
| 8 | 8 |
| 9 This program is free software; you can redistribute it and/or modify | 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 | 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 | 11 the Free Software Foundation; either version 3 of the License, or |
| 12 (at your option) any later version. | 12 (at your option) any later version. |
| 13 | 13 |
| 14 This program is distributed in the hope that it will be useful, | 14 This program is distributed in the hope that it will be useful, |
| 15 but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 17 GNU General Public License for more details. | 17 GNU General Public License for more details. |
| 18 | 18 |
| 19 You should have received a copy of the GNU General Public License | 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 | 20 along with this program; if not, write to the Free Software |
| 21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | 21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
| 22 MA 02110-1301, USA. */ | 22 MA 02110-1301, USA. */ |
| 23 | 23 |
| 24 #include "sysdep.h" | 24 #include "sysdep.h" |
| 25 #include "bfd.h" | 25 #include "bfd.h" |
| 26 #include "libbfd.h" | 26 #include "libbfd.h" |
| 27 #include "ns32k.h" | 27 #include "ns32k.h" |
| 28 | 28 |
| 29 #define N(machine, printable, d, next) \ | 29 #define N(machine, printable, d, next) \ |
| 30 { 32, 32, 8, bfd_arch_ns32k, machine, "ns32k",printable,3,d,bfd_default_compati
ble,bfd_default_scan, next, } | 30 { 32, 32, 8, bfd_arch_ns32k, machine, "ns32k",printable,3,d, \ |
| 31 bfd_default_compatible,bfd_default_scan,bfd_arch_default_fill,next, } |
| 31 | 32 |
| 32 static const bfd_arch_info_type arch_info_struct[] = | 33 static const bfd_arch_info_type arch_info_struct[] = |
| 33 { | 34 { |
| 34 N(32532,"ns32k:32532",TRUE, 0), /* The word ns32k will match this too. */ | 35 N(32532,"ns32k:32532",TRUE, 0), /* The word ns32k will match this too. */ |
| 35 }; | 36 }; |
| 36 | 37 |
| 37 const bfd_arch_info_type bfd_ns32k_arch = | 38 const bfd_arch_info_type bfd_ns32k_arch = |
| 38 N(32032,"ns32k:32032",FALSE, &arch_info_struct[0]); | 39 N(32032,"ns32k:32032",FALSE, &arch_info_struct[0]); |
| 39 | 40 |
| 40 static 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 | |
| 46 bfd_vma | 41 bfd_vma |
| 47 _bfd_ns32k_get_displacement (buffer, size) | 42 _bfd_ns32k_get_displacement (bfd_byte *buffer, int size) |
| 48 bfd_byte *buffer; | |
| 49 int size; | |
| 50 { | 43 { |
| 51 bfd_signed_vma value; | 44 bfd_signed_vma value; |
| 52 | 45 |
| 53 switch (size) | 46 switch (size) |
| 54 { | 47 { |
| 55 case 1: | 48 case 1: |
| 56 value = ((*buffer & 0x7f) ^ 0x40) - 0x40; | 49 value = ((*buffer & 0x7f) ^ 0x40) - 0x40; |
| 57 break; | 50 break; |
| 58 | 51 |
| 59 case 2: | 52 case 2: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 70 | 63 |
| 71 default: | 64 default: |
| 72 abort (); | 65 abort (); |
| 73 return 0; | 66 return 0; |
| 74 } | 67 } |
| 75 | 68 |
| 76 return value; | 69 return value; |
| 77 } | 70 } |
| 78 | 71 |
| 79 void | 72 void |
| 80 _bfd_ns32k_put_displacement (value, buffer, size) | 73 _bfd_ns32k_put_displacement (bfd_vma value, bfd_byte *buffer, int size) |
| 81 bfd_vma value; | |
| 82 bfd_byte *buffer; | |
| 83 int size; | |
| 84 { | 74 { |
| 85 switch (size) | 75 switch (size) |
| 86 { | 76 { |
| 87 case 1: | 77 case 1: |
| 88 value &= 0x7f; | 78 value &= 0x7f; |
| 89 *buffer++ = value; | 79 *buffer++ = value; |
| 90 break; | 80 break; |
| 91 | 81 |
| 92 case 2: | 82 case 2: |
| 93 value &= 0x3fff; | 83 value &= 0x3fff; |
| 94 value |= 0x8000; | 84 value |= 0x8000; |
| 95 *buffer++ = (value >> 8); | 85 *buffer++ = (value >> 8); |
| 96 *buffer++ = value; | 86 *buffer++ = value; |
| 97 break; | 87 break; |
| 98 | 88 |
| 99 case 4: | 89 case 4: |
| 100 value |= (bfd_vma) 0xc0000000; | 90 value |= (bfd_vma) 0xc0000000; |
| 101 *buffer++ = (value >> 24); | 91 *buffer++ = (value >> 24); |
| 102 *buffer++ = (value >> 16); | 92 *buffer++ = (value >> 16); |
| 103 *buffer++ = (value >> 8); | 93 *buffer++ = (value >> 8); |
| 104 *buffer++ = value; | 94 *buffer++ = value; |
| 105 break; | 95 break; |
| 106 } | 96 } |
| 107 return; | 97 return; |
| 108 } | 98 } |
| 109 | 99 |
| 110 bfd_vma | 100 bfd_vma |
| 111 _bfd_ns32k_get_immediate (buffer, size) | 101 _bfd_ns32k_get_immediate (bfd_byte *buffer, int size) |
| 112 bfd_byte *buffer; | |
| 113 int size; | |
| 114 { | 102 { |
| 115 bfd_vma value = 0; | 103 bfd_vma value = 0; |
| 116 | 104 |
| 117 switch (size) | 105 switch (size) |
| 118 { | 106 { |
| 119 case 4: | 107 case 4: |
| 120 value = (value << 8) | (*buffer++ & 0xff); | 108 value = (value << 8) | (*buffer++ & 0xff); |
| 121 value = (value << 8) | (*buffer++ & 0xff); | 109 value = (value << 8) | (*buffer++ & 0xff); |
| 122 case 2: | 110 case 2: |
| 123 value = (value << 8) | (*buffer++ & 0xff); | 111 value = (value << 8) | (*buffer++ & 0xff); |
| 124 case 1: | 112 case 1: |
| 125 value = (value << 8) | (*buffer++ & 0xff); | 113 value = (value << 8) | (*buffer++ & 0xff); |
| 126 break; | 114 break; |
| 127 default: | 115 default: |
| 128 abort (); | 116 abort (); |
| 129 } | 117 } |
| 130 return value; | 118 return value; |
| 131 } | 119 } |
| 132 | 120 |
| 133 void | 121 void |
| 134 _bfd_ns32k_put_immediate (value, buffer, size) | 122 _bfd_ns32k_put_immediate (bfd_vma value, bfd_byte *buffer, int size) |
| 135 bfd_vma value; | |
| 136 bfd_byte *buffer; | |
| 137 int size; | |
| 138 { | 123 { |
| 139 buffer += size - 1; | 124 buffer += size - 1; |
| 140 switch (size) | 125 switch (size) |
| 141 { | 126 { |
| 142 case 4: | 127 case 4: |
| 143 *buffer-- = (value & 0xff); value >>= 8; | 128 *buffer-- = (value & 0xff); value >>= 8; |
| 144 *buffer-- = (value & 0xff); value >>= 8; | 129 *buffer-- = (value & 0xff); value >>= 8; |
| 145 case 2: | 130 case 2: |
| 146 *buffer-- = (value & 0xff); value >>= 8; | 131 *buffer-- = (value & 0xff); value >>= 8; |
| 147 case 1: | 132 case 1: |
| 148 *buffer-- = (value & 0xff); value >>= 8; | 133 *buffer-- = (value & 0xff); value >>= 8; |
| 149 } | 134 } |
| 150 } | 135 } |
| 151 | 136 |
| 152 /* This is just like the standard perform_relocation except we | 137 /* This is just like the standard perform_relocation except we |
| 153 use get_data and put_data which know about the ns32k storage | 138 use get_data and put_data which know about the ns32k storage |
| 154 methods. This is probably a lot more complicated than it | 139 methods. This is probably a lot more complicated than it |
| 155 needs to be! */ | 140 needs to be! */ |
| 156 | 141 |
| 157 static bfd_reloc_status_type | 142 static bfd_reloc_status_type |
| 158 do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, | 143 do_ns32k_reloc (bfd * abfd, |
| 159 » » error_message, get_data, put_data) | 144 » » arelent * reloc_entry, |
| 160 bfd *abfd; | 145 » » struct bfd_symbol * symbol, |
| 161 arelent *reloc_entry; | 146 » » void * data, |
| 162 struct bfd_symbol *symbol; | 147 » » asection * input_section, |
| 163 PTR data; | 148 » » bfd * output_bfd, |
| 164 asection *input_section; | 149 » » char ** error_message ATTRIBUTE_UNUSED, |
| 165 bfd *output_bfd; | 150 » » bfd_vma (* get_data) (bfd_byte *, int), |
| 166 char **error_message ATTRIBUTE_UNUSED; | 151 » » void (* put_data) (bfd_vma, bfd_byte *, int)) |
| 167 bfd_vma (*get_data) PARAMS ((bfd_byte *, int)); | |
| 168 void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int)); | |
| 169 { | 152 { |
| 170 int overflow = 0; | 153 int overflow = 0; |
| 171 bfd_vma relocation; | 154 bfd_vma relocation; |
| 172 bfd_reloc_status_type flag = bfd_reloc_ok; | 155 bfd_reloc_status_type flag = bfd_reloc_ok; |
| 173 bfd_size_type addr = reloc_entry->address; | 156 bfd_size_type addr = reloc_entry->address; |
| 174 bfd_vma output_base = 0; | 157 bfd_vma output_base = 0; |
| 175 reloc_howto_type *howto = reloc_entry->howto; | 158 reloc_howto_type *howto = reloc_entry->howto; |
| 176 asection *reloc_target_output_section; | 159 asection *reloc_target_output_section; |
| 177 bfd_byte *location; | 160 bfd_byte *location; |
| 178 | 161 |
| 179 if ((symbol->section == &bfd_abs_section) | 162 if (bfd_is_abs_section (symbol->section) |
| 180 && output_bfd != (bfd *) NULL) | 163 && output_bfd != (bfd *) NULL) |
| 181 { | 164 { |
| 182 reloc_entry->address += input_section->output_offset; | 165 reloc_entry->address += input_section->output_offset; |
| 183 return bfd_reloc_ok; | 166 return bfd_reloc_ok; |
| 184 } | 167 } |
| 185 | 168 |
| 186 /* If we are not producing relocatable output, return an error if | 169 /* If we are not producing relocatable output, return an error if |
| 187 the symbol is not defined. An undefined weak symbol is | 170 the symbol is not defined. An undefined weak symbol is |
| 188 considered to have a value of zero (SVR4 ABI, p. 4-27). */ | 171 considered to have a value of zero (SVR4 ABI, p. 4-27). */ |
| 189 if (symbol->section == &bfd_und_section | 172 if (bfd_is_und_section (symbol->section) |
| 190 && (symbol->flags & BSF_WEAK) == 0 | 173 && (symbol->flags & BSF_WEAK) == 0 |
| 191 && output_bfd == (bfd *) NULL) | 174 && output_bfd == (bfd *) NULL) |
| 192 flag = bfd_reloc_undefined; | 175 flag = bfd_reloc_undefined; |
| 193 | 176 |
| 194 /* Is the address of the relocation really within the section? */ | 177 /* Is the address of the relocation really within the section? */ |
| 195 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) | 178 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) |
| 196 return bfd_reloc_outofrange; | 179 return bfd_reloc_outofrange; |
| 197 | 180 |
| 198 /* Work out which section the relocation is targeted at and the | 181 /* Work out which section the relocation is targeted at and the |
| 199 initial relocation command value. */ | 182 initial relocation command value. */ |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 } | 558 } |
| 576 if ((howto->complain_on_overflow != complain_overflow_dont) && overflow) | 559 if ((howto->complain_on_overflow != complain_overflow_dont) && overflow) |
| 577 return bfd_reloc_overflow; | 560 return bfd_reloc_overflow; |
| 578 | 561 |
| 579 return flag; | 562 return flag; |
| 580 } | 563 } |
| 581 | 564 |
| 582 /* Relocate a given location using a given value and howto. */ | 565 /* Relocate a given location using a given value and howto. */ |
| 583 | 566 |
| 584 bfd_reloc_status_type | 567 bfd_reloc_status_type |
| 585 _bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation, location, | 568 _bfd_do_ns32k_reloc_contents (reloc_howto_type *howto, |
| 586 » » » get_data, put_data) | 569 » » » bfd *input_bfd ATTRIBUTE_UNUSED, |
| 587 reloc_howto_type *howto; | 570 » » » bfd_vma relocation, |
| 588 bfd *input_bfd ATTRIBUTE_UNUSED; | 571 » » » bfd_byte *location, |
| 589 bfd_vma relocation; | 572 » » » bfd_vma (*get_data) (bfd_byte *, int), |
| 590 bfd_byte *location; | 573 » » » void (*put_data) (bfd_vma, bfd_byte *, int)) |
| 591 bfd_vma (*get_data) PARAMS ((bfd_byte *, int)); | |
| 592 void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int)); | |
| 593 { | 574 { |
| 594 int size; | 575 int size; |
| 595 bfd_vma x; | 576 bfd_vma x; |
| 596 bfd_boolean overflow; | 577 bfd_boolean overflow; |
| 597 | 578 |
| 598 /* If the size is negative, negate RELOCATION. This isn't very | 579 /* If the size is negative, negate RELOCATION. This isn't very |
| 599 general. */ | 580 general. */ |
| 600 if (howto->size < 0) | 581 if (howto->size < 0) |
| 601 relocation = -relocation; | 582 relocation = -relocation; |
| 602 | 583 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 case 8: | 731 case 8: |
| 751 #endif | 732 #endif |
| 752 put_data (x, location, size); | 733 put_data (x, location, size); |
| 753 break; | 734 break; |
| 754 } | 735 } |
| 755 | 736 |
| 756 return overflow ? bfd_reloc_overflow : bfd_reloc_ok; | 737 return overflow ? bfd_reloc_overflow : bfd_reloc_ok; |
| 757 } | 738 } |
| 758 | 739 |
| 759 bfd_reloc_status_type | 740 bfd_reloc_status_type |
| 760 _bfd_ns32k_reloc_disp (abfd, reloc_entry, symbol, data, input_section, | 741 _bfd_ns32k_reloc_disp (bfd *abfd, |
| 761 » » output_bfd, error_message) | 742 » » arelent *reloc_entry, |
| 762 bfd *abfd; | 743 » » struct bfd_symbol *symbol, |
| 763 arelent *reloc_entry; | 744 » » void * data, |
| 764 struct bfd_symbol *symbol; | 745 » » asection *input_section, |
| 765 PTR data; | 746 » » bfd *output_bfd, |
| 766 asection *input_section; | 747 » » char **error_message) |
| 767 bfd *output_bfd; | |
| 768 char **error_message; | |
| 769 { | 748 { |
| 770 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, | 749 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, |
| 771 output_bfd, error_message, | 750 output_bfd, error_message, |
| 772 _bfd_ns32k_get_displacement, | 751 _bfd_ns32k_get_displacement, |
| 773 _bfd_ns32k_put_displacement); | 752 _bfd_ns32k_put_displacement); |
| 774 } | 753 } |
| 775 | 754 |
| 776 bfd_reloc_status_type | 755 bfd_reloc_status_type |
| 777 _bfd_ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section, | 756 _bfd_ns32k_reloc_imm (bfd *abfd, |
| 778 » » output_bfd, error_message) | 757 » » arelent *reloc_entry, |
| 779 bfd *abfd; | 758 » » struct bfd_symbol *symbol, |
| 780 arelent *reloc_entry; | 759 » » void * data, |
| 781 struct bfd_symbol *symbol; | 760 » » asection *input_section, |
| 782 PTR data; | 761 » » bfd *output_bfd, |
| 783 asection *input_section; | 762 » » char **error_message) |
| 784 bfd *output_bfd; | |
| 785 char **error_message; | |
| 786 { | 763 { |
| 787 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, | 764 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, |
| 788 output_bfd, error_message, _bfd_ns32k_get_immediate, | 765 output_bfd, error_message, _bfd_ns32k_get_immediate, |
| 789 _bfd_ns32k_put_immediate); | 766 _bfd_ns32k_put_immediate); |
| 790 } | 767 } |
| 791 | 768 |
| 792 bfd_reloc_status_type | 769 bfd_reloc_status_type |
| 793 _bfd_ns32k_final_link_relocate (howto, input_bfd, input_section, contents, | 770 _bfd_ns32k_final_link_relocate (reloc_howto_type *howto, |
| 794 » » » » address, value, addend) | 771 » » » » bfd *input_bfd, |
| 795 reloc_howto_type *howto; | 772 » » » » asection *input_section, |
| 796 bfd *input_bfd; | 773 » » » » bfd_byte *contents, |
| 797 asection *input_section; | 774 » » » » bfd_vma address, |
| 798 bfd_byte *contents; | 775 » » » » bfd_vma value, |
| 799 bfd_vma address; | 776 » » » » bfd_vma addend) |
| 800 bfd_vma value; | |
| 801 bfd_vma addend; | |
| 802 { | 777 { |
| 803 bfd_vma relocation; | 778 bfd_vma relocation; |
| 804 | 779 |
| 805 /* Sanity check the address. */ | 780 /* Sanity check the address. */ |
| 806 if (address > bfd_get_section_limit (input_bfd, input_section)) | 781 if (address > bfd_get_section_limit (input_bfd, input_section)) |
| 807 return bfd_reloc_outofrange; | 782 return bfd_reloc_outofrange; |
| 808 | 783 |
| 809 /* This function assumes that we are dealing with a basic relocation | 784 /* 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 | 785 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 | 786 relocate to. This is just VALUE, the value of the symbol, plus |
| (...skipping 14 matching lines...) Expand all Loading... |
| 826 { | 801 { |
| 827 relocation -= (input_section->output_section->vma | 802 relocation -= (input_section->output_section->vma |
| 828 + input_section->output_offset); | 803 + input_section->output_offset); |
| 829 if (howto->pcrel_offset) | 804 if (howto->pcrel_offset) |
| 830 relocation -= address; | 805 relocation -= address; |
| 831 } | 806 } |
| 832 | 807 |
| 833 return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation, | 808 return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation, |
| 834 contents + address); | 809 contents + address); |
| 835 } | 810 } |
| OLD | NEW |