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 |