1 1.1 christos /* Motorola 68HC11/HC12-specific support for 32-bit ELF 2 1.10 christos Copyright (C) 1999-2025 Free Software Foundation, Inc. 3 1.1 christos Contributed by Stephane Carrez (stcarrez (at) nerim.fr) 4 1.1 christos 5 1.1 christos This file is part of BFD, the Binary File Descriptor library. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program; if not, write to the Free Software 19 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 1.1 christos MA 02110-1301, USA. */ 21 1.1 christos 22 1.1 christos #include "sysdep.h" 23 1.1 christos #include "bfd.h" 24 1.1 christos #include "bfdlink.h" 25 1.1 christos #include "libbfd.h" 26 1.1 christos #include "elf-bfd.h" 27 1.1 christos #include "elf32-m68hc1x.h" 28 1.1 christos #include "elf/m68hc11.h" 29 1.1 christos #include "opcode/m68hc11.h" 30 1.5 christos #include "libiberty.h" 31 1.1 christos 32 1.1 christos #define m68hc12_stub_hash_lookup(table, string, create, copy) \ 33 1.1 christos ((struct elf32_m68hc11_stub_hash_entry *) \ 34 1.1 christos bfd_hash_lookup ((table), (string), (create), (copy))) 35 1.1 christos 36 1.1 christos static struct elf32_m68hc11_stub_hash_entry* m68hc12_add_stub 37 1.1 christos (const char *stub_name, 38 1.1 christos asection *section, 39 1.1 christos struct m68hc11_elf_link_hash_table *htab); 40 1.1 christos 41 1.1 christos static struct bfd_hash_entry *stub_hash_newfunc 42 1.1 christos (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); 43 1.1 christos 44 1.1 christos static void m68hc11_elf_set_symbol (bfd* abfd, struct bfd_link_info *info, 45 1.6 christos const char* name, bfd_vma value, 46 1.6 christos asection* sec); 47 1.1 christos 48 1.8 christos static bool m68hc11_elf_export_one_stub 49 1.1 christos (struct bfd_hash_entry *gen_entry, void *in_arg); 50 1.1 christos 51 1.1 christos static void scan_sections_for_abi (bfd*, asection*, void *); 52 1.1 christos 53 1.1 christos struct m68hc11_scan_param 54 1.1 christos { 55 1.1 christos struct m68hc11_page_info* pinfo; 56 1.8 christos bool use_memory_banks; 57 1.1 christos }; 58 1.1 christos 59 1.1 christos 60 1.3 christos /* Destroy a 68HC11/68HC12 ELF linker hash table. */ 61 1.3 christos 62 1.3 christos static void 63 1.3 christos m68hc11_elf_bfd_link_hash_table_free (bfd *obfd) 64 1.3 christos { 65 1.3 christos struct m68hc11_elf_link_hash_table *ret 66 1.3 christos = (struct m68hc11_elf_link_hash_table *) obfd->link.hash; 67 1.3 christos 68 1.3 christos bfd_hash_table_free (ret->stub_hash_table); 69 1.3 christos free (ret->stub_hash_table); 70 1.3 christos _bfd_elf_link_hash_table_free (obfd); 71 1.3 christos } 72 1.3 christos 73 1.1 christos /* Create a 68HC11/68HC12 ELF linker hash table. */ 74 1.1 christos 75 1.1 christos struct m68hc11_elf_link_hash_table* 76 1.1 christos m68hc11_elf_hash_table_create (bfd *abfd) 77 1.1 christos { 78 1.1 christos struct m68hc11_elf_link_hash_table *ret; 79 1.8 christos size_t amt = sizeof (struct m68hc11_elf_link_hash_table); 80 1.1 christos 81 1.3 christos ret = (struct m68hc11_elf_link_hash_table *) bfd_zmalloc (amt); 82 1.1 christos if (ret == (struct m68hc11_elf_link_hash_table *) NULL) 83 1.1 christos return NULL; 84 1.1 christos 85 1.1 christos if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, 86 1.1 christos _bfd_elf_link_hash_newfunc, 87 1.10 christos sizeof (struct elf_link_hash_entry))) 88 1.1 christos { 89 1.1 christos free (ret); 90 1.1 christos return NULL; 91 1.1 christos } 92 1.1 christos 93 1.1 christos /* Init the stub hash table too. */ 94 1.1 christos amt = sizeof (struct bfd_hash_table); 95 1.1 christos ret->stub_hash_table = (struct bfd_hash_table*) bfd_malloc (amt); 96 1.1 christos if (ret->stub_hash_table == NULL) 97 1.1 christos { 98 1.3 christos _bfd_elf_link_hash_table_free (abfd); 99 1.1 christos return NULL; 100 1.1 christos } 101 1.1 christos if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc, 102 1.1 christos sizeof (struct elf32_m68hc11_stub_hash_entry))) 103 1.3 christos { 104 1.3 christos free (ret->stub_hash_table); 105 1.3 christos _bfd_elf_link_hash_table_free (abfd); 106 1.3 christos return NULL; 107 1.3 christos } 108 1.3 christos ret->root.root.hash_table_free = m68hc11_elf_bfd_link_hash_table_free; 109 1.1 christos 110 1.1 christos return ret; 111 1.1 christos } 112 1.1 christos 113 1.1 christos /* Assorted hash table functions. */ 114 1.1 christos 115 1.1 christos /* Initialize an entry in the stub hash table. */ 116 1.1 christos 117 1.1 christos static struct bfd_hash_entry * 118 1.1 christos stub_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table, 119 1.6 christos const char *string) 120 1.1 christos { 121 1.1 christos /* Allocate the structure if it has not already been allocated by a 122 1.1 christos subclass. */ 123 1.1 christos if (entry == NULL) 124 1.1 christos { 125 1.1 christos entry = bfd_hash_allocate (table, 126 1.1 christos sizeof (struct elf32_m68hc11_stub_hash_entry)); 127 1.1 christos if (entry == NULL) 128 1.1 christos return entry; 129 1.1 christos } 130 1.1 christos 131 1.1 christos /* Call the allocation method of the superclass. */ 132 1.1 christos entry = bfd_hash_newfunc (entry, table, string); 133 1.1 christos if (entry != NULL) 134 1.1 christos { 135 1.1 christos struct elf32_m68hc11_stub_hash_entry *eh; 136 1.1 christos 137 1.1 christos /* Initialize the local fields. */ 138 1.1 christos eh = (struct elf32_m68hc11_stub_hash_entry *) entry; 139 1.1 christos eh->stub_sec = NULL; 140 1.1 christos eh->stub_offset = 0; 141 1.1 christos eh->target_value = 0; 142 1.1 christos eh->target_section = NULL; 143 1.1 christos } 144 1.1 christos 145 1.1 christos return entry; 146 1.1 christos } 147 1.1 christos 148 1.1 christos /* Add a new stub entry to the stub hash. Not all fields of the new 149 1.1 christos stub entry are initialised. */ 150 1.1 christos 151 1.1 christos static struct elf32_m68hc11_stub_hash_entry * 152 1.1 christos m68hc12_add_stub (const char *stub_name, asection *section, 153 1.6 christos struct m68hc11_elf_link_hash_table *htab) 154 1.1 christos { 155 1.1 christos struct elf32_m68hc11_stub_hash_entry *stub_entry; 156 1.1 christos 157 1.1 christos /* Enter this entry into the linker stub hash table. */ 158 1.1 christos stub_entry = m68hc12_stub_hash_lookup (htab->stub_hash_table, stub_name, 159 1.8 christos true, false); 160 1.1 christos if (stub_entry == NULL) 161 1.1 christos { 162 1.6 christos /* xgettext:c-format */ 163 1.6 christos _bfd_error_handler (_("%pB: cannot create stub entry %s"), 164 1.6 christos section->owner, stub_name); 165 1.1 christos return NULL; 166 1.1 christos } 167 1.1 christos 168 1.1 christos if (htab->stub_section == 0) 169 1.1 christos { 170 1.1 christos htab->stub_section = (*htab->add_stub_section) (".tramp", 171 1.6 christos htab->tramp_section); 172 1.1 christos } 173 1.1 christos 174 1.1 christos stub_entry->stub_sec = htab->stub_section; 175 1.1 christos stub_entry->stub_offset = 0; 176 1.1 christos return stub_entry; 177 1.1 christos } 178 1.1 christos 179 1.1 christos /* Hook called by the linker routine which adds symbols from an object 180 1.1 christos file. We use it for identify far symbols and force a loading of 181 1.1 christos the trampoline handler. */ 182 1.1 christos 183 1.8 christos bool 184 1.1 christos elf32_m68hc11_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, 185 1.6 christos Elf_Internal_Sym *sym, 186 1.6 christos const char **namep ATTRIBUTE_UNUSED, 187 1.6 christos flagword *flagsp ATTRIBUTE_UNUSED, 188 1.6 christos asection **secp ATTRIBUTE_UNUSED, 189 1.6 christos bfd_vma *valp ATTRIBUTE_UNUSED) 190 1.1 christos { 191 1.1 christos if (sym->st_other & STO_M68HC12_FAR) 192 1.1 christos { 193 1.1 christos struct elf_link_hash_entry *h; 194 1.1 christos 195 1.1 christos h = (struct elf_link_hash_entry *) 196 1.1 christos bfd_link_hash_lookup (info->hash, "__far_trampoline", 197 1.8 christos false, false, false); 198 1.1 christos if (h == NULL) 199 1.6 christos { 200 1.6 christos struct bfd_link_hash_entry* entry = NULL; 201 1.1 christos 202 1.6 christos _bfd_generic_link_add_one_symbol (info, abfd, 203 1.6 christos "__far_trampoline", 204 1.6 christos BSF_GLOBAL, 205 1.6 christos bfd_und_section_ptr, 206 1.6 christos (bfd_vma) 0, (const char*) NULL, 207 1.8 christos false, false, &entry); 208 1.6 christos } 209 1.1 christos 210 1.1 christos } 211 1.8 christos return true; 212 1.1 christos } 213 1.1 christos 214 1.1 christos /* Merge non-visibility st_other attributes, STO_M68HC12_FAR and 215 1.1 christos STO_M68HC12_INTERRUPT. */ 216 1.1 christos 217 1.1 christos void 218 1.1 christos elf32_m68hc11_merge_symbol_attribute (struct elf_link_hash_entry *h, 219 1.8 christos unsigned int st_other, 220 1.8 christos bool definition, 221 1.8 christos bool dynamic ATTRIBUTE_UNUSED) 222 1.1 christos { 223 1.1 christos if (definition) 224 1.8 christos h->other = ((st_other & ~ELF_ST_VISIBILITY (-1)) 225 1.1 christos | ELF_ST_VISIBILITY (h->other)); 226 1.1 christos } 227 1.1 christos 228 1.1 christos /* External entry points for sizing and building linker stubs. */ 229 1.1 christos 230 1.1 christos /* Set up various things so that we can make a list of input sections 231 1.1 christos for each output section included in the link. Returns -1 on error, 232 1.1 christos 0 when no stubs will be needed, and 1 on success. */ 233 1.1 christos 234 1.1 christos int 235 1.1 christos elf32_m68hc11_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info) 236 1.1 christos { 237 1.1 christos bfd *input_bfd; 238 1.1 christos unsigned int bfd_count; 239 1.3 christos unsigned int top_id, top_index; 240 1.1 christos asection *section; 241 1.1 christos asection **input_list, **list; 242 1.8 christos size_t amt; 243 1.1 christos asection *text_section; 244 1.1 christos struct m68hc11_elf_link_hash_table *htab; 245 1.1 christos 246 1.1 christos htab = m68hc11_elf_hash_table (info); 247 1.1 christos if (htab == NULL) 248 1.1 christos return -1; 249 1.1 christos 250 1.1 christos if (bfd_get_flavour (info->output_bfd) != bfd_target_elf_flavour) 251 1.1 christos return 0; 252 1.1 christos 253 1.1 christos /* Count the number of input BFDs and find the top input section id. 254 1.1 christos Also search for an existing ".tramp" section so that we know 255 1.1 christos where generated trampolines must go. Default to ".text" if we 256 1.1 christos can't find it. */ 257 1.1 christos htab->tramp_section = 0; 258 1.1 christos text_section = 0; 259 1.1 christos for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0; 260 1.1 christos input_bfd != NULL; 261 1.3 christos input_bfd = input_bfd->link.next) 262 1.1 christos { 263 1.1 christos bfd_count += 1; 264 1.1 christos for (section = input_bfd->sections; 265 1.1 christos section != NULL; 266 1.1 christos section = section->next) 267 1.1 christos { 268 1.7 christos const char *name = bfd_section_name (section); 269 1.1 christos 270 1.6 christos if (!strcmp (name, ".tramp")) 271 1.6 christos htab->tramp_section = section; 272 1.1 christos 273 1.6 christos if (!strcmp (name, ".text")) 274 1.6 christos text_section = section; 275 1.1 christos 276 1.1 christos if (top_id < section->id) 277 1.1 christos top_id = section->id; 278 1.1 christos } 279 1.1 christos } 280 1.1 christos htab->bfd_count = bfd_count; 281 1.1 christos if (htab->tramp_section == 0) 282 1.1 christos htab->tramp_section = text_section; 283 1.1 christos 284 1.1 christos /* We can't use output_bfd->section_count here to find the top output 285 1.1 christos section index as some sections may have been removed, and 286 1.1 christos strip_excluded_output_sections doesn't renumber the indices. */ 287 1.1 christos for (section = output_bfd->sections, top_index = 0; 288 1.1 christos section != NULL; 289 1.1 christos section = section->next) 290 1.1 christos { 291 1.1 christos if (top_index < section->index) 292 1.1 christos top_index = section->index; 293 1.1 christos } 294 1.1 christos 295 1.1 christos htab->top_index = top_index; 296 1.1 christos amt = sizeof (asection *) * (top_index + 1); 297 1.1 christos input_list = (asection **) bfd_malloc (amt); 298 1.1 christos htab->input_list = input_list; 299 1.1 christos if (input_list == NULL) 300 1.1 christos return -1; 301 1.1 christos 302 1.1 christos /* For sections we aren't interested in, mark their entries with a 303 1.1 christos value we can check later. */ 304 1.1 christos list = input_list + top_index; 305 1.1 christos do 306 1.1 christos *list = bfd_abs_section_ptr; 307 1.1 christos while (list-- != input_list); 308 1.1 christos 309 1.1 christos for (section = output_bfd->sections; 310 1.1 christos section != NULL; 311 1.1 christos section = section->next) 312 1.1 christos { 313 1.1 christos if ((section->flags & SEC_CODE) != 0) 314 1.1 christos input_list[section->index] = NULL; 315 1.1 christos } 316 1.1 christos 317 1.1 christos return 1; 318 1.1 christos } 319 1.1 christos 320 1.1 christos /* Determine and set the size of the stub section for a final link. 321 1.1 christos 322 1.1 christos The basic idea here is to examine all the relocations looking for 323 1.1 christos PC-relative calls to a target that is unreachable with a "bl" 324 1.1 christos instruction. */ 325 1.1 christos 326 1.8 christos bool 327 1.1 christos elf32_m68hc11_size_stubs (bfd *output_bfd, bfd *stub_bfd, 328 1.6 christos struct bfd_link_info *info, 329 1.6 christos asection * (*add_stub_section) (const char*, asection*)) 330 1.1 christos { 331 1.1 christos bfd *input_bfd; 332 1.1 christos asection *section; 333 1.1 christos Elf_Internal_Sym *local_syms, **all_local_syms; 334 1.1 christos unsigned int bfd_indx, bfd_count; 335 1.8 christos size_t amt; 336 1.1 christos asection *stub_sec; 337 1.1 christos struct m68hc11_elf_link_hash_table *htab = m68hc11_elf_hash_table (info); 338 1.1 christos 339 1.1 christos if (htab == NULL) 340 1.8 christos return false; 341 1.1 christos 342 1.1 christos /* Stash our params away. */ 343 1.1 christos htab->stub_bfd = stub_bfd; 344 1.1 christos htab->add_stub_section = add_stub_section; 345 1.1 christos 346 1.1 christos /* Count the number of input BFDs and find the top input section id. */ 347 1.1 christos for (input_bfd = info->input_bfds, bfd_count = 0; 348 1.1 christos input_bfd != NULL; 349 1.3 christos input_bfd = input_bfd->link.next) 350 1.1 christos bfd_count += 1; 351 1.1 christos 352 1.1 christos /* We want to read in symbol extension records only once. To do this 353 1.1 christos we need to read in the local symbols in parallel and save them for 354 1.1 christos later use; so hold pointers to the local symbols in an array. */ 355 1.1 christos amt = sizeof (Elf_Internal_Sym *) * bfd_count; 356 1.1 christos all_local_syms = (Elf_Internal_Sym **) bfd_zmalloc (amt); 357 1.1 christos if (all_local_syms == NULL) 358 1.8 christos return false; 359 1.1 christos 360 1.1 christos /* Walk over all the input BFDs, swapping in local symbols. */ 361 1.1 christos for (input_bfd = info->input_bfds, bfd_indx = 0; 362 1.1 christos input_bfd != NULL; 363 1.3 christos input_bfd = input_bfd->link.next, bfd_indx++) 364 1.1 christos { 365 1.1 christos Elf_Internal_Shdr *symtab_hdr; 366 1.1 christos 367 1.1 christos /* We'll need the symbol table in a second. */ 368 1.1 christos symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 369 1.1 christos if (symtab_hdr->sh_info == 0) 370 1.1 christos continue; 371 1.1 christos 372 1.1 christos /* We need an array of the local symbols attached to the input bfd. */ 373 1.1 christos local_syms = (Elf_Internal_Sym *) symtab_hdr->contents; 374 1.1 christos if (local_syms == NULL) 375 1.1 christos { 376 1.1 christos local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, 377 1.1 christos symtab_hdr->sh_info, 0, 378 1.1 christos NULL, NULL, NULL); 379 1.1 christos /* Cache them for elf_link_input_bfd. */ 380 1.1 christos symtab_hdr->contents = (unsigned char *) local_syms; 381 1.1 christos } 382 1.1 christos if (local_syms == NULL) 383 1.6 christos { 384 1.6 christos free (all_local_syms); 385 1.8 christos return false; 386 1.6 christos } 387 1.1 christos 388 1.1 christos all_local_syms[bfd_indx] = local_syms; 389 1.1 christos } 390 1.1 christos 391 1.1 christos for (input_bfd = info->input_bfds, bfd_indx = 0; 392 1.1 christos input_bfd != NULL; 393 1.3 christos input_bfd = input_bfd->link.next, bfd_indx++) 394 1.1 christos { 395 1.1 christos Elf_Internal_Shdr *symtab_hdr; 396 1.1 christos struct elf_link_hash_entry ** sym_hashes; 397 1.1 christos 398 1.1 christos sym_hashes = elf_sym_hashes (input_bfd); 399 1.1 christos 400 1.1 christos /* We'll need the symbol table in a second. */ 401 1.1 christos symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 402 1.1 christos if (symtab_hdr->sh_info == 0) 403 1.6 christos continue; 404 1.1 christos 405 1.1 christos local_syms = all_local_syms[bfd_indx]; 406 1.1 christos 407 1.1 christos /* Walk over each section attached to the input bfd. */ 408 1.1 christos for (section = input_bfd->sections; 409 1.6 christos section != NULL; 410 1.6 christos section = section->next) 411 1.6 christos { 412 1.6 christos Elf_Internal_Rela *internal_relocs, *irelaend, *irela; 413 1.6 christos 414 1.6 christos /* If there aren't any relocs, then there's nothing more 415 1.6 christos to do. */ 416 1.6 christos if ((section->flags & SEC_RELOC) == 0 417 1.6 christos || section->reloc_count == 0) 418 1.6 christos continue; 419 1.6 christos 420 1.6 christos /* If this section is a link-once section that will be 421 1.6 christos discarded, then don't create any stubs. */ 422 1.6 christos if (section->output_section == NULL 423 1.6 christos || section->output_section->owner != output_bfd) 424 1.6 christos continue; 425 1.6 christos 426 1.6 christos /* Get the relocs. */ 427 1.6 christos internal_relocs 428 1.6 christos = _bfd_elf_link_read_relocs (input_bfd, section, NULL, 429 1.1 christos (Elf_Internal_Rela *) NULL, 430 1.1 christos info->keep_memory); 431 1.6 christos if (internal_relocs == NULL) 432 1.6 christos goto error_ret_free_local; 433 1.1 christos 434 1.6 christos /* Now examine each relocation. */ 435 1.6 christos irela = internal_relocs; 436 1.6 christos irelaend = irela + section->reloc_count; 437 1.6 christos for (; irela < irelaend; irela++) 438 1.6 christos { 439 1.6 christos unsigned int r_type, r_indx; 440 1.6 christos struct elf32_m68hc11_stub_hash_entry *stub_entry; 441 1.6 christos asection *sym_sec; 442 1.6 christos bfd_vma sym_value; 443 1.6 christos struct elf_link_hash_entry *hash; 444 1.6 christos const char *stub_name; 445 1.6 christos Elf_Internal_Sym *sym; 446 1.6 christos 447 1.6 christos r_type = ELF32_R_TYPE (irela->r_info); 448 1.6 christos 449 1.6 christos /* Only look at 16-bit relocs. */ 450 1.6 christos if (r_type != (unsigned int) R_M68HC11_16) 451 1.6 christos continue; 452 1.6 christos 453 1.6 christos /* Now determine the call target, its name, value, 454 1.6 christos section. */ 455 1.6 christos r_indx = ELF32_R_SYM (irela->r_info); 456 1.6 christos if (r_indx < symtab_hdr->sh_info) 457 1.6 christos { 458 1.6 christos /* It's a local symbol. */ 459 1.6 christos Elf_Internal_Shdr *hdr; 460 1.8 christos bool is_far; 461 1.6 christos 462 1.6 christos sym = local_syms + r_indx; 463 1.6 christos is_far = (sym && (sym->st_other & STO_M68HC12_FAR)); 464 1.6 christos if (!is_far) 465 1.6 christos continue; 466 1.1 christos 467 1.1 christos if (sym->st_shndx >= elf_numsections (input_bfd)) 468 1.1 christos sym_sec = NULL; 469 1.1 christos else 470 1.1 christos { 471 1.1 christos hdr = elf_elfsections (input_bfd)[sym->st_shndx]; 472 1.1 christos sym_sec = hdr->bfd_section; 473 1.1 christos } 474 1.6 christos stub_name = (bfd_elf_string_from_elf_section 475 1.6 christos (input_bfd, symtab_hdr->sh_link, 476 1.6 christos sym->st_name)); 477 1.6 christos sym_value = sym->st_value; 478 1.6 christos hash = NULL; 479 1.6 christos } 480 1.6 christos else 481 1.6 christos { 482 1.6 christos /* It's an external symbol. */ 483 1.6 christos int e_indx; 484 1.6 christos 485 1.6 christos e_indx = r_indx - symtab_hdr->sh_info; 486 1.6 christos hash = (struct elf_link_hash_entry *) 487 1.6 christos (sym_hashes[e_indx]); 488 1.6 christos 489 1.6 christos while (hash->root.type == bfd_link_hash_indirect 490 1.6 christos || hash->root.type == bfd_link_hash_warning) 491 1.6 christos hash = ((struct elf_link_hash_entry *) 492 1.6 christos hash->root.u.i.link); 493 1.6 christos 494 1.6 christos if (hash->root.type == bfd_link_hash_defined 495 1.6 christos || hash->root.type == bfd_link_hash_defweak 496 1.6 christos || hash->root.type == bfd_link_hash_new) 497 1.6 christos { 498 1.6 christos if (!(hash->other & STO_M68HC12_FAR)) 499 1.6 christos continue; 500 1.6 christos } 501 1.6 christos else if (hash->root.type == bfd_link_hash_undefweak) 502 1.6 christos { 503 1.6 christos continue; 504 1.6 christos } 505 1.6 christos else if (hash->root.type == bfd_link_hash_undefined) 506 1.6 christos { 507 1.6 christos continue; 508 1.6 christos } 509 1.6 christos else 510 1.6 christos { 511 1.6 christos bfd_set_error (bfd_error_bad_value); 512 1.6 christos goto error_ret_free_internal; 513 1.6 christos } 514 1.6 christos sym_sec = hash->root.u.def.section; 515 1.6 christos sym_value = hash->root.u.def.value; 516 1.6 christos stub_name = hash->root.root.string; 517 1.6 christos } 518 1.6 christos 519 1.6 christos if (!stub_name) 520 1.6 christos goto error_ret_free_internal; 521 1.6 christos 522 1.6 christos stub_entry = m68hc12_stub_hash_lookup 523 1.6 christos (htab->stub_hash_table, 524 1.6 christos stub_name, 525 1.8 christos false, false); 526 1.6 christos if (stub_entry == NULL) 527 1.6 christos { 528 1.6 christos if (add_stub_section == 0) 529 1.6 christos continue; 530 1.6 christos 531 1.6 christos stub_entry = m68hc12_add_stub (stub_name, section, htab); 532 1.6 christos if (stub_entry == NULL) 533 1.6 christos { 534 1.6 christos error_ret_free_internal: 535 1.6 christos if (elf_section_data (section)->relocs == NULL) 536 1.6 christos free (internal_relocs); 537 1.6 christos goto error_ret_free_local; 538 1.6 christos } 539 1.6 christos } 540 1.6 christos 541 1.6 christos stub_entry->target_value = sym_value; 542 1.6 christos stub_entry->target_section = sym_sec; 543 1.6 christos } 544 1.6 christos 545 1.6 christos /* We're done with the internal relocs, free them. */ 546 1.6 christos if (elf_section_data (section)->relocs == NULL) 547 1.6 christos free (internal_relocs); 548 1.6 christos } 549 1.1 christos } 550 1.1 christos 551 1.1 christos if (add_stub_section) 552 1.1 christos { 553 1.1 christos /* OK, we've added some stubs. Find out the new size of the 554 1.6 christos stub sections. */ 555 1.1 christos for (stub_sec = htab->stub_bfd->sections; 556 1.6 christos stub_sec != NULL; 557 1.6 christos stub_sec = stub_sec->next) 558 1.6 christos { 559 1.6 christos stub_sec->size = 0; 560 1.6 christos } 561 1.1 christos 562 1.1 christos bfd_hash_traverse (htab->stub_hash_table, htab->size_one_stub, htab); 563 1.1 christos } 564 1.1 christos free (all_local_syms); 565 1.8 christos return true; 566 1.1 christos 567 1.1 christos error_ret_free_local: 568 1.1 christos free (all_local_syms); 569 1.8 christos return false; 570 1.1 christos } 571 1.1 christos 572 1.1 christos /* Export the trampoline addresses in the symbol table. */ 573 1.8 christos static bool 574 1.1 christos m68hc11_elf_export_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) 575 1.1 christos { 576 1.1 christos struct bfd_link_info *info; 577 1.1 christos struct m68hc11_elf_link_hash_table *htab; 578 1.1 christos struct elf32_m68hc11_stub_hash_entry *stub_entry; 579 1.1 christos char* name; 580 1.8 christos bool result; 581 1.1 christos 582 1.1 christos info = (struct bfd_link_info *) in_arg; 583 1.1 christos htab = m68hc11_elf_hash_table (info); 584 1.1 christos if (htab == NULL) 585 1.8 christos return false; 586 1.1 christos 587 1.1 christos /* Massage our args to the form they really have. */ 588 1.1 christos stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry; 589 1.1 christos 590 1.1 christos /* Generate the trampoline according to HC11 or HC12. */ 591 1.1 christos result = (* htab->build_one_stub) (gen_entry, in_arg); 592 1.1 christos 593 1.1 christos /* Make a printable name that does not conflict with the real function. */ 594 1.5 christos name = concat ("tramp.", stub_entry->root.string, NULL); 595 1.1 christos 596 1.1 christos /* Export the symbol for debugging/disassembling. */ 597 1.1 christos m68hc11_elf_set_symbol (htab->stub_bfd, info, name, 598 1.6 christos stub_entry->stub_offset, 599 1.6 christos stub_entry->stub_sec); 600 1.5 christos free (name); 601 1.1 christos return result; 602 1.1 christos } 603 1.1 christos 604 1.1 christos /* Export a symbol or set its value and section. */ 605 1.1 christos static void 606 1.1 christos m68hc11_elf_set_symbol (bfd *abfd, struct bfd_link_info *info, 607 1.6 christos const char *name, bfd_vma value, asection *sec) 608 1.1 christos { 609 1.1 christos struct elf_link_hash_entry *h; 610 1.1 christos 611 1.1 christos h = (struct elf_link_hash_entry *) 612 1.8 christos bfd_link_hash_lookup (info->hash, name, false, false, false); 613 1.1 christos if (h == NULL) 614 1.1 christos { 615 1.1 christos _bfd_generic_link_add_one_symbol (info, abfd, 616 1.6 christos name, 617 1.6 christos BSF_GLOBAL, 618 1.6 christos sec, 619 1.6 christos value, 620 1.6 christos (const char*) NULL, 621 1.8 christos true, false, NULL); 622 1.1 christos } 623 1.1 christos else 624 1.1 christos { 625 1.1 christos h->root.type = bfd_link_hash_defined; 626 1.1 christos h->root.u.def.value = value; 627 1.1 christos h->root.u.def.section = sec; 628 1.1 christos } 629 1.1 christos } 630 1.1 christos 631 1.1 christos 632 1.1 christos /* Build all the stubs associated with the current output file. The 633 1.1 christos stubs are kept in a hash table attached to the main linker hash 634 1.1 christos table. This function is called via m68hc12elf_finish in the 635 1.1 christos linker. */ 636 1.1 christos 637 1.8 christos bool 638 1.1 christos elf32_m68hc11_build_stubs (bfd *abfd, struct bfd_link_info *info) 639 1.1 christos { 640 1.1 christos asection *stub_sec; 641 1.1 christos struct bfd_hash_table *table; 642 1.1 christos struct m68hc11_elf_link_hash_table *htab; 643 1.1 christos struct m68hc11_scan_param param; 644 1.1 christos 645 1.1 christos m68hc11_elf_get_bank_parameters (info); 646 1.1 christos htab = m68hc11_elf_hash_table (info); 647 1.1 christos if (htab == NULL) 648 1.8 christos return false; 649 1.1 christos 650 1.1 christos for (stub_sec = htab->stub_bfd->sections; 651 1.1 christos stub_sec != NULL; 652 1.1 christos stub_sec = stub_sec->next) 653 1.1 christos { 654 1.1 christos bfd_size_type size; 655 1.1 christos 656 1.1 christos /* Allocate memory to hold the linker stubs. */ 657 1.1 christos size = stub_sec->size; 658 1.1 christos stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size); 659 1.1 christos if (stub_sec->contents == NULL && size != 0) 660 1.8 christos return false; 661 1.10 christos stub_sec->alloced = 1; 662 1.1 christos stub_sec->size = 0; 663 1.1 christos } 664 1.1 christos 665 1.1 christos /* Build the stubs as directed by the stub hash table. */ 666 1.1 christos table = htab->stub_hash_table; 667 1.1 christos bfd_hash_traverse (table, m68hc11_elf_export_one_stub, info); 668 1.3 christos 669 1.1 christos /* Scan the output sections to see if we use the memory banks. 670 1.1 christos If so, export the symbols that define how the memory banks 671 1.1 christos are mapped. This is used by gdb and the simulator to obtain 672 1.1 christos the information. It can be used by programs to burn the eprom 673 1.1 christos at the good addresses. */ 674 1.8 christos param.use_memory_banks = false; 675 1.1 christos param.pinfo = &htab->pinfo; 676 1.1 christos bfd_map_over_sections (abfd, scan_sections_for_abi, ¶m); 677 1.1 christos if (param.use_memory_banks) 678 1.1 christos { 679 1.1 christos m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_START_NAME, 680 1.6 christos htab->pinfo.bank_physical, 681 1.6 christos bfd_abs_section_ptr); 682 1.1 christos m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_VIRTUAL_NAME, 683 1.6 christos htab->pinfo.bank_virtual, 684 1.6 christos bfd_abs_section_ptr); 685 1.1 christos m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_SIZE_NAME, 686 1.6 christos htab->pinfo.bank_size, 687 1.6 christos bfd_abs_section_ptr); 688 1.1 christos } 689 1.1 christos 690 1.8 christos return true; 691 1.1 christos } 692 1.1 christos 693 1.1 christos void 694 1.1 christos m68hc11_elf_get_bank_parameters (struct bfd_link_info *info) 695 1.1 christos { 696 1.1 christos unsigned i; 697 1.1 christos struct m68hc11_page_info *pinfo; 698 1.1 christos struct bfd_link_hash_entry *h; 699 1.1 christos struct m68hc11_elf_link_hash_table *htab; 700 1.1 christos 701 1.1 christos htab = m68hc11_elf_hash_table (info); 702 1.1 christos if (htab == NULL) 703 1.1 christos return; 704 1.1 christos 705 1.1 christos pinfo = & htab->pinfo; 706 1.1 christos if (pinfo->bank_param_initialized) 707 1.1 christos return; 708 1.1 christos 709 1.1 christos pinfo->bank_virtual = M68HC12_BANK_VIRT; 710 1.1 christos pinfo->bank_mask = M68HC12_BANK_MASK; 711 1.1 christos pinfo->bank_physical = M68HC12_BANK_BASE; 712 1.1 christos pinfo->bank_shift = M68HC12_BANK_SHIFT; 713 1.1 christos pinfo->bank_size = 1 << M68HC12_BANK_SHIFT; 714 1.1 christos 715 1.1 christos h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_START_NAME, 716 1.8 christos false, false, true); 717 1.1 christos if (h != (struct bfd_link_hash_entry*) NULL 718 1.1 christos && h->type == bfd_link_hash_defined) 719 1.1 christos pinfo->bank_physical = (h->u.def.value 720 1.6 christos + h->u.def.section->output_section->vma 721 1.6 christos + h->u.def.section->output_offset); 722 1.1 christos 723 1.1 christos h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_VIRTUAL_NAME, 724 1.8 christos false, false, true); 725 1.1 christos if (h != (struct bfd_link_hash_entry*) NULL 726 1.1 christos && h->type == bfd_link_hash_defined) 727 1.1 christos pinfo->bank_virtual = (h->u.def.value 728 1.6 christos + h->u.def.section->output_section->vma 729 1.6 christos + h->u.def.section->output_offset); 730 1.1 christos 731 1.1 christos h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_SIZE_NAME, 732 1.8 christos false, false, true); 733 1.1 christos if (h != (struct bfd_link_hash_entry*) NULL 734 1.1 christos && h->type == bfd_link_hash_defined) 735 1.1 christos pinfo->bank_size = (h->u.def.value 736 1.6 christos + h->u.def.section->output_section->vma 737 1.6 christos + h->u.def.section->output_offset); 738 1.1 christos 739 1.1 christos pinfo->bank_shift = 0; 740 1.1 christos for (i = pinfo->bank_size; i != 0; i >>= 1) 741 1.1 christos pinfo->bank_shift++; 742 1.1 christos pinfo->bank_shift--; 743 1.1 christos pinfo->bank_mask = (1 << pinfo->bank_shift) - 1; 744 1.1 christos pinfo->bank_physical_end = pinfo->bank_physical + pinfo->bank_size; 745 1.1 christos pinfo->bank_param_initialized = 1; 746 1.1 christos 747 1.8 christos h = bfd_link_hash_lookup (info->hash, "__far_trampoline", false, 748 1.8 christos false, true); 749 1.1 christos if (h != (struct bfd_link_hash_entry*) NULL 750 1.1 christos && h->type == bfd_link_hash_defined) 751 1.1 christos pinfo->trampoline_addr = (h->u.def.value 752 1.6 christos + h->u.def.section->output_section->vma 753 1.6 christos + h->u.def.section->output_offset); 754 1.1 christos } 755 1.1 christos 756 1.1 christos /* Return 1 if the address is in banked memory. 757 1.1 christos This can be applied to a virtual address and to a physical address. */ 758 1.1 christos int 759 1.1 christos m68hc11_addr_is_banked (struct m68hc11_page_info *pinfo, bfd_vma addr) 760 1.1 christos { 761 1.1 christos if (addr >= pinfo->bank_virtual) 762 1.1 christos return 1; 763 1.1 christos 764 1.1 christos if (addr >= pinfo->bank_physical && addr <= pinfo->bank_physical_end) 765 1.1 christos return 1; 766 1.1 christos 767 1.1 christos return 0; 768 1.1 christos } 769 1.1 christos 770 1.1 christos /* Return the physical address seen by the processor, taking 771 1.1 christos into account banked memory. */ 772 1.1 christos bfd_vma 773 1.1 christos m68hc11_phys_addr (struct m68hc11_page_info *pinfo, bfd_vma addr) 774 1.1 christos { 775 1.1 christos if (addr < pinfo->bank_virtual) 776 1.1 christos return addr; 777 1.1 christos 778 1.1 christos /* Map the address to the memory bank. */ 779 1.1 christos addr -= pinfo->bank_virtual; 780 1.1 christos addr &= pinfo->bank_mask; 781 1.1 christos addr += pinfo->bank_physical; 782 1.1 christos return addr; 783 1.1 christos } 784 1.1 christos 785 1.1 christos /* Return the page number corresponding to an address in banked memory. */ 786 1.1 christos bfd_vma 787 1.1 christos m68hc11_phys_page (struct m68hc11_page_info *pinfo, bfd_vma addr) 788 1.1 christos { 789 1.1 christos if (addr < pinfo->bank_virtual) 790 1.1 christos return 0; 791 1.1 christos 792 1.1 christos /* Map the address to the memory bank. */ 793 1.1 christos addr -= pinfo->bank_virtual; 794 1.1 christos addr >>= pinfo->bank_shift; 795 1.1 christos addr &= 0x0ff; 796 1.1 christos return addr; 797 1.1 christos } 798 1.1 christos 799 1.1 christos /* This function is used for relocs which are only used for relaxing, 800 1.1 christos which the linker should otherwise ignore. */ 801 1.1 christos 802 1.1 christos bfd_reloc_status_type 803 1.1 christos m68hc11_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, 804 1.6 christos arelent *reloc_entry, 805 1.6 christos asymbol *symbol ATTRIBUTE_UNUSED, 806 1.6 christos void *data ATTRIBUTE_UNUSED, 807 1.6 christos asection *input_section, 808 1.6 christos bfd *output_bfd, 809 1.6 christos char **error_message ATTRIBUTE_UNUSED) 810 1.1 christos { 811 1.1 christos if (output_bfd != NULL) 812 1.1 christos reloc_entry->address += input_section->output_offset; 813 1.1 christos return bfd_reloc_ok; 814 1.1 christos } 815 1.1 christos 816 1.1 christos bfd_reloc_status_type 817 1.1 christos m68hc11_elf_special_reloc (bfd *abfd ATTRIBUTE_UNUSED, 818 1.6 christos arelent *reloc_entry, 819 1.6 christos asymbol *symbol, 820 1.6 christos void *data ATTRIBUTE_UNUSED, 821 1.6 christos asection *input_section, 822 1.6 christos bfd *output_bfd, 823 1.6 christos char **error_message ATTRIBUTE_UNUSED) 824 1.1 christos { 825 1.1 christos if (output_bfd != (bfd *) NULL 826 1.1 christos && (symbol->flags & BSF_SECTION_SYM) == 0 827 1.1 christos && (! reloc_entry->howto->partial_inplace 828 1.1 christos || reloc_entry->addend == 0)) 829 1.1 christos { 830 1.1 christos reloc_entry->address += input_section->output_offset; 831 1.1 christos return bfd_reloc_ok; 832 1.1 christos } 833 1.1 christos 834 1.1 christos if (output_bfd != NULL) 835 1.1 christos return bfd_reloc_continue; 836 1.1 christos 837 1.1 christos if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) 838 1.1 christos return bfd_reloc_outofrange; 839 1.1 christos 840 1.1 christos abort(); 841 1.1 christos } 842 1.1 christos 843 1.1 christos /* Look through the relocs for a section during the first phase. 844 1.1 christos Since we don't do .gots or .plts, we just need to consider the 845 1.1 christos virtual table relocs for gc. */ 846 1.1 christos 847 1.8 christos bool 848 1.1 christos elf32_m68hc11_check_relocs (bfd *abfd, struct bfd_link_info *info, 849 1.6 christos asection *sec, const Elf_Internal_Rela *relocs) 850 1.1 christos { 851 1.6 christos Elf_Internal_Shdr * symtab_hdr; 852 1.1 christos struct elf_link_hash_entry ** sym_hashes; 853 1.6 christos const Elf_Internal_Rela * rel; 854 1.6 christos const Elf_Internal_Rela * rel_end; 855 1.1 christos 856 1.3 christos if (bfd_link_relocatable (info)) 857 1.8 christos return true; 858 1.1 christos 859 1.1 christos symtab_hdr = & elf_tdata (abfd)->symtab_hdr; 860 1.1 christos sym_hashes = elf_sym_hashes (abfd); 861 1.1 christos rel_end = relocs + sec->reloc_count; 862 1.1 christos 863 1.1 christos for (rel = relocs; rel < rel_end; rel++) 864 1.1 christos { 865 1.1 christos struct elf_link_hash_entry * h; 866 1.1 christos unsigned long r_symndx; 867 1.1 christos 868 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info); 869 1.1 christos 870 1.1 christos if (r_symndx < symtab_hdr->sh_info) 871 1.6 christos h = NULL; 872 1.1 christos else 873 1.1 christos { 874 1.1 christos h = sym_hashes [r_symndx - symtab_hdr->sh_info]; 875 1.1 christos while (h->root.type == bfd_link_hash_indirect 876 1.1 christos || h->root.type == bfd_link_hash_warning) 877 1.1 christos h = (struct elf_link_hash_entry *) h->root.u.i.link; 878 1.1 christos } 879 1.1 christos 880 1.1 christos switch (ELF32_R_TYPE (rel->r_info)) 881 1.6 christos { 882 1.6 christos /* This relocation describes the C++ object vtable hierarchy. 883 1.6 christos Reconstruct it for later use during GC. */ 884 1.6 christos case R_M68HC11_GNU_VTINHERIT: 885 1.6 christos if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) 886 1.8 christos return false; 887 1.6 christos break; 888 1.6 christos 889 1.6 christos /* This relocation describes which C++ vtable entries are actually 890 1.6 christos used. Record for later use during GC. */ 891 1.6 christos case R_M68HC11_GNU_VTENTRY: 892 1.7 christos if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) 893 1.8 christos return false; 894 1.6 christos break; 895 1.6 christos } 896 1.1 christos } 897 1.1 christos 898 1.8 christos return true; 899 1.1 christos } 900 1.1 christos 901 1.8 christos static bool ATTRIBUTE_PRINTF (6, 7) 902 1.7 christos reloc_warning (struct bfd_link_info *info, const char *name, bfd *input_bfd, 903 1.7 christos asection *input_section, const Elf_Internal_Rela *rel, 904 1.7 christos const char *fmt, ...) 905 1.7 christos { 906 1.7 christos va_list ap; 907 1.7 christos char *buf; 908 1.7 christos int ret; 909 1.7 christos 910 1.7 christos va_start (ap, fmt); 911 1.7 christos ret = vasprintf (&buf, fmt, ap); 912 1.7 christos va_end (ap); 913 1.7 christos if (ret < 0) 914 1.7 christos { 915 1.7 christos bfd_set_error (bfd_error_no_memory); 916 1.8 christos return false; 917 1.7 christos } 918 1.7 christos info->callbacks->warning (info, buf, name, input_bfd, input_section, 919 1.7 christos rel->r_offset); 920 1.7 christos free (buf); 921 1.8 christos return true; 922 1.7 christos } 923 1.7 christos 924 1.1 christos /* Relocate a 68hc11/68hc12 ELF section. */ 925 1.8 christos int 926 1.1 christos elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, 927 1.6 christos struct bfd_link_info *info, 928 1.6 christos bfd *input_bfd, asection *input_section, 929 1.6 christos bfd_byte *contents, Elf_Internal_Rela *relocs, 930 1.6 christos Elf_Internal_Sym *local_syms, 931 1.6 christos asection **local_sections) 932 1.1 christos { 933 1.1 christos Elf_Internal_Shdr *symtab_hdr; 934 1.1 christos struct elf_link_hash_entry **sym_hashes; 935 1.1 christos Elf_Internal_Rela *rel, *relend; 936 1.1 christos const char *name = NULL; 937 1.1 christos struct m68hc11_page_info *pinfo; 938 1.1 christos const struct elf_backend_data * const ebd = get_elf_backend_data (input_bfd); 939 1.1 christos struct m68hc11_elf_link_hash_table *htab; 940 1.1 christos unsigned long e_flags; 941 1.1 christos 942 1.1 christos symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 943 1.1 christos sym_hashes = elf_sym_hashes (input_bfd); 944 1.1 christos e_flags = elf_elfheader (input_bfd)->e_flags; 945 1.1 christos 946 1.1 christos htab = m68hc11_elf_hash_table (info); 947 1.1 christos if (htab == NULL) 948 1.8 christos return false; 949 1.1 christos 950 1.1 christos /* Get memory bank parameters. */ 951 1.1 christos m68hc11_elf_get_bank_parameters (info); 952 1.1 christos 953 1.1 christos pinfo = & htab->pinfo; 954 1.1 christos rel = relocs; 955 1.1 christos relend = relocs + input_section->reloc_count; 956 1.1 christos 957 1.1 christos for (; rel < relend; rel++) 958 1.1 christos { 959 1.1 christos int r_type; 960 1.1 christos arelent arel; 961 1.1 christos reloc_howto_type *howto; 962 1.1 christos unsigned long r_symndx; 963 1.1 christos Elf_Internal_Sym *sym; 964 1.1 christos asection *sec; 965 1.1 christos bfd_vma relocation = 0; 966 1.1 christos bfd_reloc_status_type r = bfd_reloc_undefined; 967 1.1 christos bfd_vma phys_page; 968 1.1 christos bfd_vma phys_addr; 969 1.1 christos bfd_vma insn_addr; 970 1.1 christos bfd_vma insn_page; 971 1.8 christos bool is_far = false; 972 1.8 christos bool is_xgate_symbol = false; 973 1.8 christos bool is_section_symbol = false; 974 1.1 christos struct elf_link_hash_entry *h; 975 1.1 christos bfd_vma val; 976 1.7 christos const char *msg; 977 1.1 christos 978 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info); 979 1.1 christos r_type = ELF32_R_TYPE (rel->r_info); 980 1.1 christos 981 1.1 christos if (r_type == R_M68HC11_GNU_VTENTRY 982 1.6 christos || r_type == R_M68HC11_GNU_VTINHERIT) 983 1.6 christos continue; 984 1.1 christos 985 1.6 christos if (! (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel)) 986 1.6 christos continue; 987 1.1 christos howto = arel.howto; 988 1.1 christos 989 1.1 christos h = NULL; 990 1.1 christos sym = NULL; 991 1.1 christos sec = NULL; 992 1.1 christos if (r_symndx < symtab_hdr->sh_info) 993 1.1 christos { 994 1.1 christos sym = local_syms + r_symndx; 995 1.1 christos sec = local_sections[r_symndx]; 996 1.1 christos relocation = (sec->output_section->vma 997 1.1 christos + sec->output_offset 998 1.1 christos + sym->st_value); 999 1.1 christos is_far = (sym && (sym->st_other & STO_M68HC12_FAR)); 1000 1.1 christos is_xgate_symbol = (sym && (sym->st_target_internal)); 1001 1.1 christos is_section_symbol = ELF_ST_TYPE (sym->st_info) & STT_SECTION; 1002 1.1 christos } 1003 1.1 christos else 1004 1.1 christos { 1005 1.8 christos bool unresolved_reloc, warned, ignored; 1006 1.1 christos 1007 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 1008 1.1 christos r_symndx, symtab_hdr, sym_hashes, 1009 1.1 christos h, sec, relocation, unresolved_reloc, 1010 1.3 christos warned, ignored); 1011 1.1 christos 1012 1.1 christos is_far = (h && (h->other & STO_M68HC12_FAR)); 1013 1.1 christos is_xgate_symbol = (h && (h->target_internal)); 1014 1.1 christos } 1015 1.1 christos 1016 1.1 christos if (sec != NULL && discarded_section (sec)) 1017 1.1 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 1018 1.1 christos rel, 1, relend, howto, 0, contents); 1019 1.1 christos 1020 1.3 christos if (bfd_link_relocatable (info)) 1021 1.1 christos { 1022 1.1 christos /* This is a relocatable link. We don't have to change 1023 1.1 christos anything, unless the reloc is against a section symbol, 1024 1.1 christos in which case we have to adjust according to where the 1025 1.1 christos section symbol winds up in the output section. */ 1026 1.1 christos if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) 1027 1.1 christos rel->r_addend += sec->output_offset; 1028 1.1 christos continue; 1029 1.1 christos } 1030 1.1 christos 1031 1.1 christos if (h != NULL) 1032 1.1 christos name = h->root.root.string; 1033 1.1 christos else 1034 1.1 christos { 1035 1.1 christos name = (bfd_elf_string_from_elf_section 1036 1.1 christos (input_bfd, symtab_hdr->sh_link, sym->st_name)); 1037 1.1 christos if (name == NULL || *name == '\0') 1038 1.7 christos name = bfd_section_name (sec); 1039 1.1 christos } 1040 1.1 christos 1041 1.1 christos if (is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16) 1042 1.1 christos { 1043 1.1 christos struct elf32_m68hc11_stub_hash_entry* stub; 1044 1.1 christos 1045 1.1 christos stub = m68hc12_stub_hash_lookup (htab->stub_hash_table, 1046 1.8 christos name, false, false); 1047 1.1 christos if (stub) 1048 1.1 christos { 1049 1.1 christos relocation = stub->stub_offset 1050 1.1 christos + stub->stub_sec->output_section->vma 1051 1.1 christos + stub->stub_sec->output_offset; 1052 1.8 christos is_far = false; 1053 1.1 christos } 1054 1.1 christos } 1055 1.1 christos 1056 1.1 christos /* Do the memory bank mapping. */ 1057 1.1 christos phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend); 1058 1.1 christos phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend); 1059 1.1 christos switch (r_type) 1060 1.6 christos { 1061 1.6 christos case R_M68HC12_LO8XG: 1062 1.6 christos /* This relocation is specific to XGATE IMM16 calls and will precede 1063 1.1 christos a HI8. tc-m68hc11 only generates them in pairs. 1064 1.1 christos Leave the relocation to the HI8XG step. */ 1065 1.6 christos r = bfd_reloc_ok; 1066 1.6 christos r_type = R_M68HC11_NONE; 1067 1.6 christos break; 1068 1.6 christos 1069 1.6 christos case R_M68HC12_HI8XG: 1070 1.6 christos /* This relocation is specific to XGATE IMM16 calls and must follow 1071 1.6 christos a LO8XG. Does not actually check that it was a LO8XG. 1072 1.1 christos Adjusts high and low bytes. */ 1073 1.6 christos relocation = phys_addr; 1074 1.6 christos if ((e_flags & E_M68HC11_XGATE_RAMOFFSET) 1075 1.1 christos && (relocation >= 0x2000)) 1076 1.1 christos relocation += 0xc000; /* HARDCODED RAM offset for XGATE. */ 1077 1.1 christos 1078 1.6 christos /* Fetch 16 bit value including low byte in previous insn. */ 1079 1.6 christos val = (bfd_get_8 (input_bfd, (bfd_byte*) contents + rel->r_offset) << 8) 1080 1.1 christos | bfd_get_8 (input_bfd, (bfd_byte*) contents + rel->r_offset - 2); 1081 1.1 christos 1082 1.6 christos /* Add on value to preserve carry, then write zero to high byte. */ 1083 1.6 christos relocation += val; 1084 1.1 christos 1085 1.6 christos /* Write out top byte. */ 1086 1.6 christos bfd_put_8 (input_bfd, (relocation >> 8) & 0xff, 1087 1.1 christos (bfd_byte*) contents + rel->r_offset); 1088 1.1 christos 1089 1.6 christos /* Write out low byte to previous instruction. */ 1090 1.6 christos bfd_put_8 (input_bfd, relocation & 0xff, 1091 1.1 christos (bfd_byte*) contents + rel->r_offset - 2); 1092 1.1 christos 1093 1.6 christos /* Mark as relocation completed. */ 1094 1.6 christos r = bfd_reloc_ok; 1095 1.6 christos r_type = R_M68HC11_NONE; 1096 1.6 christos break; 1097 1.6 christos 1098 1.6 christos /* The HI8 and LO8 relocs are generated by %hi(expr) %lo(expr) 1099 1.6 christos assembler directives. %hi does not support carry. */ 1100 1.6 christos case R_M68HC11_HI8: 1101 1.6 christos case R_M68HC11_LO8: 1102 1.6 christos relocation = phys_addr; 1103 1.6 christos break; 1104 1.6 christos 1105 1.6 christos case R_M68HC11_24: 1106 1.6 christos /* Reloc used by 68HC12 call instruction. */ 1107 1.6 christos bfd_put_16 (input_bfd, phys_addr, 1108 1.6 christos (bfd_byte*) contents + rel->r_offset); 1109 1.6 christos bfd_put_8 (input_bfd, phys_page, 1110 1.6 christos (bfd_byte*) contents + rel->r_offset + 2); 1111 1.6 christos r = bfd_reloc_ok; 1112 1.6 christos r_type = R_M68HC11_NONE; 1113 1.6 christos break; 1114 1.6 christos 1115 1.6 christos case R_M68HC11_NONE: 1116 1.6 christos r = bfd_reloc_ok; 1117 1.6 christos break; 1118 1.6 christos 1119 1.6 christos case R_M68HC11_LO16: 1120 1.6 christos /* Reloc generated by %addr(expr) gas to obtain the 1121 1.6 christos address as mapped in the memory bank window. */ 1122 1.6 christos relocation = phys_addr; 1123 1.6 christos break; 1124 1.6 christos 1125 1.6 christos case R_M68HC11_PAGE: 1126 1.6 christos /* Reloc generated by %page(expr) gas to obtain the 1127 1.6 christos page number associated with the address. */ 1128 1.6 christos relocation = phys_page; 1129 1.6 christos break; 1130 1.6 christos 1131 1.6 christos case R_M68HC11_16: 1132 1.6 christos if (is_far) 1133 1.6 christos { 1134 1.7 christos if (!reloc_warning (info, name, input_bfd, input_section, rel, 1135 1.7 christos _("reference to the far symbol `%s' using a " 1136 1.7 christos "wrong relocation may result in incorrect " 1137 1.7 christos "execution"), name)) 1138 1.8 christos return false; 1139 1.6 christos } 1140 1.1 christos 1141 1.6 christos /* Get virtual address of instruction having the relocation. */ 1142 1.6 christos insn_addr = input_section->output_section->vma 1143 1.6 christos + input_section->output_offset 1144 1.6 christos + rel->r_offset; 1145 1.1 christos 1146 1.6 christos insn_page = m68hc11_phys_page (pinfo, insn_addr); 1147 1.1 christos 1148 1.6 christos /* If we are linking an S12 instruction against an XGATE symbol, we 1149 1.6 christos need to change the offset of the symbol value so that it's correct 1150 1.1 christos from the S12's perspective. */ 1151 1.6 christos if (is_xgate_symbol) 1152 1.1 christos { 1153 1.1 christos /* The ram in the global space is mapped to 0x2000 in the 16-bit 1154 1.1 christos address space for S12 and 0xE000 in the 16-bit address space 1155 1.1 christos for XGATE. */ 1156 1.1 christos if (relocation >= 0xE000) 1157 1.1 christos { 1158 1.1 christos /* We offset the address by the difference 1159 1.1 christos between these two mappings. */ 1160 1.1 christos relocation -= 0xC000; 1161 1.1 christos break; 1162 1.1 christos } 1163 1.1 christos else 1164 1.1 christos { 1165 1.7 christos if (!reloc_warning (info, name, input_bfd, input_section, rel, 1166 1.7 christos _("XGATE address (%lx) is not within " 1167 1.7 christos "shared RAM(0xE000-0xFFFF), therefore " 1168 1.7 christos "you must manually offset the address, " 1169 1.7 christos "and possibly manage the page, in your " 1170 1.7 christos "code."), (long) phys_addr)) 1171 1.8 christos return false; 1172 1.1 christos break; 1173 1.1 christos } 1174 1.1 christos } 1175 1.1 christos 1176 1.6 christos if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend) 1177 1.6 christos && m68hc11_addr_is_banked (pinfo, insn_addr) 1178 1.7 christos && phys_page != insn_page 1179 1.7 christos && !(e_flags & E_M68HC11_NO_BANK_WARNING)) 1180 1.6 christos { 1181 1.7 christos if (!reloc_warning (info, name, input_bfd, input_section, rel, 1182 1.7 christos _("banked address [%lx:%04lx] (%lx) is not " 1183 1.7 christos "in the same bank as current banked " 1184 1.7 christos "address [%lx:%04lx] (%lx)"), 1185 1.7 christos (long) phys_page, (long) phys_addr, 1186 1.7 christos (long) (relocation + rel->r_addend), 1187 1.7 christos (long) insn_page, 1188 1.7 christos (long) m68hc11_phys_addr (pinfo, insn_addr), 1189 1.7 christos (long) insn_addr)) 1190 1.8 christos return false; 1191 1.6 christos break; 1192 1.6 christos } 1193 1.1 christos 1194 1.6 christos if (phys_page != 0 && insn_page == 0) 1195 1.6 christos { 1196 1.7 christos if (!reloc_warning (info, name, input_bfd, input_section, rel, 1197 1.7 christos _("reference to a banked address [%lx:%04lx] " 1198 1.7 christos "in the normal address space at %04lx"), 1199 1.7 christos (long) phys_page, (long) phys_addr, 1200 1.7 christos (long) insn_addr)) 1201 1.8 christos return false; 1202 1.6 christos relocation = phys_addr; 1203 1.6 christos break; 1204 1.6 christos } 1205 1.6 christos 1206 1.6 christos /* If this is a banked address use the phys_addr so that 1207 1.6 christos we stay in the banked window. */ 1208 1.6 christos if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend)) 1209 1.6 christos relocation = phys_addr; 1210 1.6 christos break; 1211 1.6 christos } 1212 1.1 christos 1213 1.1 christos /* If we are linking an XGATE instruction against an S12 symbol, we 1214 1.6 christos need to change the offset of the symbol value so that it's correct 1215 1.1 christos from the XGATE's perspective. */ 1216 1.1 christos if (!strcmp (howto->name, "R_XGATE_IMM8_LO") 1217 1.6 christos || !strcmp (howto->name, "R_XGATE_IMM8_HI")) 1218 1.6 christos { 1219 1.6 christos /* We can only offset S12 addresses that lie within the non-paged 1220 1.6 christos area of RAM. */ 1221 1.6 christos if (!is_xgate_symbol && !is_section_symbol) 1222 1.6 christos { 1223 1.6 christos /* The ram in the global space is mapped to 0x2000 and stops at 1224 1.6 christos 0x4000 in the 16-bit address space for S12 and 0xE000 in the 1225 1.6 christos 16-bit address space for XGATE. */ 1226 1.6 christos if (relocation >= 0x2000 && relocation < 0x4000) 1227 1.6 christos /* We offset the address by the difference 1228 1.6 christos between these two mappings. */ 1229 1.6 christos relocation += 0xC000; 1230 1.6 christos else 1231 1.6 christos { 1232 1.7 christos if (!reloc_warning (info, name, input_bfd, input_section, rel, 1233 1.7 christos _("S12 address (%lx) is not within " 1234 1.7 christos "shared RAM(0x2000-0x4000), therefore " 1235 1.7 christos "you must manually offset the address " 1236 1.7 christos "in your code"), (long) phys_addr)) 1237 1.8 christos return false; 1238 1.6 christos break; 1239 1.6 christos } 1240 1.6 christos } 1241 1.6 christos } 1242 1.1 christos 1243 1.1 christos if (r_type != R_M68HC11_NONE) 1244 1.6 christos { 1245 1.6 christos if ((r_type == R_M68HC12_PCREL_9) || (r_type == R_M68HC12_PCREL_10)) 1246 1.6 christos r = _bfd_final_link_relocate (howto, input_bfd, input_section, 1247 1.6 christos contents, rel->r_offset, 1248 1.6 christos relocation - 2, rel->r_addend); 1249 1.6 christos else 1250 1.6 christos r = _bfd_final_link_relocate (howto, input_bfd, input_section, 1251 1.6 christos contents, rel->r_offset, 1252 1.6 christos relocation, rel->r_addend); 1253 1.6 christos } 1254 1.1 christos 1255 1.1 christos if (r != bfd_reloc_ok) 1256 1.1 christos { 1257 1.1 christos switch (r) 1258 1.1 christos { 1259 1.1 christos case bfd_reloc_overflow: 1260 1.5 christos (*info->callbacks->reloc_overflow) 1261 1.5 christos (info, NULL, name, howto->name, (bfd_vma) 0, 1262 1.5 christos input_bfd, input_section, rel->r_offset); 1263 1.1 christos break; 1264 1.1 christos 1265 1.1 christos case bfd_reloc_undefined: 1266 1.5 christos (*info->callbacks->undefined_symbol) 1267 1.8 christos (info, name, input_bfd, input_section, rel->r_offset, true); 1268 1.1 christos break; 1269 1.1 christos 1270 1.1 christos case bfd_reloc_outofrange: 1271 1.1 christos msg = _ ("internal error: out of range error"); 1272 1.1 christos goto common_error; 1273 1.1 christos 1274 1.1 christos case bfd_reloc_notsupported: 1275 1.1 christos msg = _ ("internal error: unsupported relocation error"); 1276 1.1 christos goto common_error; 1277 1.1 christos 1278 1.1 christos case bfd_reloc_dangerous: 1279 1.1 christos msg = _ ("internal error: dangerous error"); 1280 1.1 christos goto common_error; 1281 1.1 christos 1282 1.1 christos default: 1283 1.1 christos msg = _ ("internal error: unknown error"); 1284 1.1 christos /* fall through */ 1285 1.1 christos 1286 1.1 christos common_error: 1287 1.5 christos (*info->callbacks->warning) (info, msg, name, input_bfd, 1288 1.5 christos input_section, rel->r_offset); 1289 1.1 christos break; 1290 1.1 christos } 1291 1.1 christos } 1292 1.1 christos } 1293 1.1 christos 1294 1.8 christos return true; 1295 1.1 christos } 1296 1.1 christos 1297 1.1 christos 1298 1.1 christos 1299 1.1 christos /* Set and control ELF flags in ELF header. */ 1301 1.8 christos 1302 1.1 christos bool 1303 1.1 christos _bfd_m68hc11_elf_set_private_flags (bfd *abfd, flagword flags) 1304 1.1 christos { 1305 1.1 christos BFD_ASSERT (!elf_flags_init (abfd) 1306 1.1 christos || elf_elfheader (abfd)->e_flags == flags); 1307 1.1 christos 1308 1.8 christos elf_elfheader (abfd)->e_flags = flags; 1309 1.8 christos elf_flags_init (abfd) = true; 1310 1.1 christos return true; 1311 1.1 christos } 1312 1.1 christos 1313 1.1 christos /* Merge backend specific data from an object file to the output 1314 1.1 christos object file when linking. */ 1315 1.8 christos 1316 1.6 christos bool 1317 1.1 christos _bfd_m68hc11_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) 1318 1.6 christos { 1319 1.1 christos bfd *obfd = info->output_bfd; 1320 1.1 christos flagword old_flags; 1321 1.8 christos flagword new_flags; 1322 1.1 christos bool ok = true; 1323 1.1 christos 1324 1.6 christos /* Check if we have the same endianness */ 1325 1.8 christos if (!_bfd_generic_verify_endian_match (ibfd, info)) 1326 1.1 christos return false; 1327 1.1 christos 1328 1.1 christos if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour 1329 1.8 christos || bfd_get_flavour (obfd) != bfd_target_elf_flavour) 1330 1.1 christos return true; 1331 1.1 christos 1332 1.1 christos new_flags = elf_elfheader (ibfd)->e_flags; 1333 1.1 christos elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI; 1334 1.1 christos old_flags = elf_elfheader (obfd)->e_flags; 1335 1.1 christos 1336 1.1 christos if (! elf_flags_init (obfd)) 1337 1.8 christos { 1338 1.1 christos elf_flags_init (obfd) = true; 1339 1.1 christos elf_elfheader (obfd)->e_flags = new_flags; 1340 1.1 christos elf_elfheader (obfd)->e_ident[EI_CLASS] 1341 1.1 christos = elf_elfheader (ibfd)->e_ident[EI_CLASS]; 1342 1.1 christos 1343 1.1 christos if (bfd_get_arch (obfd) == bfd_get_arch (ibfd) 1344 1.1 christos && bfd_get_arch_info (obfd)->the_default) 1345 1.1 christos { 1346 1.1 christos if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), 1347 1.8 christos bfd_get_mach (ibfd))) 1348 1.1 christos return false; 1349 1.1 christos } 1350 1.8 christos 1351 1.1 christos return true; 1352 1.1 christos } 1353 1.1 christos 1354 1.1 christos /* Check ABI compatibility. */ 1355 1.1 christos if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32)) 1356 1.6 christos { 1357 1.6 christos _bfd_error_handler 1358 1.6 christos (_("%pB: linking files compiled for 16-bit integers (-mshort) " 1359 1.8 christos "and others for 32-bit integers"), ibfd); 1360 1.1 christos ok = false; 1361 1.1 christos } 1362 1.1 christos if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64)) 1363 1.6 christos { 1364 1.6 christos _bfd_error_handler 1365 1.6 christos (_("%pB: linking files compiled for 32-bit double (-fshort-double) " 1366 1.8 christos "and others for 64-bit double"), ibfd); 1367 1.1 christos ok = false; 1368 1.1 christos } 1369 1.1 christos 1370 1.1 christos /* Processor compatibility. */ 1371 1.1 christos if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags)) 1372 1.6 christos { 1373 1.6 christos _bfd_error_handler 1374 1.6 christos (_("%pB: linking files compiled for HCS12 with " 1375 1.8 christos "others compiled for HC12"), ibfd); 1376 1.1 christos ok = false; 1377 1.1 christos } 1378 1.6 christos new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK) 1379 1.1 christos | (EF_M68HC11_MERGE_MACH (new_flags, old_flags))); 1380 1.1 christos 1381 1.1 christos elf_elfheader (obfd)->e_flags = new_flags; 1382 1.1 christos 1383 1.1 christos new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK); 1384 1.1 christos old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK); 1385 1.1 christos 1386 1.1 christos /* Warn about any other mismatches */ 1387 1.1 christos if (new_flags != old_flags) 1388 1.6 christos { 1389 1.6 christos _bfd_error_handler 1390 1.6 christos /* xgettext:c-format */ 1391 1.6 christos (_("%pB: uses different e_flags (%#x) fields than previous modules (%#x)"), 1392 1.8 christos ibfd, new_flags, old_flags); 1393 1.1 christos ok = false; 1394 1.1 christos } 1395 1.1 christos 1396 1.1 christos if (! ok) 1397 1.1 christos { 1398 1.8 christos bfd_set_error (bfd_error_bad_value); 1399 1.1 christos return false; 1400 1.1 christos } 1401 1.8 christos 1402 1.1 christos return true; 1403 1.1 christos } 1404 1.8 christos 1405 1.1 christos bool 1406 1.1 christos _bfd_m68hc11_elf_print_private_bfd_data (bfd *abfd, void *ptr) 1407 1.1 christos { 1408 1.1 christos FILE *file = (FILE *) ptr; 1409 1.1 christos 1410 1.1 christos BFD_ASSERT (abfd != NULL && ptr != NULL); 1411 1.1 christos 1412 1.1 christos /* Print normal ELF private data. */ 1413 1.1 christos _bfd_elf_print_private_bfd_data (abfd, ptr); 1414 1.1 christos 1415 1.1 christos /* xgettext:c-format */ 1416 1.1 christos fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags); 1417 1.1 christos 1418 1.1 christos if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32) 1419 1.1 christos fprintf (file, _("[abi=32-bit int, ")); 1420 1.1 christos else 1421 1.1 christos fprintf (file, _("[abi=16-bit int, ")); 1422 1.1 christos 1423 1.1 christos if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64) 1424 1.1 christos fprintf (file, _("64-bit double, ")); 1425 1.1 christos else 1426 1.1 christos fprintf (file, _("32-bit double, ")); 1427 1.1 christos 1428 1.1 christos if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0) 1429 1.1 christos fprintf (file, _("cpu=HC11]")); 1430 1.1 christos else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH) 1431 1.1 christos fprintf (file, _("cpu=HCS12]")); 1432 1.3 christos else 1433 1.1 christos fprintf (file, _("cpu=HC12]")); 1434 1.1 christos 1435 1.1 christos if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS) 1436 1.1 christos fprintf (file, _(" [memory=bank-model]")); 1437 1.1 christos else 1438 1.1 christos fprintf (file, _(" [memory=flat]")); 1439 1.1 christos 1440 1.1 christos if (elf_elfheader (abfd)->e_flags & E_M68HC11_XGATE_RAMOFFSET) 1441 1.1 christos fprintf (file, _(" [XGATE RAM offsetting]")); 1442 1.1 christos 1443 1.1 christos fputc ('\n', file); 1444 1.8 christos 1445 1.1 christos return true; 1446 1.1 christos } 1447 1.1 christos 1448 1.6 christos static void scan_sections_for_abi (bfd *abfd ATTRIBUTE_UNUSED, 1449 1.1 christos asection *asect, void *arg) 1450 1.1 christos { 1451 1.1 christos struct m68hc11_scan_param* p = (struct m68hc11_scan_param*) arg; 1452 1.1 christos 1453 1.8 christos if (asect->vma >= p->pinfo->bank_virtual) 1454 1.1 christos p->use_memory_banks = true; 1455 1.3 christos } 1456 1.1 christos 1457 1.1 christos /* Tweak the OSABI field of the elf header. */ 1458 1.8 christos 1459 1.7 christos bool 1460 1.1 christos elf32_m68hc11_init_file_header (bfd *abfd, struct bfd_link_info *link_info) 1461 1.1 christos { 1462 1.1 christos struct m68hc11_scan_param param; 1463 1.1 christos struct m68hc11_elf_link_hash_table *htab; 1464 1.7 christos 1465 1.8 christos if (!_bfd_elf_init_file_header (abfd, link_info)) 1466 1.7 christos return false; 1467 1.1 christos 1468 1.8 christos if (link_info == NULL) 1469 1.1 christos return true; 1470 1.1 christos 1471 1.1 christos htab = m68hc11_elf_hash_table (link_info); 1472 1.8 christos if (htab == NULL) 1473 1.1 christos return true; 1474 1.1 christos 1475 1.1 christos m68hc11_elf_get_bank_parameters (link_info); 1476 1.8 christos 1477 1.1 christos param.use_memory_banks = false; 1478 1.1 christos param.pinfo = & htab->pinfo; 1479 1.1 christos 1480 1.1 christos bfd_map_over_sections (abfd, scan_sections_for_abi, ¶m); 1481 1.1 christos 1482 1.1 christos if (param.use_memory_banks) 1483 1.1 christos { 1484 1.1 christos Elf_Internal_Ehdr * i_ehdrp; 1485 1.1 christos 1486 1.1 christos i_ehdrp = elf_elfheader (abfd); 1487 1.1 christos i_ehdrp->e_flags |= E_M68HC12_BANKS; 1488 1.8 christos } 1489 1.1 christos return true; 1490 } 1491