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