1/* Motorola 68HC11/68HC12-specific support for 32-bit ELF
2   Copyright 2003, 2004 Free Software Foundation, Inc.
3   Contributed by Stephane Carrez (stcarrez@nerim.fr)
4
5This file is part of BFD, the Binary File Descriptor library.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20
21#ifndef _ELF32_M68HC1X_H
22#define _ELF32_M68HC1X_H
23
24#include "elf-bfd.h"
25#include "bfdlink.h"
26#include "elf/m68hc11.h"
27
28/* Name of symbols exported by HC11/HC12 linker when there is a memory
29   bank window.  */
30#define BFD_M68HC11_BANK_START_NAME   "__bank_start"
31#define BFD_M68HC11_BANK_SIZE_NAME    "__bank_size"
32#define BFD_M68HC11_BANK_VIRTUAL_NAME "__bank_virtual"
33
34/* Set and control ELF flags in ELF header.  */
35extern bfd_boolean _bfd_m68hc11_elf_merge_private_bfd_data (bfd*,bfd*);
36extern bfd_boolean _bfd_m68hc11_elf_set_private_flags (bfd*,flagword);
37extern bfd_boolean _bfd_m68hc11_elf_print_private_bfd_data (bfd*, void*);
38
39/* This hash entry is used to record a trampoline that must be generated
40   to call a far function using a normal calling convention ('jsr').
41   The trampoline is used when a pointer to a far function is used.
42   It takes care of installing the proper memory bank as well as creating
43   the 'call/rtc' calling convention.  */
44struct elf32_m68hc11_stub_hash_entry {
45
46  /* Base hash table entry structure.  */
47  struct bfd_hash_entry root;
48
49  /* The stub section.  */
50  asection *stub_sec;
51
52  /* Offset within stub_sec of the beginning of this stub.  */
53  bfd_vma stub_offset;
54
55  /* Given the symbol's value and its section we can determine its final
56     value when building the stubs (so the stub knows where to jump.  */
57  bfd_vma target_value;
58  asection *target_section;
59};
60
61/* Placeholder for the parameters to compute memory page and physical address.
62   The following formulas are used:
63
64   sym > bank_virtual =>
65     %addr(sym) = (((sym - bank_virtual) & bank_mask) + bank_physical
66     %page(sym) = (((sym - bank_virtual) >> bank_shift) % 256
67
68   sym < bank_virtual =>
69     %addr(sym) = sym
70     %page(sym) = 0
71
72
73   These parameters are obtained from the symbol table by looking
74   at the following:
75
76   __bank_start         Symbol marking the start of memory bank window
77                        (bank_physical)
78   __bank_virtual       Logical address of symbols for which the transformation
79                        must be computed
80   __bank_page_size     Size in bytes of page size (this is *NOT* the memory
81                        bank window size and the window size is always
82                        less or equal to the page size)
83
84   For 68HC12, the window is at 0x8000 and the page size is 16K (full window).
85   For 68HC11 this is board specific (implemented by external hardware).
86
87*/
88struct m68hc11_page_info
89{
90  bfd_vma bank_virtual;
91  bfd_vma bank_physical;
92  bfd_vma bank_physical_end;
93  bfd_vma bank_mask;
94  bfd_vma bank_size;
95  int bank_shift;
96  int bank_param_initialized;
97  bfd_vma trampoline_addr;
98};
99
100struct m68hc11_elf_link_hash_table
101{
102  struct elf_link_hash_table root;
103  struct m68hc11_page_info pinfo;
104
105  /* The stub hash table.  */
106  struct bfd_hash_table* stub_hash_table;
107
108  /* Linker stub bfd.  */
109  bfd *stub_bfd;
110
111  asection* stub_section;
112  asection* tramp_section;
113
114  /* Linker call-backs.  */
115  asection * (*add_stub_section) PARAMS ((const char *, asection *));
116
117  /* Assorted information used by elf32_hppa_size_stubs.  */
118  unsigned int bfd_count;
119  int top_index;
120  asection **input_list;
121
122  /* Small local sym to section mapping cache.  */
123  struct sym_sec_cache sym_sec;
124
125  bfd_boolean (* size_one_stub) PARAMS((struct bfd_hash_entry*, void*));
126  bfd_boolean (* build_one_stub) PARAMS((struct bfd_hash_entry*, void*));
127};
128
129/* Get the Sparc64 ELF linker hash table from a link_info structure.  */
130
131#define m68hc11_elf_hash_table(p) \
132  ((struct m68hc11_elf_link_hash_table *) ((p)->hash))
133
134/* Create a 68HC11/68HC12 ELF linker hash table.  */
135
136extern struct m68hc11_elf_link_hash_table* m68hc11_elf_hash_table_create
137  (bfd*);
138extern void m68hc11_elf_bfd_link_hash_table_free (struct bfd_link_hash_table*);
139
140extern void m68hc11_elf_get_bank_parameters (struct bfd_link_info*);
141
142/* Return 1 if the address is in banked memory.
143   This can be applied to a virtual address and to a physical address.  */
144extern int m68hc11_addr_is_banked (struct m68hc11_page_info*, bfd_vma);
145
146/* Return the physical address seen by the processor, taking
147   into account banked memory.  */
148extern bfd_vma m68hc11_phys_addr (struct m68hc11_page_info*, bfd_vma);
149
150/* Return the page number corresponding to an address in banked memory.  */
151extern bfd_vma m68hc11_phys_page (struct m68hc11_page_info*, bfd_vma);
152
153bfd_reloc_status_type m68hc11_elf_ignore_reloc
154  (bfd *abfd, arelent *reloc_entry,
155   asymbol *symbol, void *data, asection *input_section,
156   bfd *output_bfd, char **error_message);
157bfd_reloc_status_type m68hc11_elf_special_reloc
158  (bfd *abfd, arelent *reloc_entry,
159    asymbol *symbol, void *data, asection *input_section,
160    bfd *output_bfd, char **error_message);
161
162/* GC mark and sweep.  */
163asection *elf32_m68hc11_gc_mark_hook
164  (asection *sec, struct bfd_link_info *info,
165   Elf_Internal_Rela *rel, struct elf_link_hash_entry *h,
166   Elf_Internal_Sym *sym);
167bfd_boolean elf32_m68hc11_gc_sweep_hook
168  (bfd *abfd, struct bfd_link_info *info,
169   asection *sec, const Elf_Internal_Rela *relocs);
170bfd_boolean elf32_m68hc11_check_relocs
171  (bfd * abfd, struct bfd_link_info * info,
172   asection * sec, const Elf_Internal_Rela * relocs);
173bfd_boolean elf32_m68hc11_relocate_section
174  (bfd *output_bfd, struct bfd_link_info *info,
175   bfd *input_bfd, asection *input_section,
176   bfd_byte *contents, Elf_Internal_Rela *relocs,
177   Elf_Internal_Sym *local_syms, asection **local_sections);
178
179bfd_boolean elf32_m68hc11_add_symbol_hook
180  (bfd *abfd, struct bfd_link_info *info,
181   Elf_Internal_Sym *sym, const char **namep,
182   flagword *flagsp, asection **secp,
183   bfd_vma *valp);
184
185/* Tweak the OSABI field of the elf header.  */
186
187extern void elf32_m68hc11_post_process_headers (bfd*, struct bfd_link_info*);
188
189int elf32_m68hc11_setup_section_lists (bfd *, struct bfd_link_info *);
190
191bfd_boolean elf32_m68hc11_size_stubs
192  (bfd *, bfd *, struct bfd_link_info *,
193   asection * (*) (const char *, asection *));
194
195bfd_boolean elf32_m68hc11_build_stubs (bfd* abfd, struct bfd_link_info *);
196#endif
197