OLD | NEW |
1 /* BFD back-end for WDC 65816 COFF binaries. | 1 /* BFD back-end for WDC 65816 COFF binaries. |
2 Copyright 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, | 2 Copyright 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, |
3 2006, 2007, 2008 Free Software Foundation, Inc. | 3 2006, 2007, 2008, 2012 Free Software Foundation, Inc. |
4 Written by Steve Chamberlain, <sac@cygnus.com>. | 4 Written by Steve Chamberlain, <sac@cygnus.com>. |
5 | 5 |
6 This file is part of BFD, the Binary File Descriptor library. | 6 This file is part of BFD, the Binary File Descriptor library. |
7 | 7 |
8 This program is free software; you can redistribute it and/or modify | 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 | 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 | 10 the Free Software Foundation; either version 3 of the License, or |
11 (at your option) any later version. | 11 (at your option) any later version. |
12 | 12 |
13 This program is distributed in the hope that it will be useful, | 13 This program is distributed in the hope that it will be useful, |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 GNU General Public License for more details. | 16 GNU General Public License for more details. |
17 | 17 |
18 You should have received a copy of the GNU General Public License | 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 | 19 along with this program; if not, write to the Free Software |
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
21 MA 02110-1301, USA. */ | 21 MA 02110-1301, USA. */ |
22 | 22 |
23 #include "sysdep.h" | 23 #include "sysdep.h" |
24 #include "bfd.h" | 24 #include "bfd.h" |
25 #include "libbfd.h" | 25 #include "libbfd.h" |
26 #include "bfdlink.h" | 26 #include "bfdlink.h" |
27 #include "coff/w65.h" | 27 #include "coff/w65.h" |
28 #include "coff/internal.h" | 28 #include "coff/internal.h" |
29 #include "libcoff.h" | 29 #include "libcoff.h" |
30 | 30 |
31 static int select_reloc PARAMS ((reloc_howto_type *)); | |
32 static void rtype2howto PARAMS ((arelent *, struct internal_reloc
*)); | |
33 static void reloc_processing PARAMS ((arelent *, struct internal_reloc
*, asymbol **, bfd *, asection *)); | |
34 static int w65_reloc16_estimate PARAMS ((bfd *, asection *, arelent *, unsig
ned int, struct bfd_link_info *)); | |
35 static void w65_reloc16_extra_cases PARAMS ((bfd *,struct bfd_link_info *, struc
t bfd_link_order *, arelent *, bfd_byte *, unsigned int *, unsigned int *)); | |
36 | |
37 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1) | 31 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1) |
38 static reloc_howto_type howto_table[] = | 32 static reloc_howto_type howto_table[] = |
39 { | 33 { |
40 HOWTO (R_W65_ABS8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "a
bs8", TRUE, 0x000000ff, 0x000000ff, FALSE), | 34 HOWTO (R_W65_ABS8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "abs
8", TRUE, 0x000000ff, 0x000000ff, FALSE), |
41 HOWTO (R_W65_ABS16, 1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, "a
bs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), | 35 HOWTO (R_W65_ABS16, 1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, "a
bs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), |
42 HOWTO (R_W65_ABS24, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "a
bs24", TRUE, 0x00ffffff, 0x00ffffff, FALSE), | 36 HOWTO (R_W65_ABS24, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "a
bs24", TRUE, 0x00ffffff, 0x00ffffff, FALSE), |
43 HOWTO (R_W65_ABS8S8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, ">
abs8", TRUE, 0x000000ff, 0x000000ff, FALSE), | 37 HOWTO (R_W65_ABS8S8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, ">
abs8", TRUE, 0x000000ff, 0x000000ff, FALSE), |
44 HOWTO (R_W65_ABS8S16, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "^
abs8", TRUE, 0x000000ff, 0x000000ff, FALSE), | 38 HOWTO (R_W65_ABS8S16, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "^
abs8", TRUE, 0x000000ff, 0x000000ff, FALSE), |
45 HOWTO (R_W65_ABS16S8, 1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, ">
abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), | 39 HOWTO (R_W65_ABS16S8, 1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, ">
abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), |
46 HOWTO (R_W65_ABS16S16,1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, "^
abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), | 40 HOWTO (R_W65_ABS16S16,1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, "^
abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), |
47 HOWTO (R_W65_PCR8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "p
crel8", TRUE, 0x000000ff, 0x000000ff, TRUE), | 41 HOWTO (R_W65_PCR8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "p
crel8", TRUE, 0x000000ff, 0x000000ff, TRUE), |
48 HOWTO (R_W65_PCR16, 1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, "p
crel16", TRUE, 0x0000ffff, 0x0000ffff, TRUE), | 42 HOWTO (R_W65_PCR16, 1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, "p
crel16", TRUE, 0x0000ffff, 0x0000ffff, TRUE), |
49 HOWTO (R_W65_DP, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "d
p", TRUE, 0x000000ff, 0x000000ff, FALSE), | 43 HOWTO (R_W65_DP, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "d
p", TRUE, 0x000000ff, 0x000000ff, FALSE), |
50 }; | 44 }; |
51 | 45 |
52 /* Turn a howto into a reloc number. */ | 46 /* Turn a howto into a reloc number. */ |
53 | 47 |
54 #define SELECT_RELOC(x,howto) \ | 48 #define SELECT_RELOC(x,howto) \ |
55 { x.r_type = select_reloc(howto); } | 49 { x.r_type = select_reloc(howto); } |
56 | 50 |
57 #define BADMAG(x) (W65BADMAG(x)) | 51 #define BADMAG(x) (W65BADMAG(x)) |
58 #define W65 1 /* Customize coffcode.h */ | 52 #define W65 1 /* Customize coffcode.h */ |
59 #define __A_MAGIC_SET__ | 53 #define __A_MAGIC_SET__ |
60 | 54 |
61 /* Code to swap in the reloc */ | 55 /* Code to swap in the reloc */ |
62 #define SWAP_IN_RELOC_OFFSET H_GET_32 | 56 #define SWAP_IN_RELOC_OFFSET H_GET_32 |
63 #define SWAP_OUT_RELOC_OFFSET H_PUT_32 | 57 #define SWAP_OUT_RELOC_OFFSET H_PUT_32 |
64 #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ | 58 #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ |
65 dst->r_stuff[0] = 'S'; \ | 59 dst->r_stuff[0] = 'S'; \ |
66 dst->r_stuff[1] = 'C'; | 60 dst->r_stuff[1] = 'C'; |
67 | 61 |
68 static int | 62 static int |
69 select_reloc (howto) | 63 select_reloc (reloc_howto_type *howto) |
70 reloc_howto_type *howto; | |
71 { | 64 { |
72 return howto->type ; | 65 return howto->type ; |
73 } | 66 } |
74 | 67 |
75 /* Code to turn a r_type into a howto ptr, uses the above howto table. */ | 68 /* Code to turn a r_type into a howto ptr, uses the above howto table. */ |
76 | 69 |
77 static void | 70 static void |
78 rtype2howto (internal, dst) | 71 rtype2howto (arelent *internal, |
79 arelent *internal; | 72 » struct internal_reloc *dst) |
80 struct internal_reloc *dst; | |
81 { | 73 { |
82 internal->howto = howto_table + dst->r_type - 1; | 74 internal->howto = howto_table + dst->r_type - 1; |
83 } | 75 } |
84 | 76 |
85 #define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry) | 77 #define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry) |
86 | 78 |
87 /* Perform any necessary magic to the addend in a reloc entry. */ | 79 /* Perform any necessary magic to the addend in a reloc entry. */ |
88 | 80 |
89 #define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ | 81 #define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ |
90 cache_ptr->addend = ext_reloc.r_offset; | 82 cache_ptr->addend = ext_reloc.r_offset; |
91 | 83 |
92 #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ | 84 #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ |
93 reloc_processing(relent, reloc, symbols, abfd, section) | 85 reloc_processing(relent, reloc, symbols, abfd, section) |
94 | 86 |
95 static void | 87 static void |
96 reloc_processing (relent, reloc, symbols, abfd, section) | 88 reloc_processing (arelent * relent, |
97 arelent * relent; | 89 » » struct internal_reloc *reloc, |
98 struct internal_reloc *reloc; | 90 » » asymbol ** symbols, |
99 asymbol ** symbols; | 91 » » bfd * abfd, |
100 bfd * abfd; | 92 » » asection * section) |
101 asection * section; | |
102 { | 93 { |
103 relent->address = reloc->r_vaddr; | 94 relent->address = reloc->r_vaddr; |
104 rtype2howto (relent, reloc); | 95 rtype2howto (relent, reloc); |
105 | 96 |
106 if (((int) reloc->r_symndx) > 0) | 97 if (((int) reloc->r_symndx) > 0) |
107 relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; | 98 relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; |
108 else | 99 else |
109 relent->sym_ptr_ptr = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr; | 100 relent->sym_ptr_ptr = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr; |
110 | 101 |
111 relent->addend = reloc->r_offset; | 102 relent->addend = reloc->r_offset; |
112 | 103 |
113 relent->address -= section->vma; | 104 relent->address -= section->vma; |
114 /* relent->section = 0;*/ | 105 /* relent->section = 0;*/ |
115 } | 106 } |
116 | 107 |
117 static int | 108 static int |
118 w65_reloc16_estimate (abfd, input_section, reloc, shrink, link_info) | 109 w65_reloc16_estimate (bfd *abfd, |
119 bfd *abfd; | 110 » » asection *input_section, |
120 asection *input_section; | 111 » » arelent *reloc, |
121 arelent *reloc; | 112 » » unsigned int shrink, |
122 unsigned int shrink; | 113 » » struct bfd_link_info *link_info) |
123 struct bfd_link_info *link_info; | |
124 { | 114 { |
125 bfd_vma value; | 115 bfd_vma value; |
126 bfd_vma dot; | 116 bfd_vma dot; |
127 bfd_vma gap; | 117 bfd_vma gap; |
128 | 118 |
129 /* The address of the thing to be relocated will have moved back by | 119 /* The address of the thing to be relocated will have moved back by |
130 the size of the shrink - but we don't change reloc->address here, | 120 the size of the shrink - but we don't change reloc->address here, |
131 since we need it to know where the relocation lives in the source | 121 since we need it to know where the relocation lives in the source |
132 uncooked section. */ | 122 uncooked section. */ |
133 | 123 |
134 /* reloc->address -= shrink; conceptual */ | 124 /* reloc->address -= shrink; conceptual */ |
135 | 125 |
136 bfd_vma address = reloc->address - shrink; | 126 bfd_vma address = reloc->address - shrink; |
137 | 127 |
138 switch (reloc->howto->type) | 128 switch (reloc->howto->type) |
139 { | 129 { |
140 case R_MOV16B2: | 130 case R_MOV16B2: |
141 case R_JMP2: | 131 case R_JMP2: |
142 shrink+=2; | 132 shrink+=2; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 /* First phase of a relaxing link. */ | 205 /* First phase of a relaxing link. */ |
216 | 206 |
217 /* Reloc types | 207 /* Reloc types |
218 large small | 208 large small |
219 R_MOV16B1 R_MOV16B2 mov.b with 16bit or 8 bit address | 209 R_MOV16B1 R_MOV16B2 mov.b with 16bit or 8 bit address |
220 R_JMP1 R_JMP2 jmp or pcrel branch | 210 R_JMP1 R_JMP2 jmp or pcrel branch |
221 R_JMPL1 R_JMPL_B8 24jmp or pcrel branch | 211 R_JMPL1 R_JMPL_B8 24jmp or pcrel branch |
222 R_MOV24B1 R_MOV24B2 24 or 8 bit reloc for mov.b */ | 212 R_MOV24B1 R_MOV24B2 24 or 8 bit reloc for mov.b */ |
223 | 213 |
224 static void | 214 static void |
225 w65_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, | 215 w65_reloc16_extra_cases (bfd *abfd, |
226 » » » dst_ptr) | 216 » » » struct bfd_link_info *link_info, |
227 bfd *abfd; | 217 » » » struct bfd_link_order *link_order, |
228 struct bfd_link_info *link_info; | 218 » » » arelent *reloc, |
229 struct bfd_link_order *link_order; | 219 » » » bfd_byte *data, |
230 arelent *reloc; | 220 » » » unsigned int *src_ptr, |
231 bfd_byte *data; | 221 » » » unsigned int *dst_ptr) |
232 unsigned int *src_ptr; | |
233 unsigned int *dst_ptr; | |
234 { | 222 { |
235 unsigned int src_address = *src_ptr; | 223 unsigned int src_address = *src_ptr; |
236 unsigned int dst_address = *dst_ptr; | 224 unsigned int dst_address = *dst_ptr; |
237 asection *input_section = link_order->u.indirect.section; | 225 asection *input_section = link_order->u.indirect.section; |
238 | 226 |
239 switch (reloc->howto->type) | 227 switch (reloc->howto->type) |
240 { | 228 { |
241 case R_W65_ABS8: | 229 case R_W65_ABS8: |
242 case R_W65_DP: | 230 case R_W65_DP: |
243 { | 231 { |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 | 369 |
382 #include "coffcode.h" | 370 #include "coffcode.h" |
383 | 371 |
384 #undef coff_bfd_get_relocated_section_contents | 372 #undef coff_bfd_get_relocated_section_contents |
385 #undef coff_bfd_relax_section | 373 #undef coff_bfd_relax_section |
386 #define coff_bfd_get_relocated_section_contents \ | 374 #define coff_bfd_get_relocated_section_contents \ |
387 bfd_coff_reloc16_get_relocated_section_contents | 375 bfd_coff_reloc16_get_relocated_section_contents |
388 #define coff_bfd_relax_section bfd_coff_reloc16_relax_section | 376 #define coff_bfd_relax_section bfd_coff_reloc16_relax_section |
389 | 377 |
390 CREATE_LITTLE_COFF_TARGET_VEC (w65_vec, "coff-w65", BFD_IS_RELAXABLE, 0, '_', NU
LL, COFF_SWAP_TABLE) | 378 CREATE_LITTLE_COFF_TARGET_VEC (w65_vec, "coff-w65", BFD_IS_RELAXABLE, 0, '_', NU
LL, COFF_SWAP_TABLE) |
OLD | NEW |