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