1d2201f2fSdrahn /* BFD back-end for Renesas H8/300 ELF binaries.
2*cf2f2c56Smiod Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2003, 2004
3d2201f2fSdrahn Free Software Foundation, Inc.
4d2201f2fSdrahn
5d2201f2fSdrahn This file is part of BFD, the Binary File Descriptor library.
6d2201f2fSdrahn
7d2201f2fSdrahn This program is free software; you can redistribute it and/or modify
8d2201f2fSdrahn it under the terms of the GNU General Public License as published by
9d2201f2fSdrahn the Free Software Foundation; either version 2 of the License, or
10d2201f2fSdrahn (at your option) any later version.
11d2201f2fSdrahn
12d2201f2fSdrahn This program is distributed in the hope that it will be useful,
13d2201f2fSdrahn but WITHOUT ANY WARRANTY; without even the implied warranty of
14d2201f2fSdrahn MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15d2201f2fSdrahn GNU General Public License for more details.
16d2201f2fSdrahn
17d2201f2fSdrahn You should have received a copy of the GNU General Public License
18d2201f2fSdrahn along with this program; if not, write to the Free Software
19d2201f2fSdrahn Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20d2201f2fSdrahn
21d2201f2fSdrahn #include "bfd.h"
22d2201f2fSdrahn #include "sysdep.h"
23d2201f2fSdrahn #include "libbfd.h"
24d2201f2fSdrahn #include "elf-bfd.h"
25d2201f2fSdrahn #include "elf/h8.h"
26d2201f2fSdrahn
27d2201f2fSdrahn static reloc_howto_type *elf32_h8_reloc_type_lookup
28*cf2f2c56Smiod (bfd *abfd, bfd_reloc_code_real_type code);
29d2201f2fSdrahn static void elf32_h8_info_to_howto
30*cf2f2c56Smiod (bfd *, arelent *, Elf_Internal_Rela *);
31d2201f2fSdrahn static void elf32_h8_info_to_howto_rel
32*cf2f2c56Smiod (bfd *, arelent *, Elf_Internal_Rela *);
33*cf2f2c56Smiod static unsigned long elf32_h8_mach (flagword);
34*cf2f2c56Smiod static void elf32_h8_final_write_processing (bfd *, bfd_boolean);
35*cf2f2c56Smiod static bfd_boolean elf32_h8_object_p (bfd *);
36*cf2f2c56Smiod static bfd_boolean elf32_h8_merge_private_bfd_data (bfd *, bfd *);
37d2201f2fSdrahn static bfd_boolean elf32_h8_relax_section
38*cf2f2c56Smiod (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
39d2201f2fSdrahn static bfd_boolean elf32_h8_relax_delete_bytes
40*cf2f2c56Smiod (bfd *, asection *, bfd_vma, int);
41*cf2f2c56Smiod static bfd_boolean elf32_h8_symbol_address_p (bfd *, asection *, bfd_vma);
42d2201f2fSdrahn static bfd_byte *elf32_h8_get_relocated_section_contents
43*cf2f2c56Smiod (bfd *, struct bfd_link_info *, struct bfd_link_order *,
44*cf2f2c56Smiod bfd_byte *, bfd_boolean, asymbol **);
45*cf2f2c56Smiod static asection *elf32_h8_gc_mark_hook
46*cf2f2c56Smiod (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
47*cf2f2c56Smiod struct elf_link_hash_entry *, Elf_Internal_Sym *);
48*cf2f2c56Smiod static bfd_boolean elf32_h8_gc_sweep_hook
49*cf2f2c56Smiod (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
50d2201f2fSdrahn static bfd_reloc_status_type elf32_h8_final_link_relocate
51*cf2f2c56Smiod (unsigned long, bfd *, bfd *, asection *,
52d2201f2fSdrahn bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
53*cf2f2c56Smiod struct bfd_link_info *, asection *, int);
54d2201f2fSdrahn static bfd_boolean elf32_h8_relocate_section
55*cf2f2c56Smiod (bfd *, struct bfd_link_info *, bfd *, asection *,
56d2201f2fSdrahn bfd_byte *, Elf_Internal_Rela *,
57*cf2f2c56Smiod Elf_Internal_Sym *, asection **);
58d2201f2fSdrahn static bfd_reloc_status_type special
59*cf2f2c56Smiod (bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **);
60d2201f2fSdrahn
61d2201f2fSdrahn /* This does not include any relocation information, but should be
62d2201f2fSdrahn good enough for GDB or objdump to read the file. */
63d2201f2fSdrahn
64d2201f2fSdrahn static reloc_howto_type h8_elf_howto_table[] = {
65d2201f2fSdrahn #define R_H8_NONE_X 0
66d2201f2fSdrahn HOWTO (R_H8_NONE, /* type */
67d2201f2fSdrahn 0, /* rightshift */
68d2201f2fSdrahn 0, /* size (0 = byte, 1 = short, 2 = long) */
69d2201f2fSdrahn 0, /* bitsize */
70d2201f2fSdrahn FALSE, /* pc_relative */
71d2201f2fSdrahn 0, /* bitpos */
72d2201f2fSdrahn complain_overflow_dont,/* complain_on_overflow */
73d2201f2fSdrahn special, /* special_function */
74d2201f2fSdrahn "R_H8_NONE", /* name */
75d2201f2fSdrahn FALSE, /* partial_inplace */
76d2201f2fSdrahn 0, /* src_mask */
77d2201f2fSdrahn 0, /* dst_mask */
78d2201f2fSdrahn FALSE), /* pcrel_offset */
79d2201f2fSdrahn #define R_H8_DIR32_X (R_H8_NONE_X + 1)
80d2201f2fSdrahn HOWTO (R_H8_DIR32, /* type */
81d2201f2fSdrahn 0, /* rightshift */
82d2201f2fSdrahn 2, /* size (0 = byte, 1 = short, 2 = long) */
83d2201f2fSdrahn 32, /* bitsize */
84d2201f2fSdrahn FALSE, /* pc_relative */
85d2201f2fSdrahn 0, /* bitpos */
86d2201f2fSdrahn complain_overflow_dont,/* complain_on_overflow */
87d2201f2fSdrahn special, /* special_function */
88d2201f2fSdrahn "R_H8_DIR32", /* name */
89d2201f2fSdrahn FALSE, /* partial_inplace */
90d2201f2fSdrahn 0, /* src_mask */
91d2201f2fSdrahn 0xffffffff, /* dst_mask */
92d2201f2fSdrahn FALSE), /* pcrel_offset */
93d2201f2fSdrahn #define R_H8_DIR16_X (R_H8_DIR32_X + 1)
94d2201f2fSdrahn HOWTO (R_H8_DIR16, /* type */
95d2201f2fSdrahn 0, /* rightshift */
96d2201f2fSdrahn 1, /* size (0 = byte, 1 = short, 2 = long) */
97d2201f2fSdrahn 16, /* bitsize */
98d2201f2fSdrahn FALSE, /* pc_relative */
99d2201f2fSdrahn 0, /* bitpos */
100d2201f2fSdrahn complain_overflow_dont,/* complain_on_overflow */
101d2201f2fSdrahn special, /* special_function */
102d2201f2fSdrahn "R_H8_DIR16", /* name */
103d2201f2fSdrahn FALSE, /* partial_inplace */
104d2201f2fSdrahn 0, /* src_mask */
105d2201f2fSdrahn 0x0000ffff, /* dst_mask */
106d2201f2fSdrahn FALSE), /* pcrel_offset */
107d2201f2fSdrahn #define R_H8_DIR8_X (R_H8_DIR16_X + 1)
108d2201f2fSdrahn HOWTO (R_H8_DIR8, /* type */
109d2201f2fSdrahn 0, /* rightshift */
110d2201f2fSdrahn 0, /* size (0 = byte, 1 = short, 2 = long) */
111d2201f2fSdrahn 8, /* bitsize */
112d2201f2fSdrahn FALSE, /* pc_relative */
113d2201f2fSdrahn 0, /* bitpos */
114d2201f2fSdrahn complain_overflow_dont,/* complain_on_overflow */
115d2201f2fSdrahn special, /* special_function */
116*cf2f2c56Smiod "R_H8_DIR8", /* name */
117d2201f2fSdrahn FALSE, /* partial_inplace */
118d2201f2fSdrahn 0, /* src_mask */
119d2201f2fSdrahn 0x000000ff, /* dst_mask */
120d2201f2fSdrahn FALSE), /* pcrel_offset */
121d2201f2fSdrahn #define R_H8_DIR16A8_X (R_H8_DIR8_X + 1)
122d2201f2fSdrahn HOWTO (R_H8_DIR16A8, /* type */
123d2201f2fSdrahn 0, /* rightshift */
124d2201f2fSdrahn 1, /* size (0 = byte, 1 = short, 2 = long) */
125d2201f2fSdrahn 16, /* bitsize */
126d2201f2fSdrahn FALSE, /* pc_relative */
127d2201f2fSdrahn 0, /* bitpos */
128d2201f2fSdrahn complain_overflow_bitfield, /* complain_on_overflow */
129d2201f2fSdrahn special, /* special_function */
130d2201f2fSdrahn "R_H8_DIR16A8", /* name */
131d2201f2fSdrahn FALSE, /* partial_inplace */
132d2201f2fSdrahn 0, /* src_mask */
133d2201f2fSdrahn 0x0000ffff, /* dst_mask */
134d2201f2fSdrahn FALSE), /* pcrel_offset */
135d2201f2fSdrahn #define R_H8_DIR16R8_X (R_H8_DIR16A8_X + 1)
136d2201f2fSdrahn HOWTO (R_H8_DIR16R8, /* type */
137d2201f2fSdrahn 0, /* rightshift */
138d2201f2fSdrahn 1, /* size (0 = byte, 1 = short, 2 = long) */
139d2201f2fSdrahn 16, /* bitsize */
140d2201f2fSdrahn FALSE, /* pc_relative */
141d2201f2fSdrahn 0, /* bitpos */
142d2201f2fSdrahn complain_overflow_bitfield, /* complain_on_overflow */
143d2201f2fSdrahn special, /* special_function */
144d2201f2fSdrahn "R_H8_DIR16R8", /* name */
145d2201f2fSdrahn FALSE, /* partial_inplace */
146d2201f2fSdrahn 0, /* src_mask */
147d2201f2fSdrahn 0x0000ffff, /* dst_mask */
148d2201f2fSdrahn FALSE), /* pcrel_offset */
149d2201f2fSdrahn #define R_H8_DIR24A8_X (R_H8_DIR16R8_X + 1)
150d2201f2fSdrahn HOWTO (R_H8_DIR24A8, /* type */
151d2201f2fSdrahn 0, /* rightshift */
152d2201f2fSdrahn 2, /* size (0 = byte, 1 = short, 2 = long) */
153d2201f2fSdrahn 24, /* bitsize */
154d2201f2fSdrahn FALSE, /* pc_relative */
155d2201f2fSdrahn 0, /* bitpos */
156d2201f2fSdrahn complain_overflow_bitfield, /* complain_on_overflow */
157d2201f2fSdrahn special, /* special_function */
158d2201f2fSdrahn "R_H8_DIR24A8", /* name */
159d2201f2fSdrahn TRUE, /* partial_inplace */
160d2201f2fSdrahn 0xff000000, /* src_mask */
161d2201f2fSdrahn 0x00ffffff, /* dst_mask */
162d2201f2fSdrahn FALSE), /* pcrel_offset */
163d2201f2fSdrahn #define R_H8_DIR24R8_X (R_H8_DIR24A8_X + 1)
164d2201f2fSdrahn HOWTO (R_H8_DIR24R8, /* type */
165d2201f2fSdrahn 0, /* rightshift */
166d2201f2fSdrahn 2, /* size (0 = byte, 1 = short, 2 = long) */
167d2201f2fSdrahn 24, /* bitsize */
168d2201f2fSdrahn FALSE, /* pc_relative */
169d2201f2fSdrahn 0, /* bitpos */
170d2201f2fSdrahn complain_overflow_bitfield, /* complain_on_overflow */
171d2201f2fSdrahn special, /* special_function */
172d2201f2fSdrahn "R_H8_DIR24R8", /* name */
173d2201f2fSdrahn TRUE, /* partial_inplace */
174d2201f2fSdrahn 0xff000000, /* src_mask */
175d2201f2fSdrahn 0x00ffffff, /* dst_mask */
176d2201f2fSdrahn FALSE), /* pcrel_offset */
177d2201f2fSdrahn #define R_H8_DIR32A16_X (R_H8_DIR24R8_X + 1)
178d2201f2fSdrahn HOWTO (R_H8_DIR32A16, /* type */
179d2201f2fSdrahn 0, /* rightshift */
180d2201f2fSdrahn 2, /* size (0 = byte, 1 = short, 2 = long) */
181d2201f2fSdrahn 32, /* bitsize */
182d2201f2fSdrahn FALSE, /* pc_relative */
183d2201f2fSdrahn 0, /* bitpos */
184d2201f2fSdrahn complain_overflow_dont,/* complain_on_overflow */
185d2201f2fSdrahn special, /* special_function */
186*cf2f2c56Smiod "R_H8_DIR32A16", /* name */
187d2201f2fSdrahn FALSE, /* partial_inplace */
188d2201f2fSdrahn 0, /* src_mask */
189d2201f2fSdrahn 0xffffffff, /* dst_mask */
190d2201f2fSdrahn FALSE), /* pcrel_offset */
191d2201f2fSdrahn #define R_H8_PCREL16_X (R_H8_DIR32A16_X + 1)
192d2201f2fSdrahn HOWTO (R_H8_PCREL16, /* type */
193d2201f2fSdrahn 0, /* rightshift */
194d2201f2fSdrahn 1, /* size (0 = byte, 1 = short, 2 = long) */
195d2201f2fSdrahn 16, /* bitsize */
196d2201f2fSdrahn TRUE, /* pc_relative */
197d2201f2fSdrahn 0, /* bitpos */
198d2201f2fSdrahn complain_overflow_signed,/* complain_on_overflow */
199d2201f2fSdrahn special, /* special_function */
200d2201f2fSdrahn "R_H8_PCREL16", /* name */
201d2201f2fSdrahn FALSE, /* partial_inplace */
202d2201f2fSdrahn 0xffff, /* src_mask */
203d2201f2fSdrahn 0xffff, /* dst_mask */
204d2201f2fSdrahn TRUE), /* pcrel_offset */
205d2201f2fSdrahn #define R_H8_PCREL8_X (R_H8_PCREL16_X + 1)
206d2201f2fSdrahn HOWTO (R_H8_PCREL8, /* type */
207d2201f2fSdrahn 0, /* rightshift */
208d2201f2fSdrahn 0, /* size (0 = byte, 1 = short, 2 = long) */
209d2201f2fSdrahn 8, /* bitsize */
210d2201f2fSdrahn TRUE, /* pc_relative */
211d2201f2fSdrahn 0, /* bitpos */
212d2201f2fSdrahn complain_overflow_signed,/* complain_on_overflow */
213d2201f2fSdrahn special, /* special_function */
214d2201f2fSdrahn "R_H8_PCREL8", /* name */
215d2201f2fSdrahn FALSE, /* partial_inplace */
216d2201f2fSdrahn 0xff, /* src_mask */
217d2201f2fSdrahn 0xff, /* dst_mask */
218d2201f2fSdrahn TRUE), /* pcrel_offset */
219d2201f2fSdrahn };
220d2201f2fSdrahn
221d2201f2fSdrahn /* This structure is used to map BFD reloc codes to H8 ELF relocs. */
222d2201f2fSdrahn
223d2201f2fSdrahn struct elf_reloc_map {
224d2201f2fSdrahn bfd_reloc_code_real_type bfd_reloc_val;
225d2201f2fSdrahn unsigned char howto_index;
226d2201f2fSdrahn };
227d2201f2fSdrahn
228*cf2f2c56Smiod /* An array mapping BFD reloc codes to H8 ELF relocs. */
229d2201f2fSdrahn
230d2201f2fSdrahn static const struct elf_reloc_map h8_reloc_map[] = {
231d2201f2fSdrahn { BFD_RELOC_NONE, R_H8_NONE_X },
232d2201f2fSdrahn { BFD_RELOC_32, R_H8_DIR32_X },
233d2201f2fSdrahn { BFD_RELOC_16, R_H8_DIR16_X },
234d2201f2fSdrahn { BFD_RELOC_8, R_H8_DIR8_X },
235d2201f2fSdrahn { BFD_RELOC_H8_DIR16A8, R_H8_DIR16A8_X },
236d2201f2fSdrahn { BFD_RELOC_H8_DIR16R8, R_H8_DIR16R8_X },
237d2201f2fSdrahn { BFD_RELOC_H8_DIR24A8, R_H8_DIR24A8_X },
238d2201f2fSdrahn { BFD_RELOC_H8_DIR24R8, R_H8_DIR24R8_X },
239d2201f2fSdrahn { BFD_RELOC_H8_DIR32A16, R_H8_DIR32A16_X },
240d2201f2fSdrahn { BFD_RELOC_16_PCREL, R_H8_PCREL16_X },
241d2201f2fSdrahn { BFD_RELOC_8_PCREL, R_H8_PCREL8_X },
242d2201f2fSdrahn };
243d2201f2fSdrahn
244d2201f2fSdrahn
245d2201f2fSdrahn static reloc_howto_type *
elf32_h8_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)246*cf2f2c56Smiod elf32_h8_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
247*cf2f2c56Smiod bfd_reloc_code_real_type code)
248d2201f2fSdrahn {
249d2201f2fSdrahn unsigned int i;
250d2201f2fSdrahn
251d2201f2fSdrahn for (i = 0; i < sizeof (h8_reloc_map) / sizeof (struct elf_reloc_map); i++)
252d2201f2fSdrahn {
253d2201f2fSdrahn if (h8_reloc_map[i].bfd_reloc_val == code)
254d2201f2fSdrahn return &h8_elf_howto_table[(int) h8_reloc_map[i].howto_index];
255d2201f2fSdrahn }
256d2201f2fSdrahn return NULL;
257d2201f2fSdrahn }
258d2201f2fSdrahn
259d2201f2fSdrahn static void
elf32_h8_info_to_howto(bfd * abfd ATTRIBUTE_UNUSED,arelent * bfd_reloc,Elf_Internal_Rela * elf_reloc)260*cf2f2c56Smiod elf32_h8_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
261*cf2f2c56Smiod Elf_Internal_Rela *elf_reloc)
262d2201f2fSdrahn {
263d2201f2fSdrahn unsigned int r;
264d2201f2fSdrahn unsigned int i;
265d2201f2fSdrahn
266d2201f2fSdrahn r = ELF32_R_TYPE (elf_reloc->r_info);
267d2201f2fSdrahn for (i = 0; i < sizeof (h8_elf_howto_table) / sizeof (reloc_howto_type); i++)
268d2201f2fSdrahn if (h8_elf_howto_table[i].type == r)
269d2201f2fSdrahn {
270d2201f2fSdrahn bfd_reloc->howto = &h8_elf_howto_table[i];
271d2201f2fSdrahn return;
272d2201f2fSdrahn }
273d2201f2fSdrahn abort ();
274d2201f2fSdrahn }
275d2201f2fSdrahn
276d2201f2fSdrahn static void
elf32_h8_info_to_howto_rel(bfd * abfd ATTRIBUTE_UNUSED,arelent * bfd_reloc,Elf_Internal_Rela * elf_reloc ATTRIBUTE_UNUSED)277*cf2f2c56Smiod elf32_h8_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
278*cf2f2c56Smiod Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED)
279d2201f2fSdrahn {
280d2201f2fSdrahn unsigned int r;
281d2201f2fSdrahn
282d2201f2fSdrahn abort ();
283d2201f2fSdrahn r = ELF32_R_TYPE (elf_reloc->r_info);
284d2201f2fSdrahn bfd_reloc->howto = &h8_elf_howto_table[r];
285d2201f2fSdrahn }
286d2201f2fSdrahn
287d2201f2fSdrahn /* Special handling for H8/300 relocs.
288d2201f2fSdrahn We only come here for pcrel stuff and return normally if not an -r link.
289d2201f2fSdrahn When doing -r, we can't do any arithmetic for the pcrel stuff, because
290d2201f2fSdrahn we support relaxing on the H8/300 series chips. */
291d2201f2fSdrahn static bfd_reloc_status_type
special(bfd * abfd ATTRIBUTE_UNUSED,arelent * reloc_entry ATTRIBUTE_UNUSED,asymbol * symbol ATTRIBUTE_UNUSED,PTR data ATTRIBUTE_UNUSED,asection * input_section ATTRIBUTE_UNUSED,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)292*cf2f2c56Smiod special (bfd *abfd ATTRIBUTE_UNUSED,
293*cf2f2c56Smiod arelent *reloc_entry ATTRIBUTE_UNUSED,
294*cf2f2c56Smiod asymbol *symbol ATTRIBUTE_UNUSED,
295*cf2f2c56Smiod PTR data ATTRIBUTE_UNUSED,
296*cf2f2c56Smiod asection *input_section ATTRIBUTE_UNUSED,
297*cf2f2c56Smiod bfd *output_bfd,
298*cf2f2c56Smiod char **error_message ATTRIBUTE_UNUSED)
299d2201f2fSdrahn {
300d2201f2fSdrahn if (output_bfd == (bfd *) NULL)
301d2201f2fSdrahn return bfd_reloc_continue;
302d2201f2fSdrahn
303d2201f2fSdrahn /* Adjust the reloc address to that in the output section. */
304d2201f2fSdrahn reloc_entry->address += input_section->output_offset;
305d2201f2fSdrahn return bfd_reloc_ok;
306d2201f2fSdrahn }
307d2201f2fSdrahn
308d2201f2fSdrahn /* Perform a relocation as part of a final link. */
309d2201f2fSdrahn static bfd_reloc_status_type
elf32_h8_final_link_relocate(unsigned long r_type,bfd * input_bfd,bfd * output_bfd ATTRIBUTE_UNUSED,asection * input_section ATTRIBUTE_UNUSED,bfd_byte * contents,bfd_vma offset,bfd_vma value,bfd_vma addend,struct bfd_link_info * info ATTRIBUTE_UNUSED,asection * sym_sec ATTRIBUTE_UNUSED,int is_local ATTRIBUTE_UNUSED)310*cf2f2c56Smiod elf32_h8_final_link_relocate (unsigned long r_type, bfd *input_bfd,
311*cf2f2c56Smiod bfd *output_bfd ATTRIBUTE_UNUSED,
312*cf2f2c56Smiod asection *input_section ATTRIBUTE_UNUSED,
313*cf2f2c56Smiod bfd_byte *contents, bfd_vma offset,
314*cf2f2c56Smiod bfd_vma value, bfd_vma addend,
315*cf2f2c56Smiod struct bfd_link_info *info ATTRIBUTE_UNUSED,
316*cf2f2c56Smiod asection *sym_sec ATTRIBUTE_UNUSED,
317*cf2f2c56Smiod int is_local ATTRIBUTE_UNUSED)
318d2201f2fSdrahn {
319d2201f2fSdrahn bfd_byte *hit_data = contents + offset;
320d2201f2fSdrahn
321d2201f2fSdrahn switch (r_type)
322d2201f2fSdrahn {
323d2201f2fSdrahn case R_H8_NONE:
324d2201f2fSdrahn return bfd_reloc_ok;
325d2201f2fSdrahn
326d2201f2fSdrahn case R_H8_DIR32:
327d2201f2fSdrahn case R_H8_DIR32A16:
328d2201f2fSdrahn case R_H8_DIR24A8:
329d2201f2fSdrahn value += addend;
330d2201f2fSdrahn bfd_put_32 (input_bfd, value, hit_data);
331d2201f2fSdrahn return bfd_reloc_ok;
332d2201f2fSdrahn
333d2201f2fSdrahn case R_H8_DIR16:
334d2201f2fSdrahn case R_H8_DIR16A8:
335d2201f2fSdrahn case R_H8_DIR16R8:
336d2201f2fSdrahn value += addend;
337d2201f2fSdrahn bfd_put_16 (input_bfd, value, hit_data);
338d2201f2fSdrahn return bfd_reloc_ok;
339d2201f2fSdrahn
340d2201f2fSdrahn /* AKA R_RELBYTE */
341d2201f2fSdrahn case R_H8_DIR8:
342d2201f2fSdrahn value += addend;
343d2201f2fSdrahn
344d2201f2fSdrahn bfd_put_8 (input_bfd, value, hit_data);
345d2201f2fSdrahn return bfd_reloc_ok;
346d2201f2fSdrahn
347d2201f2fSdrahn case R_H8_DIR24R8:
348d2201f2fSdrahn value += addend;
349d2201f2fSdrahn
350d2201f2fSdrahn /* HIT_DATA is the address for the first byte for the relocated
351*cf2f2c56Smiod value. Subtract 1 so that we can manipulate the data in 32-bit
352d2201f2fSdrahn hunks. */
353d2201f2fSdrahn hit_data--;
354d2201f2fSdrahn
355d2201f2fSdrahn /* Clear out the top byte in value. */
356d2201f2fSdrahn value &= 0xffffff;
357d2201f2fSdrahn
358d2201f2fSdrahn /* Retrieve the type byte for value from the section contents. */
359d2201f2fSdrahn value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
360d2201f2fSdrahn
361*cf2f2c56Smiod /* Now scribble it out in one 32-bit hunk. */
362d2201f2fSdrahn bfd_put_32 (input_bfd, value, hit_data);
363d2201f2fSdrahn return bfd_reloc_ok;
364d2201f2fSdrahn
365d2201f2fSdrahn case R_H8_PCREL16:
366d2201f2fSdrahn value -= (input_section->output_section->vma
367d2201f2fSdrahn + input_section->output_offset);
368d2201f2fSdrahn value -= offset;
369d2201f2fSdrahn value += addend;
370d2201f2fSdrahn
371d2201f2fSdrahn /* The value is relative to the start of the instruction,
372d2201f2fSdrahn not the relocation offset. Subtract 2 to account for
373d2201f2fSdrahn this minor issue. */
374d2201f2fSdrahn value -= 2;
375d2201f2fSdrahn
376d2201f2fSdrahn bfd_put_16 (input_bfd, value, hit_data);
377d2201f2fSdrahn return bfd_reloc_ok;
378d2201f2fSdrahn
379d2201f2fSdrahn case R_H8_PCREL8:
380d2201f2fSdrahn value -= (input_section->output_section->vma
381d2201f2fSdrahn + input_section->output_offset);
382d2201f2fSdrahn value -= offset;
383d2201f2fSdrahn value += addend;
384d2201f2fSdrahn
385d2201f2fSdrahn /* The value is relative to the start of the instruction,
386d2201f2fSdrahn not the relocation offset. Subtract 1 to account for
387d2201f2fSdrahn this minor issue. */
388d2201f2fSdrahn value -= 1;
389d2201f2fSdrahn
390d2201f2fSdrahn bfd_put_8 (input_bfd, value, hit_data);
391d2201f2fSdrahn return bfd_reloc_ok;
392d2201f2fSdrahn
393d2201f2fSdrahn default:
394d2201f2fSdrahn return bfd_reloc_notsupported;
395d2201f2fSdrahn }
396d2201f2fSdrahn }
397d2201f2fSdrahn
398d2201f2fSdrahn /* Relocate an H8 ELF section. */
399d2201f2fSdrahn static bfd_boolean
elf32_h8_relocate_section(bfd * output_bfd,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)400*cf2f2c56Smiod elf32_h8_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
401*cf2f2c56Smiod bfd *input_bfd, asection *input_section,
402*cf2f2c56Smiod bfd_byte *contents, Elf_Internal_Rela *relocs,
403*cf2f2c56Smiod Elf_Internal_Sym *local_syms,
404*cf2f2c56Smiod asection **local_sections)
405d2201f2fSdrahn {
406d2201f2fSdrahn Elf_Internal_Shdr *symtab_hdr;
407d2201f2fSdrahn struct elf_link_hash_entry **sym_hashes;
408d2201f2fSdrahn Elf_Internal_Rela *rel, *relend;
409d2201f2fSdrahn
410*cf2f2c56Smiod if (info->relocatable)
411d2201f2fSdrahn return TRUE;
412d2201f2fSdrahn
413d2201f2fSdrahn symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
414d2201f2fSdrahn sym_hashes = elf_sym_hashes (input_bfd);
415d2201f2fSdrahn
416d2201f2fSdrahn rel = relocs;
417d2201f2fSdrahn relend = relocs + input_section->reloc_count;
418d2201f2fSdrahn for (; rel < relend; rel++)
419d2201f2fSdrahn {
420d2201f2fSdrahn unsigned int r_type;
421d2201f2fSdrahn unsigned long r_symndx;
422d2201f2fSdrahn Elf_Internal_Sym *sym;
423d2201f2fSdrahn asection *sec;
424d2201f2fSdrahn struct elf_link_hash_entry *h;
425d2201f2fSdrahn bfd_vma relocation;
426d2201f2fSdrahn bfd_reloc_status_type r;
427d2201f2fSdrahn
428d2201f2fSdrahn /* This is a final link. */
429d2201f2fSdrahn r_symndx = ELF32_R_SYM (rel->r_info);
430d2201f2fSdrahn r_type = ELF32_R_TYPE (rel->r_info);
431d2201f2fSdrahn h = NULL;
432d2201f2fSdrahn sym = NULL;
433d2201f2fSdrahn sec = NULL;
434d2201f2fSdrahn if (r_symndx < symtab_hdr->sh_info)
435d2201f2fSdrahn {
436d2201f2fSdrahn sym = local_syms + r_symndx;
437d2201f2fSdrahn sec = local_sections[r_symndx];
438*cf2f2c56Smiod relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
439d2201f2fSdrahn }
440d2201f2fSdrahn else
441d2201f2fSdrahn {
442*cf2f2c56Smiod bfd_boolean unresolved_reloc, warned;
443*cf2f2c56Smiod
444*cf2f2c56Smiod RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
445*cf2f2c56Smiod r_symndx, symtab_hdr, sym_hashes,
446*cf2f2c56Smiod h, sec, relocation,
447*cf2f2c56Smiod unresolved_reloc, warned);
448d2201f2fSdrahn }
449d2201f2fSdrahn
450d2201f2fSdrahn r = elf32_h8_final_link_relocate (r_type, input_bfd, output_bfd,
451d2201f2fSdrahn input_section,
452d2201f2fSdrahn contents, rel->r_offset,
453d2201f2fSdrahn relocation, rel->r_addend,
454d2201f2fSdrahn info, sec, h == NULL);
455d2201f2fSdrahn
456d2201f2fSdrahn if (r != bfd_reloc_ok)
457d2201f2fSdrahn {
458d2201f2fSdrahn const char *name;
459d2201f2fSdrahn const char *msg = (const char *) 0;
460d2201f2fSdrahn arelent bfd_reloc;
461d2201f2fSdrahn reloc_howto_type *howto;
462d2201f2fSdrahn
463d2201f2fSdrahn elf32_h8_info_to_howto (input_bfd, &bfd_reloc, rel);
464d2201f2fSdrahn howto = bfd_reloc.howto;
465d2201f2fSdrahn
466d2201f2fSdrahn if (h != NULL)
467d2201f2fSdrahn name = h->root.root.string;
468d2201f2fSdrahn else
469d2201f2fSdrahn {
470d2201f2fSdrahn name = (bfd_elf_string_from_elf_section
471d2201f2fSdrahn (input_bfd, symtab_hdr->sh_link, sym->st_name));
472d2201f2fSdrahn if (name == NULL || *name == '\0')
473d2201f2fSdrahn name = bfd_section_name (input_bfd, sec);
474d2201f2fSdrahn }
475d2201f2fSdrahn
476d2201f2fSdrahn switch (r)
477d2201f2fSdrahn {
478d2201f2fSdrahn case bfd_reloc_overflow:
479d2201f2fSdrahn if (! ((*info->callbacks->reloc_overflow)
480d2201f2fSdrahn (info, name, howto->name, (bfd_vma) 0,
481d2201f2fSdrahn input_bfd, input_section, rel->r_offset)))
482d2201f2fSdrahn return FALSE;
483d2201f2fSdrahn break;
484d2201f2fSdrahn
485d2201f2fSdrahn case bfd_reloc_undefined:
486d2201f2fSdrahn if (! ((*info->callbacks->undefined_symbol)
487d2201f2fSdrahn (info, name, input_bfd, input_section,
488d2201f2fSdrahn rel->r_offset, TRUE)))
489d2201f2fSdrahn return FALSE;
490d2201f2fSdrahn break;
491d2201f2fSdrahn
492d2201f2fSdrahn case bfd_reloc_outofrange:
493d2201f2fSdrahn msg = _("internal error: out of range error");
494d2201f2fSdrahn goto common_error;
495d2201f2fSdrahn
496d2201f2fSdrahn case bfd_reloc_notsupported:
497d2201f2fSdrahn msg = _("internal error: unsupported relocation error");
498d2201f2fSdrahn goto common_error;
499d2201f2fSdrahn
500d2201f2fSdrahn case bfd_reloc_dangerous:
501d2201f2fSdrahn msg = _("internal error: dangerous error");
502d2201f2fSdrahn goto common_error;
503d2201f2fSdrahn
504d2201f2fSdrahn default:
505d2201f2fSdrahn msg = _("internal error: unknown error");
506d2201f2fSdrahn /* fall through */
507d2201f2fSdrahn
508d2201f2fSdrahn common_error:
509d2201f2fSdrahn if (!((*info->callbacks->warning)
510d2201f2fSdrahn (info, msg, name, input_bfd, input_section,
511d2201f2fSdrahn rel->r_offset)))
512d2201f2fSdrahn return FALSE;
513d2201f2fSdrahn break;
514d2201f2fSdrahn }
515d2201f2fSdrahn }
516d2201f2fSdrahn }
517d2201f2fSdrahn
518d2201f2fSdrahn return TRUE;
519d2201f2fSdrahn }
520d2201f2fSdrahn
521d2201f2fSdrahn /* Object files encode the specific H8 model they were compiled
522d2201f2fSdrahn for in the ELF flags field.
523d2201f2fSdrahn
524d2201f2fSdrahn Examine that field and return the proper BFD machine type for
525d2201f2fSdrahn the object file. */
526d2201f2fSdrahn static unsigned long
elf32_h8_mach(flagword flags)527*cf2f2c56Smiod elf32_h8_mach (flagword flags)
528d2201f2fSdrahn {
529d2201f2fSdrahn switch (flags & EF_H8_MACH)
530d2201f2fSdrahn {
531d2201f2fSdrahn case E_H8_MACH_H8300:
532d2201f2fSdrahn default:
533d2201f2fSdrahn return bfd_mach_h8300;
534d2201f2fSdrahn
535d2201f2fSdrahn case E_H8_MACH_H8300H:
536d2201f2fSdrahn return bfd_mach_h8300h;
537d2201f2fSdrahn
538d2201f2fSdrahn case E_H8_MACH_H8300S:
539d2201f2fSdrahn return bfd_mach_h8300s;
540d2201f2fSdrahn
541d2201f2fSdrahn case E_H8_MACH_H8300HN:
542d2201f2fSdrahn return bfd_mach_h8300hn;
543d2201f2fSdrahn
544d2201f2fSdrahn case E_H8_MACH_H8300SN:
545d2201f2fSdrahn return bfd_mach_h8300sn;
546*cf2f2c56Smiod
547*cf2f2c56Smiod case E_H8_MACH_H8300SX:
548*cf2f2c56Smiod return bfd_mach_h8300sx;
549*cf2f2c56Smiod
550*cf2f2c56Smiod case E_H8_MACH_H8300SXN:
551*cf2f2c56Smiod return bfd_mach_h8300sxn;
552d2201f2fSdrahn }
553d2201f2fSdrahn }
554d2201f2fSdrahn
555d2201f2fSdrahn /* The final processing done just before writing out a H8 ELF object
556d2201f2fSdrahn file. We use this opportunity to encode the BFD machine type
557d2201f2fSdrahn into the flags field in the object file. */
558d2201f2fSdrahn
559d2201f2fSdrahn static void
elf32_h8_final_write_processing(bfd * abfd,bfd_boolean linker ATTRIBUTE_UNUSED)560*cf2f2c56Smiod elf32_h8_final_write_processing (bfd *abfd,
561*cf2f2c56Smiod bfd_boolean linker ATTRIBUTE_UNUSED)
562d2201f2fSdrahn {
563d2201f2fSdrahn unsigned long val;
564d2201f2fSdrahn
565d2201f2fSdrahn switch (bfd_get_mach (abfd))
566d2201f2fSdrahn {
567d2201f2fSdrahn default:
568d2201f2fSdrahn case bfd_mach_h8300:
569d2201f2fSdrahn val = E_H8_MACH_H8300;
570d2201f2fSdrahn break;
571d2201f2fSdrahn
572d2201f2fSdrahn case bfd_mach_h8300h:
573d2201f2fSdrahn val = E_H8_MACH_H8300H;
574d2201f2fSdrahn break;
575d2201f2fSdrahn
576d2201f2fSdrahn case bfd_mach_h8300s:
577d2201f2fSdrahn val = E_H8_MACH_H8300S;
578d2201f2fSdrahn break;
579d2201f2fSdrahn
580d2201f2fSdrahn case bfd_mach_h8300hn:
581d2201f2fSdrahn val = E_H8_MACH_H8300HN;
582d2201f2fSdrahn break;
583d2201f2fSdrahn
584d2201f2fSdrahn case bfd_mach_h8300sn:
585d2201f2fSdrahn val = E_H8_MACH_H8300SN;
586d2201f2fSdrahn break;
587*cf2f2c56Smiod
588*cf2f2c56Smiod case bfd_mach_h8300sx:
589*cf2f2c56Smiod val = E_H8_MACH_H8300SX;
590*cf2f2c56Smiod break;
591*cf2f2c56Smiod
592*cf2f2c56Smiod case bfd_mach_h8300sxn:
593*cf2f2c56Smiod val = E_H8_MACH_H8300SXN;
594*cf2f2c56Smiod break;
595d2201f2fSdrahn }
596d2201f2fSdrahn
597d2201f2fSdrahn elf_elfheader (abfd)->e_flags &= ~ (EF_H8_MACH);
598d2201f2fSdrahn elf_elfheader (abfd)->e_flags |= val;
599d2201f2fSdrahn }
600d2201f2fSdrahn
601d2201f2fSdrahn /* Return nonzero if ABFD represents a valid H8 ELF object file; also
602d2201f2fSdrahn record the encoded machine type found in the ELF flags. */
603d2201f2fSdrahn
604d2201f2fSdrahn static bfd_boolean
elf32_h8_object_p(bfd * abfd)605*cf2f2c56Smiod elf32_h8_object_p (bfd *abfd)
606d2201f2fSdrahn {
607d2201f2fSdrahn bfd_default_set_arch_mach (abfd, bfd_arch_h8300,
608d2201f2fSdrahn elf32_h8_mach (elf_elfheader (abfd)->e_flags));
609d2201f2fSdrahn return TRUE;
610d2201f2fSdrahn }
611d2201f2fSdrahn
612d2201f2fSdrahn /* Merge backend specific data from an object file to the output
613d2201f2fSdrahn object file when linking. The only data we need to copy at this
614d2201f2fSdrahn time is the architecture/machine information. */
615d2201f2fSdrahn
616d2201f2fSdrahn static bfd_boolean
elf32_h8_merge_private_bfd_data(bfd * ibfd,bfd * obfd)617*cf2f2c56Smiod elf32_h8_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
618d2201f2fSdrahn {
619d2201f2fSdrahn if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
620d2201f2fSdrahn || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
621d2201f2fSdrahn return TRUE;
622d2201f2fSdrahn
623d2201f2fSdrahn if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
624d2201f2fSdrahn && bfd_get_mach (obfd) < bfd_get_mach (ibfd))
625d2201f2fSdrahn {
626d2201f2fSdrahn if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
627d2201f2fSdrahn bfd_get_mach (ibfd)))
628d2201f2fSdrahn return FALSE;
629d2201f2fSdrahn }
630d2201f2fSdrahn
631d2201f2fSdrahn return TRUE;
632d2201f2fSdrahn }
633d2201f2fSdrahn
634d2201f2fSdrahn /* This function handles relaxing for the H8..
635d2201f2fSdrahn
636*cf2f2c56Smiod There are a few relaxing opportunities available on the H8:
637d2201f2fSdrahn
638d2201f2fSdrahn jmp/jsr:24 -> bra/bsr:8 2 bytes
639d2201f2fSdrahn The jmp may be completely eliminated if the previous insn is a
640d2201f2fSdrahn conditional branch to the insn after the jump. In that case
641d2201f2fSdrahn we invert the branch and delete the jump and save 4 bytes.
642d2201f2fSdrahn
643d2201f2fSdrahn bCC:16 -> bCC:8 2 bytes
644d2201f2fSdrahn bsr:16 -> bsr:8 2 bytes
645d2201f2fSdrahn
646*cf2f2c56Smiod bset:16 -> bset:8 2 bytes
647*cf2f2c56Smiod bset:24/32 -> bset:8 4 bytes
648*cf2f2c56Smiod (also applicable to other bit manipulation instructions)
649*cf2f2c56Smiod
650d2201f2fSdrahn mov.b:16 -> mov.b:8 2 bytes
651d2201f2fSdrahn mov.b:24/32 -> mov.b:8 4 bytes
652d2201f2fSdrahn
653*cf2f2c56Smiod bset:24/32 -> bset:16 2 bytes
654*cf2f2c56Smiod (also applicable to other bit manipulation instructions)
655*cf2f2c56Smiod
656d2201f2fSdrahn mov.[bwl]:24/32 -> mov.[bwl]:16 2 bytes */
657d2201f2fSdrahn
658d2201f2fSdrahn static bfd_boolean
elf32_h8_relax_section(bfd * abfd,asection * sec,struct bfd_link_info * link_info,bfd_boolean * again)659*cf2f2c56Smiod elf32_h8_relax_section (bfd *abfd, asection *sec,
660*cf2f2c56Smiod struct bfd_link_info *link_info, bfd_boolean *again)
661d2201f2fSdrahn {
662d2201f2fSdrahn Elf_Internal_Shdr *symtab_hdr;
663d2201f2fSdrahn Elf_Internal_Rela *internal_relocs;
664d2201f2fSdrahn Elf_Internal_Rela *irel, *irelend;
665d2201f2fSdrahn bfd_byte *contents = NULL;
666d2201f2fSdrahn Elf_Internal_Sym *isymbuf = NULL;
667d2201f2fSdrahn static asection *last_input_section = NULL;
668d2201f2fSdrahn static Elf_Internal_Rela *last_reloc = NULL;
669d2201f2fSdrahn
670d2201f2fSdrahn /* Assume nothing changes. */
671d2201f2fSdrahn *again = FALSE;
672d2201f2fSdrahn
673*cf2f2c56Smiod /* We don't have to do anything for a relocatable link, if
674d2201f2fSdrahn this section does not have relocs, or if this is not a
675d2201f2fSdrahn code section. */
676*cf2f2c56Smiod if (link_info->relocatable
677d2201f2fSdrahn || (sec->flags & SEC_RELOC) == 0
678d2201f2fSdrahn || sec->reloc_count == 0
679d2201f2fSdrahn || (sec->flags & SEC_CODE) == 0)
680d2201f2fSdrahn return TRUE;
681d2201f2fSdrahn
682d2201f2fSdrahn /* If this is the first time we have been called for this section,
683d2201f2fSdrahn initialize the cooked size. */
684d2201f2fSdrahn if (sec->_cooked_size == 0)
685d2201f2fSdrahn sec->_cooked_size = sec->_raw_size;
686d2201f2fSdrahn
687d2201f2fSdrahn symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
688d2201f2fSdrahn
689d2201f2fSdrahn /* Get a copy of the native relocations. */
690*cf2f2c56Smiod internal_relocs = (_bfd_elf_link_read_relocs
691d2201f2fSdrahn (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
692d2201f2fSdrahn link_info->keep_memory));
693d2201f2fSdrahn if (internal_relocs == NULL)
694d2201f2fSdrahn goto error_return;
695d2201f2fSdrahn
696d2201f2fSdrahn if (sec != last_input_section)
697d2201f2fSdrahn last_reloc = NULL;
698d2201f2fSdrahn
699d2201f2fSdrahn last_input_section = sec;
700d2201f2fSdrahn
701d2201f2fSdrahn /* Walk through the relocs looking for relaxing opportunities. */
702d2201f2fSdrahn irelend = internal_relocs + sec->reloc_count;
703d2201f2fSdrahn for (irel = internal_relocs; irel < irelend; irel++)
704d2201f2fSdrahn {
705d2201f2fSdrahn bfd_vma symval;
706d2201f2fSdrahn
707d2201f2fSdrahn /* Keep track of the previous reloc so that we can delete
708d2201f2fSdrahn some long jumps created by the compiler. */
709d2201f2fSdrahn if (irel != internal_relocs)
710d2201f2fSdrahn last_reloc = irel - 1;
711d2201f2fSdrahn
712d2201f2fSdrahn if (ELF32_R_TYPE (irel->r_info) != R_H8_DIR24R8
713d2201f2fSdrahn && ELF32_R_TYPE (irel->r_info) != R_H8_PCREL16
714d2201f2fSdrahn && ELF32_R_TYPE (irel->r_info) != R_H8_DIR16A8
715d2201f2fSdrahn && ELF32_R_TYPE (irel->r_info) != R_H8_DIR24A8
716d2201f2fSdrahn && ELF32_R_TYPE (irel->r_info) != R_H8_DIR32A16)
717d2201f2fSdrahn continue;
718d2201f2fSdrahn
719d2201f2fSdrahn /* Get the section contents if we haven't done so already. */
720d2201f2fSdrahn if (contents == NULL)
721d2201f2fSdrahn {
722d2201f2fSdrahn /* Get cached copy if it exists. */
723d2201f2fSdrahn if (elf_section_data (sec)->this_hdr.contents != NULL)
724d2201f2fSdrahn contents = elf_section_data (sec)->this_hdr.contents;
725d2201f2fSdrahn else
726d2201f2fSdrahn {
727d2201f2fSdrahn /* Go get them off disk. */
728d2201f2fSdrahn contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
729d2201f2fSdrahn if (contents == NULL)
730d2201f2fSdrahn goto error_return;
731d2201f2fSdrahn
732d2201f2fSdrahn if (! bfd_get_section_contents (abfd, sec, contents,
733d2201f2fSdrahn (file_ptr) 0, sec->_raw_size))
734d2201f2fSdrahn goto error_return;
735d2201f2fSdrahn }
736d2201f2fSdrahn }
737d2201f2fSdrahn
738d2201f2fSdrahn /* Read this BFD's local symbols if we haven't done so already. */
739d2201f2fSdrahn if (isymbuf == NULL && symtab_hdr->sh_info != 0)
740d2201f2fSdrahn {
741d2201f2fSdrahn isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
742d2201f2fSdrahn if (isymbuf == NULL)
743d2201f2fSdrahn isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
744d2201f2fSdrahn symtab_hdr->sh_info, 0,
745d2201f2fSdrahn NULL, NULL, NULL);
746d2201f2fSdrahn if (isymbuf == NULL)
747d2201f2fSdrahn goto error_return;
748d2201f2fSdrahn }
749d2201f2fSdrahn
750d2201f2fSdrahn /* Get the value of the symbol referred to by the reloc. */
751d2201f2fSdrahn if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
752d2201f2fSdrahn {
753d2201f2fSdrahn /* A local symbol. */
754d2201f2fSdrahn Elf_Internal_Sym *isym;
755d2201f2fSdrahn asection *sym_sec;
756d2201f2fSdrahn
757d2201f2fSdrahn isym = isymbuf + ELF32_R_SYM (irel->r_info);
758d2201f2fSdrahn sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
759*cf2f2c56Smiod symval = isym->st_value;
760*cf2f2c56Smiod /* If the reloc is absolute, it will not have
761*cf2f2c56Smiod a symbol or section associated with it. */
762*cf2f2c56Smiod if (sym_sec)
763*cf2f2c56Smiod symval += sym_sec->output_section->vma
764*cf2f2c56Smiod + sym_sec->output_offset;
765d2201f2fSdrahn }
766d2201f2fSdrahn else
767d2201f2fSdrahn {
768d2201f2fSdrahn unsigned long indx;
769d2201f2fSdrahn struct elf_link_hash_entry *h;
770d2201f2fSdrahn
771d2201f2fSdrahn /* An external symbol. */
772d2201f2fSdrahn indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
773d2201f2fSdrahn h = elf_sym_hashes (abfd)[indx];
774d2201f2fSdrahn BFD_ASSERT (h != NULL);
775d2201f2fSdrahn if (h->root.type != bfd_link_hash_defined
776d2201f2fSdrahn && h->root.type != bfd_link_hash_defweak)
777d2201f2fSdrahn {
778d2201f2fSdrahn /* This appears to be a reference to an undefined
779d2201f2fSdrahn symbol. Just ignore it--it will be caught by the
780d2201f2fSdrahn regular reloc processing. */
781d2201f2fSdrahn continue;
782d2201f2fSdrahn }
783d2201f2fSdrahn
784d2201f2fSdrahn symval = (h->root.u.def.value
785d2201f2fSdrahn + h->root.u.def.section->output_section->vma
786d2201f2fSdrahn + h->root.u.def.section->output_offset);
787d2201f2fSdrahn }
788d2201f2fSdrahn
789d2201f2fSdrahn /* For simplicity of coding, we are going to modify the section
790d2201f2fSdrahn contents, the section relocs, and the BFD symbol table. We
791d2201f2fSdrahn must tell the rest of the code not to free up this
792d2201f2fSdrahn information. It would be possible to instead create a table
793d2201f2fSdrahn of changes which have to be made, as is done in coff-mips.c;
794d2201f2fSdrahn that would be more work, but would require less memory when
795d2201f2fSdrahn the linker is run. */
796d2201f2fSdrahn switch (ELF32_R_TYPE (irel->r_info))
797d2201f2fSdrahn {
798*cf2f2c56Smiod /* Try to turn a 24-bit absolute branch/call into an 8-bit
799d2201f2fSdrahn pc-relative branch/call. */
800d2201f2fSdrahn case R_H8_DIR24R8:
801d2201f2fSdrahn {
802d2201f2fSdrahn bfd_vma value = symval + irel->r_addend;
803d2201f2fSdrahn bfd_vma dot, gap;
804d2201f2fSdrahn
805d2201f2fSdrahn /* Get the address of this instruction. */
806d2201f2fSdrahn dot = (sec->output_section->vma
807d2201f2fSdrahn + sec->output_offset + irel->r_offset - 1);
808d2201f2fSdrahn
809d2201f2fSdrahn /* Compute the distance from this insn to the branch target. */
810d2201f2fSdrahn gap = value - dot;
811d2201f2fSdrahn
812d2201f2fSdrahn /* If the distance is within -126..+130 inclusive, then we can
813d2201f2fSdrahn relax this jump. +130 is valid since the target will move
814d2201f2fSdrahn two bytes closer if we do relax this branch. */
815d2201f2fSdrahn if ((int) gap >= -126 && (int) gap <= 130)
816d2201f2fSdrahn {
817d2201f2fSdrahn unsigned char code;
818d2201f2fSdrahn
819d2201f2fSdrahn /* Note that we've changed the relocs, section contents,
820d2201f2fSdrahn etc. */
821d2201f2fSdrahn elf_section_data (sec)->relocs = internal_relocs;
822d2201f2fSdrahn elf_section_data (sec)->this_hdr.contents = contents;
823d2201f2fSdrahn symtab_hdr->contents = (unsigned char *) isymbuf;
824d2201f2fSdrahn
825d2201f2fSdrahn /* Get the instruction code being relaxed. */
826d2201f2fSdrahn code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
827d2201f2fSdrahn
828d2201f2fSdrahn /* If the previous instruction conditionally jumped around
829d2201f2fSdrahn this instruction, we may be able to reverse the condition
830d2201f2fSdrahn and redirect the previous instruction to the target of
831d2201f2fSdrahn this instruction.
832d2201f2fSdrahn
833d2201f2fSdrahn Such sequences are used by the compiler to deal with
834d2201f2fSdrahn long conditional branches.
835d2201f2fSdrahn
836d2201f2fSdrahn Only perform this optimisation for jumps (code 0x5a) not
837d2201f2fSdrahn subroutine calls, as otherwise it could transform:
838d2201f2fSdrahn
839d2201f2fSdrahn mov.w r0,r0
840d2201f2fSdrahn beq .L1
841d2201f2fSdrahn jsr @_bar
842d2201f2fSdrahn .L1: rts
843d2201f2fSdrahn _bar: rts
844d2201f2fSdrahn into:
845d2201f2fSdrahn mov.w r0,r0
846d2201f2fSdrahn bne _bar
847d2201f2fSdrahn rts
848d2201f2fSdrahn _bar: rts
849d2201f2fSdrahn
850d2201f2fSdrahn which changes the call (jsr) into a branch (bne). */
851d2201f2fSdrahn if (code == 0x5a
852d2201f2fSdrahn && (int) gap <= 130
853d2201f2fSdrahn && (int) gap >= -128
854d2201f2fSdrahn && last_reloc
855d2201f2fSdrahn && ELF32_R_TYPE (last_reloc->r_info) == R_H8_PCREL8
856d2201f2fSdrahn && ELF32_R_SYM (last_reloc->r_info) < symtab_hdr->sh_info)
857d2201f2fSdrahn {
858d2201f2fSdrahn bfd_vma last_value;
859d2201f2fSdrahn asection *last_sym_sec;
860d2201f2fSdrahn Elf_Internal_Sym *last_sym;
861d2201f2fSdrahn
862d2201f2fSdrahn /* We will need to examine the symbol used by the
863d2201f2fSdrahn previous relocation. */
864d2201f2fSdrahn
865d2201f2fSdrahn last_sym = isymbuf + ELF32_R_SYM (last_reloc->r_info);
866d2201f2fSdrahn last_sym_sec
867d2201f2fSdrahn = bfd_section_from_elf_index (abfd, last_sym->st_shndx);
868d2201f2fSdrahn last_value = (last_sym->st_value
869d2201f2fSdrahn + last_sym_sec->output_section->vma
870d2201f2fSdrahn + last_sym_sec->output_offset);
871d2201f2fSdrahn
872d2201f2fSdrahn /* Verify that the previous relocation was for a
873d2201f2fSdrahn branch around this instruction and that no symbol
874d2201f2fSdrahn exists at the current location. */
875d2201f2fSdrahn if (last_value == dot + 4
876d2201f2fSdrahn && last_reloc->r_offset + 2 == irel->r_offset
877d2201f2fSdrahn && ! elf32_h8_symbol_address_p (abfd, sec, dot))
878d2201f2fSdrahn {
879d2201f2fSdrahn /* We can eliminate this jump. Twiddle the
880d2201f2fSdrahn previous relocation as necessary. */
881d2201f2fSdrahn irel->r_info
882d2201f2fSdrahn = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
883d2201f2fSdrahn ELF32_R_TYPE (R_H8_NONE));
884d2201f2fSdrahn
885d2201f2fSdrahn last_reloc->r_info
886d2201f2fSdrahn = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
887d2201f2fSdrahn ELF32_R_TYPE (R_H8_PCREL8));
888d2201f2fSdrahn last_reloc->r_addend = irel->r_addend;
889d2201f2fSdrahn
890d2201f2fSdrahn code = bfd_get_8 (abfd,
891d2201f2fSdrahn contents + last_reloc->r_offset - 1);
892d2201f2fSdrahn code ^= 1;
893d2201f2fSdrahn bfd_put_8 (abfd,
894d2201f2fSdrahn code,
895d2201f2fSdrahn contents + last_reloc->r_offset - 1);
896d2201f2fSdrahn
897d2201f2fSdrahn /* Delete four bytes of data. */
898d2201f2fSdrahn if (!elf32_h8_relax_delete_bytes (abfd, sec,
899d2201f2fSdrahn irel->r_offset - 1,
900d2201f2fSdrahn 4))
901d2201f2fSdrahn goto error_return;
902d2201f2fSdrahn
903d2201f2fSdrahn *again = TRUE;
904d2201f2fSdrahn break;
905d2201f2fSdrahn }
906d2201f2fSdrahn }
907d2201f2fSdrahn
908d2201f2fSdrahn if (code == 0x5e)
909*cf2f2c56Smiod /* This is jsr. */
910d2201f2fSdrahn bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 1);
911d2201f2fSdrahn else if (code == 0x5a)
912*cf2f2c56Smiod /* This is jmp. */
913d2201f2fSdrahn bfd_put_8 (abfd, 0x40, contents + irel->r_offset - 1);
914d2201f2fSdrahn else
915d2201f2fSdrahn abort ();
916d2201f2fSdrahn
917d2201f2fSdrahn /* Fix the relocation's type. */
918d2201f2fSdrahn irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
919d2201f2fSdrahn R_H8_PCREL8);
920d2201f2fSdrahn
921d2201f2fSdrahn /* Delete two bytes of data. */
922d2201f2fSdrahn if (!elf32_h8_relax_delete_bytes (abfd, sec,
923d2201f2fSdrahn irel->r_offset + 1, 2))
924d2201f2fSdrahn goto error_return;
925d2201f2fSdrahn
926d2201f2fSdrahn /* That will change things, so, we should relax again.
927d2201f2fSdrahn Note that this is not required, and it may be slow. */
928d2201f2fSdrahn *again = TRUE;
929d2201f2fSdrahn }
930d2201f2fSdrahn break;
931d2201f2fSdrahn }
932d2201f2fSdrahn
933*cf2f2c56Smiod /* Try to turn a 16-bit pc-relative branch into a 8-bit pc-relative
934d2201f2fSdrahn branch. */
935d2201f2fSdrahn case R_H8_PCREL16:
936d2201f2fSdrahn {
937d2201f2fSdrahn bfd_vma value = symval + irel->r_addend;
938d2201f2fSdrahn bfd_vma dot;
939d2201f2fSdrahn bfd_vma gap;
940d2201f2fSdrahn
941d2201f2fSdrahn /* Get the address of this instruction. */
942d2201f2fSdrahn dot = (sec->output_section->vma
943d2201f2fSdrahn + sec->output_offset
944d2201f2fSdrahn + irel->r_offset - 2);
945d2201f2fSdrahn
946d2201f2fSdrahn gap = value - dot;
947d2201f2fSdrahn
948d2201f2fSdrahn /* If the distance is within -126..+130 inclusive, then we can
949d2201f2fSdrahn relax this jump. +130 is valid since the target will move
950d2201f2fSdrahn two bytes closer if we do relax this branch. */
951d2201f2fSdrahn if ((int) gap >= -126 && (int) gap <= 130)
952d2201f2fSdrahn {
953d2201f2fSdrahn unsigned char code;
954d2201f2fSdrahn
955d2201f2fSdrahn /* Note that we've changed the relocs, section contents,
956d2201f2fSdrahn etc. */
957d2201f2fSdrahn elf_section_data (sec)->relocs = internal_relocs;
958d2201f2fSdrahn elf_section_data (sec)->this_hdr.contents = contents;
959d2201f2fSdrahn symtab_hdr->contents = (unsigned char *) isymbuf;
960d2201f2fSdrahn
961d2201f2fSdrahn /* Get the opcode. */
962d2201f2fSdrahn code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
963d2201f2fSdrahn
964d2201f2fSdrahn if (code == 0x58)
965d2201f2fSdrahn {
966d2201f2fSdrahn /* bCC:16 -> bCC:8 */
967*cf2f2c56Smiod /* Get the second byte of the original insn, which
968*cf2f2c56Smiod contains the condition code. */
969d2201f2fSdrahn code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
970*cf2f2c56Smiod
971*cf2f2c56Smiod /* Compute the fisrt byte of the relaxed
972*cf2f2c56Smiod instruction. The original sequence 0x58 0xX0
973*cf2f2c56Smiod is relaxed to 0x4X, where X represents the
974*cf2f2c56Smiod condition code. */
975d2201f2fSdrahn code &= 0xf0;
976d2201f2fSdrahn code >>= 4;
977d2201f2fSdrahn code |= 0x40;
978d2201f2fSdrahn bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
979d2201f2fSdrahn }
980d2201f2fSdrahn else if (code == 0x5c)
981*cf2f2c56Smiod /* This is bsr. */
982d2201f2fSdrahn bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 2);
983d2201f2fSdrahn else
984d2201f2fSdrahn abort ();
985d2201f2fSdrahn
986d2201f2fSdrahn /* Fix the relocation's type. */
987d2201f2fSdrahn irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
988d2201f2fSdrahn R_H8_PCREL8);
989d2201f2fSdrahn irel->r_offset--;
990d2201f2fSdrahn
991d2201f2fSdrahn /* Delete two bytes of data. */
992d2201f2fSdrahn if (!elf32_h8_relax_delete_bytes (abfd, sec,
993d2201f2fSdrahn irel->r_offset + 1, 2))
994d2201f2fSdrahn goto error_return;
995d2201f2fSdrahn
996d2201f2fSdrahn /* That will change things, so, we should relax again.
997d2201f2fSdrahn Note that this is not required, and it may be slow. */
998d2201f2fSdrahn *again = TRUE;
999d2201f2fSdrahn }
1000d2201f2fSdrahn break;
1001d2201f2fSdrahn }
1002d2201f2fSdrahn
1003*cf2f2c56Smiod /* This is a 16-bit absolute address in one of the following
1004*cf2f2c56Smiod instructions:
1005*cf2f2c56Smiod
1006*cf2f2c56Smiod "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
1007*cf2f2c56Smiod "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
1008*cf2f2c56Smiod "mov.b"
1009*cf2f2c56Smiod
1010*cf2f2c56Smiod We may relax this into an 8-bit absolute address if it's in
1011*cf2f2c56Smiod the right range. */
1012d2201f2fSdrahn case R_H8_DIR16A8:
1013d2201f2fSdrahn {
1014*cf2f2c56Smiod bfd_vma value;
1015d2201f2fSdrahn
1016*cf2f2c56Smiod value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
1017*cf2f2c56Smiod if (value >= 0xffffff00u)
1018d2201f2fSdrahn {
1019d2201f2fSdrahn unsigned char code;
1020*cf2f2c56Smiod unsigned char temp_code;
1021d2201f2fSdrahn
1022d2201f2fSdrahn /* Note that we've changed the relocs, section contents,
1023d2201f2fSdrahn etc. */
1024d2201f2fSdrahn elf_section_data (sec)->relocs = internal_relocs;
1025d2201f2fSdrahn elf_section_data (sec)->this_hdr.contents = contents;
1026d2201f2fSdrahn symtab_hdr->contents = (unsigned char *) isymbuf;
1027d2201f2fSdrahn
1028d2201f2fSdrahn /* Get the opcode. */
1029d2201f2fSdrahn code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
1030d2201f2fSdrahn
1031*cf2f2c56Smiod /* All instructions with R_H8_DIR16A8 start with
1032*cf2f2c56Smiod 0x6a. */
1033d2201f2fSdrahn if (code != 0x6a)
1034d2201f2fSdrahn abort ();
1035d2201f2fSdrahn
1036*cf2f2c56Smiod temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1037*cf2f2c56Smiod /* If this is a mov.b instruction, clear the lower
1038*cf2f2c56Smiod nibble, which contains the source/destination
1039*cf2f2c56Smiod register number. */
1040*cf2f2c56Smiod if ((temp_code & 0x10) != 0x10)
1041*cf2f2c56Smiod temp_code &= 0xf0;
1042d2201f2fSdrahn
1043*cf2f2c56Smiod switch (temp_code)
1044*cf2f2c56Smiod {
1045*cf2f2c56Smiod case 0x00:
1046*cf2f2c56Smiod /* This is mov.b @aa:16,Rd. */
1047*cf2f2c56Smiod bfd_put_8 (abfd, (code & 0xf) | 0x20,
1048d2201f2fSdrahn contents + irel->r_offset - 2);
1049*cf2f2c56Smiod break;
1050*cf2f2c56Smiod case 0x80:
1051*cf2f2c56Smiod /* This is mov.b Rs,@aa:16. */
1052*cf2f2c56Smiod bfd_put_8 (abfd, (code & 0xf) | 0x30,
1053d2201f2fSdrahn contents + irel->r_offset - 2);
1054*cf2f2c56Smiod break;
1055*cf2f2c56Smiod case 0x18:
1056*cf2f2c56Smiod /* This is a bit-maniputation instruction that
1057*cf2f2c56Smiod stores one bit into memory, one of "bclr",
1058*cf2f2c56Smiod "bist", "bnot", "bset", and "bst". */
1059*cf2f2c56Smiod bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
1060*cf2f2c56Smiod break;
1061*cf2f2c56Smiod case 0x10:
1062*cf2f2c56Smiod /* This is a bit-maniputation instruction that
1063*cf2f2c56Smiod loads one bit from memory, one of "band",
1064*cf2f2c56Smiod "biand", "bild", "bior", "bixor", "bld", "bor",
1065*cf2f2c56Smiod "btst", and "bxor". */
1066*cf2f2c56Smiod bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
1067*cf2f2c56Smiod break;
1068*cf2f2c56Smiod default:
1069d2201f2fSdrahn abort ();
1070*cf2f2c56Smiod }
1071d2201f2fSdrahn
1072d2201f2fSdrahn /* Fix the relocation's type. */
1073d2201f2fSdrahn irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1074d2201f2fSdrahn R_H8_DIR8);
1075d2201f2fSdrahn
1076*cf2f2c56Smiod /* Move the relocation. */
1077*cf2f2c56Smiod irel->r_offset--;
1078*cf2f2c56Smiod
1079d2201f2fSdrahn /* Delete two bytes of data. */
1080d2201f2fSdrahn if (!elf32_h8_relax_delete_bytes (abfd, sec,
1081d2201f2fSdrahn irel->r_offset + 1, 2))
1082d2201f2fSdrahn goto error_return;
1083d2201f2fSdrahn
1084d2201f2fSdrahn /* That will change things, so, we should relax again.
1085d2201f2fSdrahn Note that this is not required, and it may be slow. */
1086d2201f2fSdrahn *again = TRUE;
1087d2201f2fSdrahn }
1088d2201f2fSdrahn break;
1089d2201f2fSdrahn }
1090d2201f2fSdrahn
1091*cf2f2c56Smiod /* This is a 24-bit absolute address in one of the following
1092*cf2f2c56Smiod instructions:
1093*cf2f2c56Smiod
1094*cf2f2c56Smiod "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
1095*cf2f2c56Smiod "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
1096*cf2f2c56Smiod "mov.b"
1097*cf2f2c56Smiod
1098*cf2f2c56Smiod We may relax this into an 8-bit absolute address if it's in
1099*cf2f2c56Smiod the right range. */
1100d2201f2fSdrahn case R_H8_DIR24A8:
1101d2201f2fSdrahn {
1102*cf2f2c56Smiod bfd_vma value;
1103d2201f2fSdrahn
1104*cf2f2c56Smiod value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
1105*cf2f2c56Smiod if (value >= 0xffffff00u)
1106d2201f2fSdrahn {
1107d2201f2fSdrahn unsigned char code;
1108*cf2f2c56Smiod unsigned char temp_code;
1109d2201f2fSdrahn
1110d2201f2fSdrahn /* Note that we've changed the relocs, section contents,
1111d2201f2fSdrahn etc. */
1112d2201f2fSdrahn elf_section_data (sec)->relocs = internal_relocs;
1113d2201f2fSdrahn elf_section_data (sec)->this_hdr.contents = contents;
1114d2201f2fSdrahn symtab_hdr->contents = (unsigned char *) isymbuf;
1115d2201f2fSdrahn
1116d2201f2fSdrahn /* Get the opcode. */
1117d2201f2fSdrahn code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
1118d2201f2fSdrahn
1119*cf2f2c56Smiod /* All instructions with R_H8_DIR24A8 start with
1120*cf2f2c56Smiod 0x6a. */
1121d2201f2fSdrahn if (code != 0x6a)
1122d2201f2fSdrahn abort ();
1123d2201f2fSdrahn
1124*cf2f2c56Smiod temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1125d2201f2fSdrahn
1126*cf2f2c56Smiod /* If this is a mov.b instruction, clear the lower
1127*cf2f2c56Smiod nibble, which contains the source/destination
1128*cf2f2c56Smiod register number. */
1129*cf2f2c56Smiod if ((temp_code & 0x30) != 0x30)
1130*cf2f2c56Smiod temp_code &= 0xf0;
1131*cf2f2c56Smiod
1132*cf2f2c56Smiod switch (temp_code)
1133*cf2f2c56Smiod {
1134*cf2f2c56Smiod case 0x20:
1135*cf2f2c56Smiod /* This is mov.b @aa:24/32,Rd. */
1136*cf2f2c56Smiod bfd_put_8 (abfd, (code & 0xf) | 0x20,
1137d2201f2fSdrahn contents + irel->r_offset - 2);
1138*cf2f2c56Smiod break;
1139*cf2f2c56Smiod case 0xa0:
1140*cf2f2c56Smiod /* This is mov.b Rs,@aa:24/32. */
1141*cf2f2c56Smiod bfd_put_8 (abfd, (code & 0xf) | 0x30,
1142d2201f2fSdrahn contents + irel->r_offset - 2);
1143*cf2f2c56Smiod break;
1144*cf2f2c56Smiod case 0x38:
1145*cf2f2c56Smiod /* This is a bit-maniputation instruction that
1146*cf2f2c56Smiod stores one bit into memory, one of "bclr",
1147*cf2f2c56Smiod "bist", "bnot", "bset", and "bst". */
1148*cf2f2c56Smiod bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
1149*cf2f2c56Smiod break;
1150*cf2f2c56Smiod case 0x30:
1151*cf2f2c56Smiod /* This is a bit-maniputation instruction that
1152*cf2f2c56Smiod loads one bit from memory, one of "band",
1153*cf2f2c56Smiod "biand", "bild", "bior", "bixor", "bld", "bor",
1154*cf2f2c56Smiod "btst", and "bxor". */
1155*cf2f2c56Smiod bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
1156*cf2f2c56Smiod break;
1157*cf2f2c56Smiod default:
1158d2201f2fSdrahn abort();
1159*cf2f2c56Smiod }
1160d2201f2fSdrahn
1161d2201f2fSdrahn /* Fix the relocation's type. */
1162d2201f2fSdrahn irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1163d2201f2fSdrahn R_H8_DIR8);
1164*cf2f2c56Smiod irel->r_offset--;
1165d2201f2fSdrahn
1166d2201f2fSdrahn /* Delete two bytes of data. */
1167*cf2f2c56Smiod if (!elf32_h8_relax_delete_bytes (abfd, sec,
1168*cf2f2c56Smiod irel->r_offset + 1, 4))
1169d2201f2fSdrahn goto error_return;
1170d2201f2fSdrahn
1171d2201f2fSdrahn /* That will change things, so, we should relax again.
1172d2201f2fSdrahn Note that this is not required, and it may be slow. */
1173d2201f2fSdrahn *again = TRUE;
1174*cf2f2c56Smiod break;
1175d2201f2fSdrahn }
1176d2201f2fSdrahn }
1177d2201f2fSdrahn
1178*cf2f2c56Smiod /* Fall through. */
1179d2201f2fSdrahn
1180*cf2f2c56Smiod /* This is a 24-/32-bit absolute address in one of the
1181*cf2f2c56Smiod following instructions:
1182*cf2f2c56Smiod
1183*cf2f2c56Smiod "band", "bclr", "biand", "bild", "bior", "bist",
1184*cf2f2c56Smiod "bixor", "bld", "bnot", "bor", "bset", "bst", "btst",
1185*cf2f2c56Smiod "bxor", "ldc.w", "stc.w" and "mov.[bwl]"
1186*cf2f2c56Smiod
1187*cf2f2c56Smiod We may relax this into an 16-bit absolute address if it's
1188*cf2f2c56Smiod in the right range. */
1189d2201f2fSdrahn case R_H8_DIR32A16:
1190d2201f2fSdrahn {
1191*cf2f2c56Smiod bfd_vma value;
1192d2201f2fSdrahn
1193*cf2f2c56Smiod value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
1194*cf2f2c56Smiod if (value <= 0x7fff || value >= 0xffff8000u)
1195d2201f2fSdrahn {
1196d2201f2fSdrahn unsigned char code;
1197d2201f2fSdrahn
1198d2201f2fSdrahn /* Note that we've changed the relocs, section contents,
1199d2201f2fSdrahn etc. */
1200d2201f2fSdrahn elf_section_data (sec)->relocs = internal_relocs;
1201d2201f2fSdrahn elf_section_data (sec)->this_hdr.contents = contents;
1202d2201f2fSdrahn symtab_hdr->contents = (unsigned char *) isymbuf;
1203d2201f2fSdrahn
1204d2201f2fSdrahn /* Get the opcode. */
1205d2201f2fSdrahn code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1206d2201f2fSdrahn
1207*cf2f2c56Smiod /* Fix the opcode. For all the instructions that
1208*cf2f2c56Smiod belong to this relaxation, we simply need to turn
1209*cf2f2c56Smiod off bit 0x20 in the previous byte. */
1210d2201f2fSdrahn code &= ~0x20;
1211d2201f2fSdrahn
1212d2201f2fSdrahn bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
1213d2201f2fSdrahn
1214d2201f2fSdrahn /* Fix the relocation's type. */
1215d2201f2fSdrahn irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1216*cf2f2c56Smiod R_H8_DIR16);
1217d2201f2fSdrahn
1218d2201f2fSdrahn /* Delete two bytes of data. */
1219d2201f2fSdrahn if (!elf32_h8_relax_delete_bytes (abfd, sec,
1220d2201f2fSdrahn irel->r_offset + 1, 2))
1221d2201f2fSdrahn goto error_return;
1222d2201f2fSdrahn
1223d2201f2fSdrahn /* That will change things, so, we should relax again.
1224d2201f2fSdrahn Note that this is not required, and it may be slow. */
1225d2201f2fSdrahn *again = TRUE;
1226d2201f2fSdrahn }
1227d2201f2fSdrahn break;
1228d2201f2fSdrahn }
1229d2201f2fSdrahn
1230d2201f2fSdrahn default:
1231d2201f2fSdrahn break;
1232d2201f2fSdrahn }
1233d2201f2fSdrahn }
1234d2201f2fSdrahn
1235d2201f2fSdrahn if (isymbuf != NULL
1236d2201f2fSdrahn && symtab_hdr->contents != (unsigned char *) isymbuf)
1237d2201f2fSdrahn {
1238d2201f2fSdrahn if (! link_info->keep_memory)
1239d2201f2fSdrahn free (isymbuf);
1240d2201f2fSdrahn else
1241d2201f2fSdrahn symtab_hdr->contents = (unsigned char *) isymbuf;
1242d2201f2fSdrahn }
1243d2201f2fSdrahn
1244d2201f2fSdrahn if (contents != NULL
1245d2201f2fSdrahn && elf_section_data (sec)->this_hdr.contents != contents)
1246d2201f2fSdrahn {
1247d2201f2fSdrahn if (! link_info->keep_memory)
1248d2201f2fSdrahn free (contents);
1249d2201f2fSdrahn else
1250d2201f2fSdrahn {
1251d2201f2fSdrahn /* Cache the section contents for elf_link_input_bfd. */
1252d2201f2fSdrahn elf_section_data (sec)->this_hdr.contents = contents;
1253d2201f2fSdrahn }
1254d2201f2fSdrahn }
1255d2201f2fSdrahn
1256d2201f2fSdrahn if (internal_relocs != NULL
1257d2201f2fSdrahn && elf_section_data (sec)->relocs != internal_relocs)
1258d2201f2fSdrahn free (internal_relocs);
1259d2201f2fSdrahn
1260d2201f2fSdrahn return TRUE;
1261d2201f2fSdrahn
1262d2201f2fSdrahn error_return:
1263d2201f2fSdrahn if (isymbuf != NULL
1264d2201f2fSdrahn && symtab_hdr->contents != (unsigned char *) isymbuf)
1265d2201f2fSdrahn free (isymbuf);
1266d2201f2fSdrahn if (contents != NULL
1267d2201f2fSdrahn && elf_section_data (sec)->this_hdr.contents != contents)
1268d2201f2fSdrahn free (contents);
1269d2201f2fSdrahn if (internal_relocs != NULL
1270d2201f2fSdrahn && elf_section_data (sec)->relocs != internal_relocs)
1271d2201f2fSdrahn free (internal_relocs);
1272d2201f2fSdrahn return FALSE;
1273d2201f2fSdrahn }
1274d2201f2fSdrahn
1275d2201f2fSdrahn /* Delete some bytes from a section while relaxing. */
1276d2201f2fSdrahn
1277d2201f2fSdrahn static bfd_boolean
elf32_h8_relax_delete_bytes(bfd * abfd,asection * sec,bfd_vma addr,int count)1278*cf2f2c56Smiod elf32_h8_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count)
1279d2201f2fSdrahn {
1280d2201f2fSdrahn Elf_Internal_Shdr *symtab_hdr;
1281d2201f2fSdrahn unsigned int sec_shndx;
1282d2201f2fSdrahn bfd_byte *contents;
1283d2201f2fSdrahn Elf_Internal_Rela *irel, *irelend;
1284d2201f2fSdrahn Elf_Internal_Rela *irelalign;
1285d2201f2fSdrahn Elf_Internal_Sym *isym;
1286d2201f2fSdrahn Elf_Internal_Sym *isymend;
1287d2201f2fSdrahn bfd_vma toaddr;
1288d2201f2fSdrahn struct elf_link_hash_entry **sym_hashes;
1289d2201f2fSdrahn struct elf_link_hash_entry **end_hashes;
1290d2201f2fSdrahn unsigned int symcount;
1291d2201f2fSdrahn
1292d2201f2fSdrahn sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1293d2201f2fSdrahn
1294d2201f2fSdrahn contents = elf_section_data (sec)->this_hdr.contents;
1295d2201f2fSdrahn
1296d2201f2fSdrahn /* The deletion must stop at the next ALIGN reloc for an aligment
1297d2201f2fSdrahn power larger than the number of bytes we are deleting. */
1298d2201f2fSdrahn
1299d2201f2fSdrahn irelalign = NULL;
1300d2201f2fSdrahn toaddr = sec->_cooked_size;
1301d2201f2fSdrahn
1302d2201f2fSdrahn irel = elf_section_data (sec)->relocs;
1303d2201f2fSdrahn irelend = irel + sec->reloc_count;
1304d2201f2fSdrahn
1305d2201f2fSdrahn /* Actually delete the bytes. */
1306d2201f2fSdrahn memmove (contents + addr, contents + addr + count,
1307d2201f2fSdrahn (size_t) (toaddr - addr - count));
1308d2201f2fSdrahn sec->_cooked_size -= count;
1309d2201f2fSdrahn
1310d2201f2fSdrahn /* Adjust all the relocs. */
1311d2201f2fSdrahn for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1312d2201f2fSdrahn {
1313d2201f2fSdrahn /* Get the new reloc address. */
1314d2201f2fSdrahn if ((irel->r_offset > addr
1315d2201f2fSdrahn && irel->r_offset < toaddr))
1316d2201f2fSdrahn irel->r_offset -= count;
1317d2201f2fSdrahn }
1318d2201f2fSdrahn
1319d2201f2fSdrahn /* Adjust the local symbols defined in this section. */
1320d2201f2fSdrahn symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1321d2201f2fSdrahn isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1322d2201f2fSdrahn isymend = isym + symtab_hdr->sh_info;
1323d2201f2fSdrahn for (; isym < isymend; isym++)
1324d2201f2fSdrahn {
1325d2201f2fSdrahn if (isym->st_shndx == sec_shndx
1326d2201f2fSdrahn && isym->st_value > addr
1327d2201f2fSdrahn && isym->st_value < toaddr)
1328d2201f2fSdrahn isym->st_value -= count;
1329d2201f2fSdrahn }
1330d2201f2fSdrahn
1331d2201f2fSdrahn /* Now adjust the global symbols defined in this section. */
1332d2201f2fSdrahn symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1333d2201f2fSdrahn - symtab_hdr->sh_info);
1334d2201f2fSdrahn sym_hashes = elf_sym_hashes (abfd);
1335d2201f2fSdrahn end_hashes = sym_hashes + symcount;
1336d2201f2fSdrahn for (; sym_hashes < end_hashes; sym_hashes++)
1337d2201f2fSdrahn {
1338d2201f2fSdrahn struct elf_link_hash_entry *sym_hash = *sym_hashes;
1339d2201f2fSdrahn if ((sym_hash->root.type == bfd_link_hash_defined
1340d2201f2fSdrahn || sym_hash->root.type == bfd_link_hash_defweak)
1341d2201f2fSdrahn && sym_hash->root.u.def.section == sec
1342d2201f2fSdrahn && sym_hash->root.u.def.value > addr
1343d2201f2fSdrahn && sym_hash->root.u.def.value < toaddr)
1344d2201f2fSdrahn {
1345d2201f2fSdrahn sym_hash->root.u.def.value -= count;
1346d2201f2fSdrahn }
1347d2201f2fSdrahn }
1348d2201f2fSdrahn
1349d2201f2fSdrahn return TRUE;
1350d2201f2fSdrahn }
1351d2201f2fSdrahn
1352d2201f2fSdrahn /* Return TRUE if a symbol exists at the given address, else return
1353d2201f2fSdrahn FALSE. */
1354d2201f2fSdrahn static bfd_boolean
elf32_h8_symbol_address_p(bfd * abfd,asection * sec,bfd_vma addr)1355*cf2f2c56Smiod elf32_h8_symbol_address_p (bfd *abfd, asection *sec, bfd_vma addr)
1356d2201f2fSdrahn {
1357d2201f2fSdrahn Elf_Internal_Shdr *symtab_hdr;
1358d2201f2fSdrahn unsigned int sec_shndx;
1359d2201f2fSdrahn Elf_Internal_Sym *isym;
1360d2201f2fSdrahn Elf_Internal_Sym *isymend;
1361d2201f2fSdrahn struct elf_link_hash_entry **sym_hashes;
1362d2201f2fSdrahn struct elf_link_hash_entry **end_hashes;
1363d2201f2fSdrahn unsigned int symcount;
1364d2201f2fSdrahn
1365d2201f2fSdrahn sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1366d2201f2fSdrahn
1367d2201f2fSdrahn /* Examine all the symbols. */
1368d2201f2fSdrahn symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1369d2201f2fSdrahn isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1370d2201f2fSdrahn isymend = isym + symtab_hdr->sh_info;
1371d2201f2fSdrahn for (; isym < isymend; isym++)
1372d2201f2fSdrahn {
1373d2201f2fSdrahn if (isym->st_shndx == sec_shndx
1374d2201f2fSdrahn && isym->st_value == addr)
1375d2201f2fSdrahn return TRUE;
1376d2201f2fSdrahn }
1377d2201f2fSdrahn
1378d2201f2fSdrahn symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1379d2201f2fSdrahn - symtab_hdr->sh_info);
1380d2201f2fSdrahn sym_hashes = elf_sym_hashes (abfd);
1381d2201f2fSdrahn end_hashes = sym_hashes + symcount;
1382d2201f2fSdrahn for (; sym_hashes < end_hashes; sym_hashes++)
1383d2201f2fSdrahn {
1384d2201f2fSdrahn struct elf_link_hash_entry *sym_hash = *sym_hashes;
1385d2201f2fSdrahn if ((sym_hash->root.type == bfd_link_hash_defined
1386d2201f2fSdrahn || sym_hash->root.type == bfd_link_hash_defweak)
1387d2201f2fSdrahn && sym_hash->root.u.def.section == sec
1388d2201f2fSdrahn && sym_hash->root.u.def.value == addr)
1389d2201f2fSdrahn return TRUE;
1390d2201f2fSdrahn }
1391d2201f2fSdrahn
1392d2201f2fSdrahn return FALSE;
1393d2201f2fSdrahn }
1394d2201f2fSdrahn
1395d2201f2fSdrahn /* This is a version of bfd_generic_get_relocated_section_contents
1396d2201f2fSdrahn which uses elf32_h8_relocate_section. */
1397d2201f2fSdrahn
1398d2201f2fSdrahn static bfd_byte *
elf32_h8_get_relocated_section_contents(bfd * output_bfd,struct bfd_link_info * link_info,struct bfd_link_order * link_order,bfd_byte * data,bfd_boolean relocatable,asymbol ** symbols)1399*cf2f2c56Smiod elf32_h8_get_relocated_section_contents (bfd *output_bfd,
1400*cf2f2c56Smiod struct bfd_link_info *link_info,
1401*cf2f2c56Smiod struct bfd_link_order *link_order,
1402*cf2f2c56Smiod bfd_byte *data,
1403*cf2f2c56Smiod bfd_boolean relocatable,
1404*cf2f2c56Smiod asymbol **symbols)
1405d2201f2fSdrahn {
1406d2201f2fSdrahn Elf_Internal_Shdr *symtab_hdr;
1407d2201f2fSdrahn asection *input_section = link_order->u.indirect.section;
1408d2201f2fSdrahn bfd *input_bfd = input_section->owner;
1409d2201f2fSdrahn asection **sections = NULL;
1410d2201f2fSdrahn Elf_Internal_Rela *internal_relocs = NULL;
1411d2201f2fSdrahn Elf_Internal_Sym *isymbuf = NULL;
1412d2201f2fSdrahn
1413d2201f2fSdrahn /* We only need to handle the case of relaxing, or of having a
1414d2201f2fSdrahn particular set of section contents, specially. */
1415*cf2f2c56Smiod if (relocatable
1416d2201f2fSdrahn || elf_section_data (input_section)->this_hdr.contents == NULL)
1417d2201f2fSdrahn return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1418d2201f2fSdrahn link_order, data,
1419*cf2f2c56Smiod relocatable,
1420d2201f2fSdrahn symbols);
1421d2201f2fSdrahn
1422d2201f2fSdrahn symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1423d2201f2fSdrahn
1424d2201f2fSdrahn memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1425d2201f2fSdrahn (size_t) input_section->_raw_size);
1426d2201f2fSdrahn
1427d2201f2fSdrahn if ((input_section->flags & SEC_RELOC) != 0
1428d2201f2fSdrahn && input_section->reloc_count > 0)
1429d2201f2fSdrahn {
1430d2201f2fSdrahn asection **secpp;
1431d2201f2fSdrahn Elf_Internal_Sym *isym, *isymend;
1432d2201f2fSdrahn bfd_size_type amt;
1433d2201f2fSdrahn
1434*cf2f2c56Smiod internal_relocs = (_bfd_elf_link_read_relocs
1435d2201f2fSdrahn (input_bfd, input_section, (PTR) NULL,
1436d2201f2fSdrahn (Elf_Internal_Rela *) NULL, FALSE));
1437d2201f2fSdrahn if (internal_relocs == NULL)
1438d2201f2fSdrahn goto error_return;
1439d2201f2fSdrahn
1440d2201f2fSdrahn if (symtab_hdr->sh_info != 0)
1441d2201f2fSdrahn {
1442d2201f2fSdrahn isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1443d2201f2fSdrahn if (isymbuf == NULL)
1444d2201f2fSdrahn isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1445d2201f2fSdrahn symtab_hdr->sh_info, 0,
1446d2201f2fSdrahn NULL, NULL, NULL);
1447d2201f2fSdrahn if (isymbuf == NULL)
1448d2201f2fSdrahn goto error_return;
1449d2201f2fSdrahn }
1450d2201f2fSdrahn
1451d2201f2fSdrahn amt = symtab_hdr->sh_info;
1452d2201f2fSdrahn amt *= sizeof (asection *);
1453d2201f2fSdrahn sections = (asection **) bfd_malloc (amt);
1454d2201f2fSdrahn if (sections == NULL && amt != 0)
1455d2201f2fSdrahn goto error_return;
1456d2201f2fSdrahn
1457d2201f2fSdrahn isymend = isymbuf + symtab_hdr->sh_info;
1458d2201f2fSdrahn for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
1459d2201f2fSdrahn {
1460d2201f2fSdrahn asection *isec;
1461d2201f2fSdrahn
1462d2201f2fSdrahn if (isym->st_shndx == SHN_UNDEF)
1463d2201f2fSdrahn isec = bfd_und_section_ptr;
1464d2201f2fSdrahn else if (isym->st_shndx == SHN_ABS)
1465d2201f2fSdrahn isec = bfd_abs_section_ptr;
1466d2201f2fSdrahn else if (isym->st_shndx == SHN_COMMON)
1467d2201f2fSdrahn isec = bfd_com_section_ptr;
1468d2201f2fSdrahn else
1469d2201f2fSdrahn isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
1470d2201f2fSdrahn
1471d2201f2fSdrahn *secpp = isec;
1472d2201f2fSdrahn }
1473d2201f2fSdrahn
1474d2201f2fSdrahn if (! elf32_h8_relocate_section (output_bfd, link_info, input_bfd,
1475d2201f2fSdrahn input_section, data, internal_relocs,
1476d2201f2fSdrahn isymbuf, sections))
1477d2201f2fSdrahn goto error_return;
1478d2201f2fSdrahn
1479d2201f2fSdrahn if (sections != NULL)
1480d2201f2fSdrahn free (sections);
1481d2201f2fSdrahn if (isymbuf != NULL
1482d2201f2fSdrahn && symtab_hdr->contents != (unsigned char *) isymbuf)
1483d2201f2fSdrahn free (isymbuf);
1484d2201f2fSdrahn if (elf_section_data (input_section)->relocs != internal_relocs)
1485d2201f2fSdrahn free (internal_relocs);
1486d2201f2fSdrahn }
1487d2201f2fSdrahn
1488d2201f2fSdrahn return data;
1489d2201f2fSdrahn
1490d2201f2fSdrahn error_return:
1491d2201f2fSdrahn if (sections != NULL)
1492d2201f2fSdrahn free (sections);
1493d2201f2fSdrahn if (isymbuf != NULL
1494d2201f2fSdrahn && symtab_hdr->contents != (unsigned char *) isymbuf)
1495d2201f2fSdrahn free (isymbuf);
1496d2201f2fSdrahn if (internal_relocs != NULL
1497d2201f2fSdrahn && elf_section_data (input_section)->relocs != internal_relocs)
1498d2201f2fSdrahn free (internal_relocs);
1499d2201f2fSdrahn return NULL;
1500d2201f2fSdrahn }
1501d2201f2fSdrahn
1502*cf2f2c56Smiod static asection *
elf32_h8_gc_mark_hook(asection * sec,struct bfd_link_info * info ATTRIBUTE_UNUSED,Elf_Internal_Rela * rel ATTRIBUTE_UNUSED,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)1503*cf2f2c56Smiod elf32_h8_gc_mark_hook (asection *sec,
1504*cf2f2c56Smiod struct bfd_link_info *info ATTRIBUTE_UNUSED,
1505*cf2f2c56Smiod Elf_Internal_Rela *rel ATTRIBUTE_UNUSED,
1506*cf2f2c56Smiod struct elf_link_hash_entry *h,
1507*cf2f2c56Smiod Elf_Internal_Sym *sym)
1508*cf2f2c56Smiod {
1509*cf2f2c56Smiod if (h != NULL)
1510*cf2f2c56Smiod {
1511*cf2f2c56Smiod switch (h->root.type)
1512*cf2f2c56Smiod {
1513*cf2f2c56Smiod case bfd_link_hash_defined:
1514*cf2f2c56Smiod case bfd_link_hash_defweak:
1515*cf2f2c56Smiod return h->root.u.def.section;
1516*cf2f2c56Smiod
1517*cf2f2c56Smiod case bfd_link_hash_common:
1518*cf2f2c56Smiod return h->root.u.c.p->section;
1519*cf2f2c56Smiod
1520*cf2f2c56Smiod default:
1521*cf2f2c56Smiod break;
1522*cf2f2c56Smiod }
1523*cf2f2c56Smiod }
1524*cf2f2c56Smiod else
1525*cf2f2c56Smiod return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
1526*cf2f2c56Smiod return NULL;
1527*cf2f2c56Smiod }
1528*cf2f2c56Smiod
1529*cf2f2c56Smiod static bfd_boolean
elf32_h8_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)1530*cf2f2c56Smiod elf32_h8_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
1531*cf2f2c56Smiod struct bfd_link_info *info ATTRIBUTE_UNUSED,
1532*cf2f2c56Smiod asection *sec ATTRIBUTE_UNUSED,
1533*cf2f2c56Smiod const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
1534*cf2f2c56Smiod {
1535*cf2f2c56Smiod return TRUE;
1536*cf2f2c56Smiod }
1537*cf2f2c56Smiod
1538d2201f2fSdrahn
1539d2201f2fSdrahn #define TARGET_BIG_SYM bfd_elf32_h8300_vec
1540d2201f2fSdrahn #define TARGET_BIG_NAME "elf32-h8300"
1541d2201f2fSdrahn #define ELF_ARCH bfd_arch_h8300
1542d2201f2fSdrahn #define ELF_MACHINE_CODE EM_H8_300
1543d2201f2fSdrahn #define ELF_MAXPAGESIZE 0x1
1544d2201f2fSdrahn #define bfd_elf32_bfd_reloc_type_lookup elf32_h8_reloc_type_lookup
1545d2201f2fSdrahn #define elf_info_to_howto elf32_h8_info_to_howto
1546d2201f2fSdrahn #define elf_info_to_howto_rel elf32_h8_info_to_howto_rel
1547d2201f2fSdrahn
1548d2201f2fSdrahn /* So we can set/examine bits in e_flags to get the specific
1549d2201f2fSdrahn H8 architecture in use. */
1550d2201f2fSdrahn #define elf_backend_final_write_processing \
1551d2201f2fSdrahn elf32_h8_final_write_processing
1552d2201f2fSdrahn #define elf_backend_object_p \
1553d2201f2fSdrahn elf32_h8_object_p
1554d2201f2fSdrahn #define bfd_elf32_bfd_merge_private_bfd_data \
1555d2201f2fSdrahn elf32_h8_merge_private_bfd_data
1556*cf2f2c56Smiod #define elf_backend_gc_mark_hook elf32_h8_gc_mark_hook
1557*cf2f2c56Smiod #define elf_backend_gc_sweep_hook elf32_h8_gc_sweep_hook
1558d2201f2fSdrahn
1559d2201f2fSdrahn /* ??? when elf_backend_relocate_section is not defined, elf32-target.h
1560d2201f2fSdrahn defaults to using _bfd_generic_link_hash_table_create, but
1561*cf2f2c56Smiod bfd_elf_size_dynamic_sections uses
1562d2201f2fSdrahn dynobj = elf_hash_table (info)->dynobj;
1563d2201f2fSdrahn and thus requires an elf hash table. */
1564d2201f2fSdrahn #define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
1565d2201f2fSdrahn
1566d2201f2fSdrahn /* Use an H8 specific linker, not the ELF generic linker. */
1567d2201f2fSdrahn #define elf_backend_relocate_section elf32_h8_relocate_section
1568d2201f2fSdrahn #define elf_backend_rela_normal 1
1569*cf2f2c56Smiod #define elf_backend_can_gc_sections 1
1570d2201f2fSdrahn
1571d2201f2fSdrahn /* And relaxing stuff. */
1572d2201f2fSdrahn #define bfd_elf32_bfd_relax_section elf32_h8_relax_section
1573d2201f2fSdrahn #define bfd_elf32_bfd_get_relocated_section_contents \
1574d2201f2fSdrahn elf32_h8_get_relocated_section_contents
1575d2201f2fSdrahn
1576d2201f2fSdrahn
1577d2201f2fSdrahn #include "elf32-target.h"
1578