00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "bfd.h"
00027 #include "sysdep.h"
00028 #include "bfdlink.h"
00029 #include "libbfd.h"
00030 #include "elf-bfd.h"
00031 #include "elf32-m68hc1x.h"
00032 #include "elf/m68hc11.h"
00033 #include "opcode/m68hc11.h"
00034
00035
00036 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
00037 (bfd *, bfd_reloc_code_real_type);
00038 static void m68hc11_info_to_howto_rel
00039 (bfd *, arelent *, Elf_Internal_Rela *);
00040
00041
00042 static bfd_boolean m68hc12_elf_size_one_stub
00043 (struct bfd_hash_entry *gen_entry, void *in_arg);
00044 static bfd_boolean m68hc12_elf_build_one_stub
00045 (struct bfd_hash_entry *gen_entry, void *in_arg);
00046 static struct bfd_link_hash_table* m68hc12_elf_bfd_link_hash_table_create
00047 (bfd*);
00048
00049 static bfd_boolean m68hc12_elf_set_mach_from_flags PARAMS ((bfd *));
00050
00051
00052 #define USE_REL 1
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 static reloc_howto_type elf_m68hc11_howto_table[] = {
00117
00118 HOWTO (R_M68HC11_NONE,
00119 0,
00120 2,
00121 32,
00122 FALSE,
00123 0,
00124 complain_overflow_dont,
00125 bfd_elf_generic_reloc,
00126 "R_M68HC12_NONE",
00127 FALSE,
00128 0,
00129 0,
00130 FALSE),
00131
00132
00133 HOWTO (R_M68HC11_8,
00134 0,
00135 0,
00136 8,
00137 FALSE,
00138 0,
00139 complain_overflow_bitfield,
00140 bfd_elf_generic_reloc,
00141 "R_M68HC12_8",
00142 FALSE,
00143 0x00ff,
00144 0x00ff,
00145 FALSE),
00146
00147
00148 HOWTO (R_M68HC11_HI8,
00149 8,
00150 0,
00151 8,
00152 FALSE,
00153 0,
00154 complain_overflow_bitfield,
00155 bfd_elf_generic_reloc,
00156 "R_M68HC12_HI8",
00157 FALSE,
00158 0x00ff,
00159 0x00ff,
00160 FALSE),
00161
00162
00163 HOWTO (R_M68HC11_LO8,
00164 0,
00165 0,
00166 8,
00167 FALSE,
00168 0,
00169 complain_overflow_dont,
00170 bfd_elf_generic_reloc,
00171 "R_M68HC12_LO8",
00172 FALSE,
00173 0x00ff,
00174 0x00ff,
00175 FALSE),
00176
00177
00178 HOWTO (R_M68HC11_PCREL_8,
00179 0,
00180 0,
00181 8,
00182 TRUE,
00183 0,
00184 complain_overflow_bitfield,
00185 bfd_elf_generic_reloc,
00186 "R_M68HC12_PCREL_8",
00187 FALSE,
00188 0x00ff,
00189 0x00ff,
00190 TRUE),
00191
00192
00193 HOWTO (R_M68HC11_16,
00194 0,
00195 1,
00196 16,
00197 FALSE,
00198 0,
00199 complain_overflow_dont ,
00200 bfd_elf_generic_reloc,
00201 "R_M68HC12_16",
00202 FALSE,
00203 0xffff,
00204 0xffff,
00205 FALSE),
00206
00207
00208
00209 HOWTO (R_M68HC11_32,
00210 0,
00211 2,
00212 32,
00213 FALSE,
00214 0,
00215 complain_overflow_bitfield,
00216 bfd_elf_generic_reloc,
00217 "R_M68HC12_32",
00218 FALSE,
00219 0xffffffff,
00220 0xffffffff,
00221 FALSE),
00222
00223
00224 HOWTO (R_M68HC11_3B,
00225 0,
00226 0,
00227 3,
00228 FALSE,
00229 0,
00230 complain_overflow_bitfield,
00231 bfd_elf_generic_reloc,
00232 "R_M68HC12_4B",
00233 FALSE,
00234 0x003,
00235 0x003,
00236 FALSE),
00237
00238
00239 HOWTO (R_M68HC11_PCREL_16,
00240 0,
00241 1,
00242 16,
00243 TRUE,
00244 0,
00245 complain_overflow_dont,
00246 bfd_elf_generic_reloc,
00247 "R_M68HC12_PCREL_16",
00248 FALSE,
00249 0xffff,
00250 0xffff,
00251 TRUE),
00252
00253
00254 HOWTO (R_M68HC11_GNU_VTINHERIT,
00255 0,
00256 1,
00257 0,
00258 FALSE,
00259 0,
00260 complain_overflow_dont,
00261 NULL,
00262 "R_M68HC11_GNU_VTINHERIT",
00263 FALSE,
00264 0,
00265 0,
00266 FALSE),
00267
00268
00269 HOWTO (R_M68HC11_GNU_VTENTRY,
00270 0,
00271 1,
00272 0,
00273 FALSE,
00274 0,
00275 complain_overflow_dont,
00276 _bfd_elf_rel_vtable_reloc_fn,
00277 "R_M68HC11_GNU_VTENTRY",
00278 FALSE,
00279 0,
00280 0,
00281 FALSE),
00282
00283
00284 HOWTO (R_M68HC11_24,
00285 0,
00286 2,
00287 24,
00288 FALSE,
00289 0,
00290 complain_overflow_dont,
00291 m68hc11_elf_special_reloc,
00292 "R_M68HC12_24",
00293 FALSE,
00294 0xffffff,
00295 0xffffff,
00296 FALSE),
00297
00298
00299 HOWTO (R_M68HC11_LO16,
00300 0,
00301 1,
00302 16,
00303 FALSE,
00304 0,
00305 complain_overflow_dont,
00306 m68hc11_elf_special_reloc,
00307 "R_M68HC12_LO16",
00308 FALSE,
00309 0xffff,
00310 0xffff,
00311 FALSE),
00312
00313
00314 HOWTO (R_M68HC11_PAGE,
00315 0,
00316 0,
00317 8,
00318 FALSE,
00319 0,
00320 complain_overflow_dont,
00321 m68hc11_elf_special_reloc,
00322 "R_M68HC12_PAGE",
00323 FALSE,
00324 0x00ff,
00325 0x00ff,
00326 FALSE),
00327
00328 EMPTY_HOWTO (14),
00329 EMPTY_HOWTO (15),
00330 EMPTY_HOWTO (16),
00331 EMPTY_HOWTO (17),
00332 EMPTY_HOWTO (18),
00333 EMPTY_HOWTO (19),
00334
00335
00336 HOWTO (R_M68HC11_RL_JUMP,
00337 0,
00338 1,
00339 0,
00340 FALSE,
00341 0,
00342 complain_overflow_dont,
00343 m68hc11_elf_ignore_reloc,
00344 "R_M68HC12_RL_JUMP",
00345 TRUE,
00346 0,
00347 0,
00348 TRUE),
00349
00350
00351 HOWTO (R_M68HC11_RL_GROUP,
00352 0,
00353 1,
00354 0,
00355 FALSE,
00356 0,
00357 complain_overflow_dont,
00358 m68hc11_elf_ignore_reloc,
00359 "R_M68HC12_RL_GROUP",
00360 TRUE,
00361 0,
00362 0,
00363 TRUE),
00364 };
00365
00366
00367
00368 struct m68hc11_reloc_map
00369 {
00370 bfd_reloc_code_real_type bfd_reloc_val;
00371 unsigned char elf_reloc_val;
00372 };
00373
00374 static const struct m68hc11_reloc_map m68hc11_reloc_map[] = {
00375 {BFD_RELOC_NONE, R_M68HC11_NONE,},
00376 {BFD_RELOC_8, R_M68HC11_8},
00377 {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
00378 {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
00379 {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
00380 {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
00381 {BFD_RELOC_16, R_M68HC11_16},
00382 {BFD_RELOC_32, R_M68HC11_32},
00383 {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
00384
00385 {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
00386 {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
00387
00388 {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
00389 {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
00390 {BFD_RELOC_M68HC11_24, R_M68HC11_24},
00391
00392 {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
00393 {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
00394 };
00395
00396 static reloc_howto_type *
00397 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00398 bfd_reloc_code_real_type code)
00399 {
00400 unsigned int i;
00401
00402 for (i = 0;
00403 i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
00404 i++)
00405 {
00406 if (m68hc11_reloc_map[i].bfd_reloc_val == code)
00407 return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
00408 }
00409
00410 return NULL;
00411 }
00412
00413
00414
00415 static void
00416 m68hc11_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
00417 arelent *cache_ptr, Elf_Internal_Rela *dst)
00418 {
00419 unsigned int r_type;
00420
00421 r_type = ELF32_R_TYPE (dst->r_info);
00422 BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
00423 cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
00424 }
00425
00426
00427
00428
00429
00430 static bfd_boolean
00431 m68hc12_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
00432 {
00433 struct elf32_m68hc11_stub_hash_entry *stub_entry;
00434 struct bfd_link_info *info;
00435 struct m68hc11_elf_link_hash_table *htab;
00436 asection *stub_sec;
00437 bfd *stub_bfd;
00438 bfd_byte *loc;
00439 bfd_vma sym_value, phys_page, phys_addr;
00440
00441
00442 stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
00443 info = (struct bfd_link_info *) in_arg;
00444
00445 htab = m68hc11_elf_hash_table (info);
00446
00447 stub_sec = stub_entry->stub_sec;
00448
00449
00450 stub_entry->stub_offset = stub_sec->size;
00451 stub_sec->size += 7;
00452 loc = stub_sec->contents + stub_entry->stub_offset;
00453
00454 stub_bfd = stub_sec->owner;
00455
00456
00457
00458
00459
00460
00461
00462 sym_value = (stub_entry->target_value
00463 + stub_entry->target_section->output_offset
00464 + stub_entry->target_section->output_section->vma);
00465 phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value);
00466 phys_page = m68hc11_phys_page (&htab->pinfo, sym_value);
00467
00468
00469 bfd_put_8 (stub_bfd, 0xCD, loc);
00470 bfd_put_16 (stub_bfd, phys_addr, loc + 1);
00471 loc += 3;
00472
00473
00474 bfd_put_8 (stub_bfd, 0x4a, loc);
00475 bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1);
00476 bfd_put_8 (stub_bfd, phys_page, loc + 3);
00477
00478 return TRUE;
00479 }
00480
00481
00482
00483
00484 static bfd_boolean
00485 m68hc12_elf_size_one_stub (struct bfd_hash_entry *gen_entry,
00486 void *in_arg ATTRIBUTE_UNUSED)
00487 {
00488 struct elf32_m68hc11_stub_hash_entry *stub_entry;
00489
00490
00491 stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
00492
00493 stub_entry->stub_sec->size += 7;
00494 return TRUE;
00495 }
00496
00497
00498
00499 static struct bfd_link_hash_table *
00500 m68hc12_elf_bfd_link_hash_table_create (bfd *abfd)
00501 {
00502 struct m68hc11_elf_link_hash_table *ret;
00503
00504 ret = m68hc11_elf_hash_table_create (abfd);
00505 if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
00506 return NULL;
00507
00508 ret->size_one_stub = m68hc12_elf_size_one_stub;
00509 ret->build_one_stub = m68hc12_elf_build_one_stub;
00510
00511 return &ret->root.root;
00512 }
00513
00514 static bfd_boolean
00515 m68hc12_elf_set_mach_from_flags (bfd *abfd)
00516 {
00517 flagword flags = elf_elfheader (abfd)->e_flags;
00518
00519 switch (flags & EF_M68HC11_MACH_MASK)
00520 {
00521 case EF_M68HC12_MACH:
00522 bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, bfd_mach_m6812);
00523 break;
00524 case EF_M68HCS12_MACH:
00525 bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, bfd_mach_m6812s);
00526 break;
00527 case EF_M68HC11_GENERIC:
00528 bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12,
00529 bfd_mach_m6812_default);
00530 break;
00531 default:
00532 return FALSE;
00533 }
00534 return TRUE;
00535 }
00536
00537
00538
00539
00540
00541
00542 static struct bfd_elf_special_section const elf32_m68hc12_special_sections[]=
00543 {
00544 { ".eeprom", 7, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
00545 { ".softregs", 9, 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
00546 { ".page0", 6, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
00547 { ".vectors", 8, 0, SHT_PROGBITS, SHF_ALLOC },
00548 { NULL, 0, 0, 0, 0 }
00549 };
00550
00551 #define ELF_ARCH bfd_arch_m68hc12
00552 #define ELF_MACHINE_CODE EM_68HC12
00553 #define ELF_MAXPAGESIZE 0x1000
00554
00555 #define TARGET_BIG_SYM bfd_elf32_m68hc12_vec
00556 #define TARGET_BIG_NAME "elf32-m68hc12"
00557
00558 #define elf_info_to_howto 0
00559 #define elf_info_to_howto_rel m68hc11_info_to_howto_rel
00560 #define elf_backend_gc_mark_hook elf32_m68hc11_gc_mark_hook
00561 #define elf_backend_gc_sweep_hook elf32_m68hc11_gc_sweep_hook
00562 #define elf_backend_check_relocs elf32_m68hc11_check_relocs
00563 #define elf_backend_relocate_section elf32_m68hc11_relocate_section
00564 #define elf_backend_object_p m68hc12_elf_set_mach_from_flags
00565 #define elf_backend_final_write_processing 0
00566 #define elf_backend_can_gc_sections 1
00567 #define elf_backend_special_sections elf32_m68hc12_special_sections
00568 #define elf_backend_post_process_headers elf32_m68hc11_post_process_headers
00569 #define elf_backend_add_symbol_hook elf32_m68hc11_add_symbol_hook
00570
00571 #define bfd_elf32_bfd_link_hash_table_create \
00572 m68hc12_elf_bfd_link_hash_table_create
00573 #define bfd_elf32_bfd_link_hash_table_free \
00574 m68hc11_elf_bfd_link_hash_table_free
00575 #define bfd_elf32_bfd_merge_private_bfd_data \
00576 _bfd_m68hc11_elf_merge_private_bfd_data
00577 #define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags
00578 #define bfd_elf32_bfd_print_private_bfd_data \
00579 _bfd_m68hc11_elf_print_private_bfd_data
00580
00581 #include "elf32-target.h"