| 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 |