1 /* Generic support for 32-bit ELF
2 Copyright 1993, 1995, 1998, 1999 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
26 static reloc_howto_type *elf32_h8_reloc_type_lookup
27 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
28 static void elf32_h8_info_to_howto
29 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
31 /* This does not include any relocation information, but should be
32 good enough for GDB or objdump to read the file. */
34 static reloc_howto_type h8_elf_howto_table[] =
37 HOWTO (R_H8_NONE, /* type */
39 0, /* size (0 = byte, 1 = short, 2 = long) */
41 false, /* pc_relative */
43 complain_overflow_dont, /* complain_on_overflow */
44 NULL, /* special_function */
45 "R_H8_NONE", /* name */
46 false, /* partial_inplace */
49 false), /* pcrel_offset */
50 #define R_H8_DIR32_X (R_H8_NONE_X + 1)
51 HOWTO (R_H8_DIR32, /* type */
53 2, /* size (0 = byte, 1 = short, 2 = long) */
55 false, /* pc_relative */
57 complain_overflow_dont, /* complain_on_overflow */
58 NULL, /* special_function */
59 "R_H8_DIR32", /* name */
60 false, /* partial_inplace */
62 0xffffffff, /* dst_mask */
63 false), /* pcrel_offset */
64 #define R_H8_DIR16_X (R_H8_DIR32_X + 1)
65 HOWTO (R_H8_DIR16, /* type */
67 1, /* size (0 = byte, 1 = short, 2 = long) */
69 false, /* pc_relative */
71 complain_overflow_dont, /* complain_on_overflow */
72 NULL, /* special_function */
73 "R_H8_DIR16", /* name */
74 false, /* partial_inplace */
76 0x0000ffff, /* dst_mask */
77 false), /* pcrel_offset */
78 #define R_H8_DIR8_X (R_H8_DIR16_X + 1)
79 HOWTO (R_H8_DIR8, /* type */
81 0, /* size (0 = byte, 1 = short, 2 = long) */
83 false, /* pc_relative */
85 complain_overflow_dont, /* complain_on_overflow */
86 NULL, /* special_function */
87 "R_H8_DIR16", /* name */
88 false, /* partial_inplace */
90 0x000000ff, /* dst_mask */
91 false), /* pcrel_offset */
92 #define R_H8_DIR16A8_X (R_H8_DIR8_X + 1)
93 HOWTO (R_H8_DIR16A8, /* type */
95 1, /* size (0 = byte, 1 = short, 2 = long) */
97 false, /* pc_relative */
99 complain_overflow_bitfield, /* complain_on_overflow */
100 NULL, /* special_function */
101 "R_H8_DIR16A8", /* name */
102 false, /* partial_inplace */
104 0x0000ffff, /* dst_mask */
105 false), /* pcrel_offset */
106 #define R_H8_DIR16R8_X (R_H8_DIR16A8_X + 1)
107 HOWTO (R_H8_DIR16R8, /* type */
109 1, /* size (0 = byte, 1 = short, 2 = long) */
111 false, /* pc_relative */
113 complain_overflow_bitfield, /* complain_on_overflow */
114 NULL, /* special_function */
115 "R_H8_DIR16R8", /* name */
116 false, /* partial_inplace */
118 0x0000ffff, /* dst_mask */
119 false), /* pcrel_offset */
120 #define R_H8_DIR24A8_X (R_H8_DIR16R8_X + 1)
121 HOWTO (R_H8_DIR24A8, /* type */
123 2, /* size (0 = byte, 1 = short, 2 = long) */
125 false, /* pc_relative */
127 complain_overflow_bitfield, /* complain_on_overflow */
128 NULL, /* special_function */
129 "R_H8_DIR24A8", /* name */
130 true, /* partial_inplace */
131 0xff000000, /* src_mask */
132 0x00ffffff, /* dst_mask */
133 false), /* pcrel_offset */
134 #define R_H8_DIR24R8_X (R_H8_DIR24A8_X + 1)
135 HOWTO (R_H8_DIR24R8, /* type */
137 2, /* size (0 = byte, 1 = short, 2 = long) */
139 false, /* pc_relative */
141 complain_overflow_bitfield, /* complain_on_overflow */
142 NULL, /* special_function */
143 "R_H8_DIR24R8", /* name */
144 true, /* partial_inplace */
145 0xff000000, /* src_mask */
146 0x00ffffff, /* dst_mask */
147 false), /* pcrel_offset */
148 #define R_H8_DIR32A16_X (R_H8_DIR24R8_X + 1)
149 HOWTO (R_H8_DIR32A16, /* type */
151 2, /* size (0 = byte, 1 = short, 2 = long) */
153 false, /* pc_relative */
155 complain_overflow_dont, /* complain_on_overflow */
156 NULL, /* special_function */
157 "R_H8_DIR32", /* name */
158 false, /* partial_inplace */
160 0xffffffff, /* dst_mask */
161 false), /* pcrel_offset */
164 /* This structure is used to map BFD reloc codes to H8 ELF relocs. */
168 bfd_reloc_code_real_type bfd_reloc_val;
169 unsigned char howto_index;
172 /* An array mapping BFD reloc codes to SH ELF relocs. */
174 static const struct elf_reloc_map h8_reloc_map[] =
176 { BFD_RELOC_NONE, R_H8_NONE_X },
177 { BFD_RELOC_32, R_H8_DIR32_X },
178 { BFD_RELOC_16, R_H8_DIR16_X },
179 { BFD_RELOC_8, R_H8_DIR8_X },
180 { BFD_RELOC_H8_DIR16A8, R_H8_DIR16A8_X },
181 { BFD_RELOC_H8_DIR16R8, R_H8_DIR16R8_X },
182 { BFD_RELOC_H8_DIR24A8, R_H8_DIR24A8_X },
183 { BFD_RELOC_H8_DIR24R8, R_H8_DIR24R8_X },
184 { BFD_RELOC_H8_DIR32A16, R_H8_DIR32A16_X },
187 static reloc_howto_type *elf32_h8_reloc_type_lookup
188 PARAMS ((bfd *, bfd_reloc_code_real_type));
189 static void elf32_h8_info_to_howto
190 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
191 static void elf32_h8_info_to_howto_rel
192 PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
193 static int elf32_h8_mach
196 static reloc_howto_type *
197 elf32_h8_reloc_type_lookup (abfd, code)
198 bfd *abfd ATTRIBUTE_UNUSED;
199 bfd_reloc_code_real_type code;
203 for (i = 0; i < sizeof (h8_reloc_map) / sizeof (struct elf_reloc_map); i++)
205 if (h8_reloc_map[i].bfd_reloc_val == code)
206 return &h8_elf_howto_table[(int) h8_reloc_map[i].howto_index];
212 elf32_h8_info_to_howto (abfd, bfd_reloc, elf_reloc)
213 bfd *abfd ATTRIBUTE_UNUSED;
215 Elf32_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED;
220 r = ELF32_R_TYPE (elf_reloc->r_info);
221 for (i = 0; i < sizeof (h8_elf_howto_table) / sizeof (reloc_howto_type); i++)
222 if (h8_elf_howto_table[i].type== r)
224 bfd_reloc->howto = &h8_elf_howto_table[i];
231 elf32_h8_info_to_howto_rel (abfd, bfd_reloc, elf_reloc)
232 bfd *abfd ATTRIBUTE_UNUSED;
234 Elf32_Internal_Rel *elf_reloc ATTRIBUTE_UNUSED;
239 r = ELF32_R_TYPE (elf_reloc->r_info);
240 bfd_reloc->howto = &h8_elf_howto_table[r];
243 /* Object files encode the specific H8 model they were compiled
244 for in the ELF flags field.
246 Examine that field and return the proper BFD machine type for
249 elf32_h8_mach (flags)
252 switch (flags & EF_H8_MACH)
254 case E_H8_MACH_H8300:
256 return bfd_mach_h8300;
258 case E_H8_MACH_H8300H:
259 return bfd_mach_h8300h;
261 case E_H8_MACH_H8300S:
262 return bfd_mach_h8300s;
266 /* The final processing done just before writing out a H8 ELF object
267 file. We use this opportunity to encode the BFD machine type
268 into the flags field in the object file. */
271 elf32_h8_final_write_processing (abfd, linker)
273 boolean linker ATTRIBUTE_UNUSED;
277 switch (bfd_get_mach (abfd))
281 val = E_H8_MACH_H8300;
284 case bfd_mach_h8300h:
285 val = E_H8_MACH_H8300H;
288 case bfd_mach_h8300s:
289 val = E_H8_MACH_H8300S;
293 elf_elfheader (abfd)->e_flags &= ~ (EF_H8_MACH);
294 elf_elfheader (abfd)->e_flags |= val;
297 /* Return nonzero if ABFD represents a valid H8 ELF object file; also
298 record the encoded machine type found in the ELF flags. */
301 elf32_h8_object_p (abfd)
304 bfd_default_set_arch_mach (abfd, bfd_arch_h8300,
305 elf32_h8_mach (elf_elfheader (abfd)->e_flags));
309 /* Merge backend specific data from an object file to the output
310 object file when linking. The only data we need to copy at this
311 time is the architecture/machine information. */
314 elf32_h8_merge_private_bfd_data (ibfd, obfd)
318 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
319 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
322 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
323 && bfd_get_mach (obfd) < bfd_get_mach (ibfd))
325 if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
326 bfd_get_mach (ibfd)))
334 #define TARGET_BIG_SYM bfd_elf32_h8300_vec
335 #define TARGET_BIG_NAME "elf32-h8300"
336 #define ELF_ARCH bfd_arch_h8300
337 #define ELF_MACHINE_CODE EM_H8_300
338 #define ELF_MAXPAGESIZE 0x1
339 #define bfd_elf32_bfd_reloc_type_lookup elf32_h8_reloc_type_lookup
340 #define elf_info_to_howto elf32_h8_info_to_howto
341 #define elf_info_to_howto_rel elf32_h8_info_to_howto_rel
343 /* So we can set/examine bits in e_flags to get the specific
344 H8 architecture in use. */
345 #define elf_backend_final_write_processing \
346 elf32_h8_final_write_processing
347 #define elf_backend_object_p \
349 #define bfd_elf32_bfd_merge_private_bfd_data \
350 elf32_h8_merge_private_bfd_data
352 /* ??? when elf_backend_relocate_section is not defined, elf32-target.h
353 defaults to using _bfd_generic_link_hash_table_create, but
354 elflink.h:bfd_elf32_size_dynamic_sections uses
355 dynobj = elf_hash_table (info)->dynobj;
356 and thus requires an elf hash table. */
357 #define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
359 #include "elf32-target.h"