OLD | NEW |
1 /* Motorola 68HC11/HC12-specific support for 32-bit ELF | 1 /* Motorola 68HC11/HC12-specific support for 32-bit ELF |
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, | 2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, |
3 2009, 2010, 2011 Free Software Foundation, Inc. | 3 2009, 2010, 2011, 2012 Free Software Foundation, Inc. |
4 Contributed by Stephane Carrez (stcarrez@nerim.fr) | 4 Contributed by Stephane Carrez (stcarrez@nerim.fr) |
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 "alloca-conf.h" | 24 #include "alloca-conf.h" |
24 #include "sysdep.h" | |
25 #include "bfd.h" | 25 #include "bfd.h" |
26 #include "bfdlink.h" | 26 #include "bfdlink.h" |
27 #include "libbfd.h" | 27 #include "libbfd.h" |
28 #include "elf-bfd.h" | 28 #include "elf-bfd.h" |
29 #include "elf32-m68hc1x.h" | 29 #include "elf32-m68hc1x.h" |
30 #include "elf/m68hc11.h" | 30 #include "elf/m68hc11.h" |
31 #include "opcode/m68hc11.h" | 31 #include "opcode/m68hc11.h" |
32 | 32 |
33 | 33 |
34 #define m68hc12_stub_hash_lookup(table, string, create, copy) \ | 34 #define m68hc12_stub_hash_lookup(table, string, create, copy) \ |
35 ((struct elf32_m68hc11_stub_hash_entry *) \ | 35 ((struct elf32_m68hc11_stub_hash_entry *) \ |
36 bfd_hash_lookup ((table), (string), (create), (copy))) | 36 bfd_hash_lookup ((table), (string), (create), (copy))) |
37 | 37 |
38 static struct elf32_m68hc11_stub_hash_entry* m68hc12_add_stub | 38 static struct elf32_m68hc11_stub_hash_entry* m68hc12_add_stub |
39 (const char *stub_name, | 39 (const char *stub_name, |
40 asection *section, | 40 asection *section, |
41 struct m68hc11_elf_link_hash_table *htab); | 41 struct m68hc11_elf_link_hash_table *htab); |
42 | 42 |
43 static struct bfd_hash_entry *stub_hash_newfunc | 43 static struct bfd_hash_entry *stub_hash_newfunc |
44 (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); | 44 (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); |
45 | 45 |
46 static void m68hc11_elf_set_symbol (bfd* abfd, struct bfd_link_info *info, | 46 static void m68hc11_elf_set_symbol (bfd* abfd, struct bfd_link_info *info, |
47 const char* name, bfd_vma value, | 47 const char* name, bfd_vma value, |
48 asection* sec); | 48 asection* sec); |
49 | 49 |
50 static bfd_boolean m68hc11_elf_export_one_stub | 50 static bfd_boolean m68hc11_elf_export_one_stub |
51 (struct bfd_hash_entry *gen_entry, void *in_arg); | 51 (struct bfd_hash_entry *gen_entry, void *in_arg); |
52 | 52 |
53 static void scan_sections_for_abi (bfd*, asection*, PTR); | 53 static void scan_sections_for_abi (bfd*, asection*, void *); |
54 | 54 |
55 struct m68hc11_scan_param | 55 struct m68hc11_scan_param |
56 { | 56 { |
57 struct m68hc11_page_info* pinfo; | 57 struct m68hc11_page_info* pinfo; |
58 bfd_boolean use_memory_banks; | 58 bfd_boolean use_memory_banks; |
59 }; | 59 }; |
60 | 60 |
61 | 61 |
62 /* Create a 68HC11/68HC12 ELF linker hash table. */ | 62 /* Create a 68HC11/68HC12 ELF linker hash table. */ |
63 | 63 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 BSF_GLOBAL, | 207 BSF_GLOBAL, |
208 bfd_und_section_ptr, | 208 bfd_und_section_ptr, |
209 (bfd_vma) 0, (const char*) NULL, | 209 (bfd_vma) 0, (const char*) NULL, |
210 FALSE, FALSE, &entry); | 210 FALSE, FALSE, &entry); |
211 } | 211 } |
212 | 212 |
213 } | 213 } |
214 return TRUE; | 214 return TRUE; |
215 } | 215 } |
216 | 216 |
| 217 /* Merge non-visibility st_other attributes, STO_M68HC12_FAR and |
| 218 STO_M68HC12_INTERRUPT. */ |
| 219 |
| 220 void |
| 221 elf32_m68hc11_merge_symbol_attribute (struct elf_link_hash_entry *h, |
| 222 const Elf_Internal_Sym *isym, |
| 223 bfd_boolean definition, |
| 224 bfd_boolean dynamic ATTRIBUTE_UNUSED) |
| 225 { |
| 226 if (definition) |
| 227 h->other = ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) |
| 228 | ELF_ST_VISIBILITY (h->other)); |
| 229 } |
| 230 |
217 /* External entry points for sizing and building linker stubs. */ | 231 /* External entry points for sizing and building linker stubs. */ |
218 | 232 |
219 /* Set up various things so that we can make a list of input sections | 233 /* Set up various things so that we can make a list of input sections |
220 for each output section included in the link. Returns -1 on error, | 234 for each output section included in the link. Returns -1 on error, |
221 0 when no stubs will be needed, and 1 on success. */ | 235 0 when no stubs will be needed, and 1 on success. */ |
222 | 236 |
223 int | 237 int |
224 elf32_m68hc11_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info) | 238 elf32_m68hc11_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info) |
225 { | 239 { |
226 bfd *input_bfd; | 240 bfd *input_bfd; |
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 Elf_Internal_Sym *sym; | 942 Elf_Internal_Sym *sym; |
929 asection *sec; | 943 asection *sec; |
930 bfd_vma relocation = 0; | 944 bfd_vma relocation = 0; |
931 bfd_reloc_status_type r = bfd_reloc_undefined; | 945 bfd_reloc_status_type r = bfd_reloc_undefined; |
932 bfd_vma phys_page; | 946 bfd_vma phys_page; |
933 bfd_vma phys_addr; | 947 bfd_vma phys_addr; |
934 bfd_vma insn_addr; | 948 bfd_vma insn_addr; |
935 bfd_vma insn_page; | 949 bfd_vma insn_page; |
936 bfd_boolean is_far = FALSE; | 950 bfd_boolean is_far = FALSE; |
937 struct elf_link_hash_entry *h; | 951 struct elf_link_hash_entry *h; |
| 952 bfd_vma val; |
938 | 953 |
939 r_symndx = ELF32_R_SYM (rel->r_info); | 954 r_symndx = ELF32_R_SYM (rel->r_info); |
940 r_type = ELF32_R_TYPE (rel->r_info); | 955 r_type = ELF32_R_TYPE (rel->r_info); |
941 | 956 |
942 if (r_type == R_M68HC11_GNU_VTENTRY | 957 if (r_type == R_M68HC11_GNU_VTENTRY |
943 || r_type == R_M68HC11_GNU_VTINHERIT ) | 958 || r_type == R_M68HC11_GNU_VTINHERIT ) |
944 continue; | 959 continue; |
945 | 960 |
946 (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel); | 961 (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel); |
947 howto = arel.howto; | 962 howto = arel.howto; |
(...skipping 15 matching lines...) Expand all Loading... |
963 bfd_boolean unresolved_reloc, warned; | 978 bfd_boolean unresolved_reloc, warned; |
964 | 979 |
965 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, | 980 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
966 r_symndx, symtab_hdr, sym_hashes, | 981 r_symndx, symtab_hdr, sym_hashes, |
967 h, sec, relocation, unresolved_reloc, | 982 h, sec, relocation, unresolved_reloc, |
968 warned); | 983 warned); |
969 | 984 |
970 is_far = (h && (h->other & STO_M68HC12_FAR)); | 985 is_far = (h && (h->other & STO_M68HC12_FAR)); |
971 } | 986 } |
972 | 987 |
973 if (sec != NULL && elf_discarded_section (sec)) | 988 if (sec != NULL && discarded_section (sec)) |
974 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, | 989 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, |
975 » » » » » rel, relend, howto, contents); | 990 » » » » » rel, 1, relend, howto, 0, contents); |
976 | 991 |
977 if (info->relocatable) | 992 if (info->relocatable) |
978 { | 993 { |
979 /* This is a relocatable link. We don't have to change | 994 /* This is a relocatable link. We don't have to change |
980 anything, unless the reloc is against a section symbol, | 995 anything, unless the reloc is against a section symbol, |
981 in which case we have to adjust according to where the | 996 in which case we have to adjust according to where the |
982 section symbol winds up in the output section. */ | 997 section symbol winds up in the output section. */ |
983 if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) | 998 if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) |
984 rel->r_addend += sec->output_offset; | 999 rel->r_addend += sec->output_offset; |
985 continue; | 1000 continue; |
(...skipping 22 matching lines...) Expand all Loading... |
1008 + stub->stub_sec->output_offset; | 1023 + stub->stub_sec->output_offset; |
1009 is_far = FALSE; | 1024 is_far = FALSE; |
1010 } | 1025 } |
1011 } | 1026 } |
1012 | 1027 |
1013 /* Do the memory bank mapping. */ | 1028 /* Do the memory bank mapping. */ |
1014 phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend); | 1029 phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend); |
1015 phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend); | 1030 phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend); |
1016 switch (r_type) | 1031 switch (r_type) |
1017 { | 1032 { |
| 1033 case R_M68HC12_LO8XG: |
| 1034 /* This relocation is specific to XGATE IMM16 calls and will precede |
| 1035 a HI8. tc-m68hc11 only generates them in pairs. |
| 1036 Leave the relocation to the HI8XG step. */ |
| 1037 r = bfd_reloc_ok; |
| 1038 r_type = R_M68HC11_NONE; |
| 1039 break; |
| 1040 |
| 1041 case R_M68HC12_HI8XG: |
| 1042 /* This relocation is specific to XGATE IMM16 calls and must follow |
| 1043 a LO8XG. Does not actually check that it was a LO8XG. |
| 1044 Adjusts high and low bytes. */ |
| 1045 relocation = phys_addr; |
| 1046 if ((elf_elfheader (input_bfd)->e_flags & E_M68HC11_XGATE_RAMOFFSET) |
| 1047 && (relocation >= 0x2000)) |
| 1048 relocation += 0xc000; /* HARDCODED RAM offset for XGATE. */ |
| 1049 |
| 1050 /* Fetch 16 bit value including low byte in previous insn. */ |
| 1051 val = (bfd_get_8 (input_bfd, (bfd_byte*) contents + rel->r_offset) <<
8) |
| 1052 | bfd_get_8 (input_bfd, (bfd_byte*) contents + rel->r_offset - 2); |
| 1053 |
| 1054 /* Add on value to preserve carry, then write zero to high byte. */ |
| 1055 relocation += val; |
| 1056 |
| 1057 /* Write out top byte. */ |
| 1058 bfd_put_8 (input_bfd, (relocation >> 8) & 0xff, |
| 1059 (bfd_byte*) contents + rel->r_offset); |
| 1060 |
| 1061 /* Write out low byte to previous instruction. */ |
| 1062 bfd_put_8 (input_bfd, relocation & 0xff, |
| 1063 (bfd_byte*) contents + rel->r_offset - 2); |
| 1064 |
| 1065 /* Mark as relocation completed. */ |
| 1066 r = bfd_reloc_ok; |
| 1067 r_type = R_M68HC11_NONE; |
| 1068 break; |
| 1069 |
| 1070 /* The HI8 and LO8 relocs are generated by %hi(expr) %lo(expr) |
| 1071 assembler directives. %hi does not support carry. */ |
| 1072 case R_M68HC11_HI8: |
| 1073 case R_M68HC11_LO8: |
| 1074 relocation = phys_addr; |
| 1075 break; |
| 1076 |
1018 case R_M68HC11_24: | 1077 case R_M68HC11_24: |
1019 /* Reloc used by 68HC12 call instruction. */ | 1078 /* Reloc used by 68HC12 call instruction. */ |
1020 bfd_put_16 (input_bfd, phys_addr, | 1079 bfd_put_16 (input_bfd, phys_addr, |
1021 (bfd_byte*) contents + rel->r_offset); | 1080 (bfd_byte*) contents + rel->r_offset); |
1022 bfd_put_8 (input_bfd, phys_page, | 1081 bfd_put_8 (input_bfd, phys_page, |
1023 (bfd_byte*) contents + rel->r_offset + 2); | 1082 (bfd_byte*) contents + rel->r_offset + 2); |
1024 r = bfd_reloc_ok; | 1083 r = bfd_reloc_ok; |
1025 r_type = R_M68HC11_NONE; | 1084 r_type = R_M68HC11_NONE; |
1026 break; | 1085 break; |
1027 | 1086 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 relocation = phys_addr; | 1161 relocation = phys_addr; |
1103 break; | 1162 break; |
1104 } | 1163 } |
1105 | 1164 |
1106 /* If this is a banked address use the phys_addr so that | 1165 /* If this is a banked address use the phys_addr so that |
1107 we stay in the banked window. */ | 1166 we stay in the banked window. */ |
1108 if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend)) | 1167 if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend)) |
1109 relocation = phys_addr; | 1168 relocation = phys_addr; |
1110 break; | 1169 break; |
1111 } | 1170 } |
| 1171 |
1112 if (r_type != R_M68HC11_NONE) | 1172 if (r_type != R_M68HC11_NONE) |
1113 r = _bfd_final_link_relocate (howto, input_bfd, input_section, | 1173 { |
| 1174 if ((r_type == R_M68HC12_PCREL_9) || (r_type == R_M68HC12_PCREL_10)) |
| 1175 r = _bfd_final_link_relocate (howto, input_bfd, input_section, |
1114 contents, rel->r_offset, | 1176 contents, rel->r_offset, |
1115 relocation, rel->r_addend); | 1177 relocation - 2, rel->r_addend); |
| 1178 else |
| 1179 r = _bfd_final_link_relocate (howto, input_bfd, input_section, |
| 1180 contents, rel->r_offset, |
| 1181 relocation, rel->r_addend); |
| 1182 } |
1116 | 1183 |
1117 if (r != bfd_reloc_ok) | 1184 if (r != bfd_reloc_ok) |
1118 { | 1185 { |
1119 const char * msg = (const char *) 0; | 1186 const char * msg = (const char *) 0; |
1120 | 1187 |
1121 switch (r) | 1188 switch (r) |
1122 { | 1189 { |
1123 case bfd_reloc_overflow: | 1190 case bfd_reloc_overflow: |
1124 if (!((*info->callbacks->reloc_overflow) | 1191 if (!((*info->callbacks->reloc_overflow) |
1125 (info, NULL, name, howto->name, (bfd_vma) 0, | 1192 (info, NULL, name, howto->name, (bfd_vma) 0, |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1293 fprintf (file, _("32-bit double, ")); | 1360 fprintf (file, _("32-bit double, ")); |
1294 | 1361 |
1295 if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0) | 1362 if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0) |
1296 fprintf (file, _("cpu=HC11]")); | 1363 fprintf (file, _("cpu=HC11]")); |
1297 else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH) | 1364 else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH) |
1298 fprintf (file, _("cpu=HCS12]")); | 1365 fprintf (file, _("cpu=HCS12]")); |
1299 else | 1366 else |
1300 fprintf (file, _("cpu=HC12]")); | 1367 fprintf (file, _("cpu=HC12]")); |
1301 | 1368 |
1302 if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS) | 1369 if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS) |
error: old chunk mismatch |
None
OLD | NEW |