* aix386-core.c: Remove use of PTR and PARAMS macros.
[deliverable/binutils-gdb.git] / bfd / coff-h8500.c
CommitLineData
c2dcd04e 1/* BFD back-end for Renesas H8/500 COFF binaries.
3db64b00 2 Copyright 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
2c3fc389 3 2005, 2007, 2008, 2012 Free Software Foundation, Inc.
252b5132
RH
4 Contributed by Cygnus Support.
5 Written by Steve Chamberlain, <sac@cygnus.com>.
6
c2dcd04e 7 This file is part of BFD, the Binary File Descriptor library.
252b5132 8
c2dcd04e
NC
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
cd123cb7 11 the Free Software Foundation; either version 3 of the License, or
c2dcd04e 12 (at your option) any later version.
252b5132 13
c2dcd04e
NC
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
252b5132 18
c2dcd04e
NC
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
cd123cb7
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
252b5132 23
252b5132 24#include "sysdep.h"
3db64b00 25#include "bfd.h"
252b5132
RH
26#include "libbfd.h"
27#include "bfdlink.h"
28#include "coff/h8500.h"
29#include "coff/internal.h"
30#include "libcoff.h"
31
f4ffd778 32
252b5132
RH
33#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
34
35static reloc_howto_type r_imm8 =
b34976b6
AM
36HOWTO (R_H8500_IMM8, 0, 1, 8, FALSE, 0,
37 complain_overflow_bitfield, 0, "r_imm8", TRUE, 0x000000ff, 0x000000ff, FALSE);
252b5132
RH
38
39static reloc_howto_type r_imm16 =
b34976b6
AM
40HOWTO (R_H8500_IMM16, 0, 1, 16, FALSE, 0,
41 complain_overflow_bitfield, 0, "r_imm16", TRUE, 0x0000ffff, 0x0000ffff, FALSE);
252b5132
RH
42
43static reloc_howto_type r_imm24 =
b34976b6
AM
44HOWTO (R_H8500_IMM24, 0, 1, 24, FALSE, 0,
45 complain_overflow_bitfield, 0, "r_imm24", TRUE, 0x00ffffff, 0x00ffffff, FALSE);
252b5132
RH
46
47static reloc_howto_type r_imm32 =
b34976b6
AM
48HOWTO (R_H8500_IMM32, 0, 1, 32, FALSE, 0,
49 complain_overflow_bitfield, 0, "r_imm32", TRUE, 0xffffffff, 0xffffffff, FALSE);
252b5132 50
252b5132 51static reloc_howto_type r_high8 =
b34976b6
AM
52HOWTO (R_H8500_HIGH8, 0, 1, 8, FALSE, 0,
53 complain_overflow_dont, 0, "r_high8", TRUE, 0x000000ff, 0x000000ff, FALSE);
252b5132
RH
54
55static reloc_howto_type r_low16 =
b34976b6
AM
56HOWTO (R_H8500_LOW16, 0, 1, 16, FALSE, 0,
57 complain_overflow_dont, 0, "r_low16", TRUE, 0x0000ffff, 0x0000ffff, FALSE);
252b5132
RH
58
59static reloc_howto_type r_pcrel8 =
b34976b6 60HOWTO (R_H8500_PCREL8, 0, 1, 8, TRUE, 0, complain_overflow_signed, 0, "r_pcrel8", TRUE, 0, 0, TRUE);
252b5132 61
252b5132 62static reloc_howto_type r_pcrel16 =
b34976b6 63HOWTO (R_H8500_PCREL16, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0, "r_pcrel16", TRUE, 0, 0, TRUE);
252b5132
RH
64
65static reloc_howto_type r_high16 =
b34976b6
AM
66HOWTO (R_H8500_HIGH16, 0, 1, 8, FALSE, 0,
67 complain_overflow_dont, 0, "r_high16", TRUE, 0x000ffff, 0x0000ffff, FALSE);
f4ffd778
NC
68\f
69/* Turn a howto into a reloc number. */
252b5132 70
5fcfd273 71static int
2c3fc389 72coff_h8500_select_reloc (reloc_howto_type *howto)
252b5132
RH
73{
74 return howto->type;
75}
76
77#define SELECT_RELOC(x,howto) x.r_type = coff_h8500_select_reloc(howto)
78
252b5132
RH
79#define BADMAG(x) H8500BADMAG(x)
80#define H8500 1 /* Customize coffcode.h */
81
82#define __A_MAGIC_SET__
83
f4ffd778 84/* Code to swap in the reloc. */
dc810e39
AM
85#define SWAP_IN_RELOC_OFFSET H_GET_32
86#define SWAP_OUT_RELOC_OFFSET H_PUT_32
252b5132
RH
87#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
88 dst->r_stuff[0] = 'S'; \
89 dst->r_stuff[1] = 'C';
90
f4ffd778 91/* Code to turn a r_type into a howto ptr, uses the above howto table. */
252b5132
RH
92
93static void
2c3fc389 94rtype2howto (arelent * internal, struct internal_reloc *dst)
252b5132
RH
95{
96 switch (dst->r_type)
97 {
98 default:
99 abort ();
100 break;
101 case R_H8500_IMM8:
102 internal->howto = &r_imm8;
103 break;
104 case R_H8500_IMM16:
105 internal->howto = &r_imm16;
106 break;
107 case R_H8500_IMM24:
108 internal->howto = &r_imm24;
109 break;
110 case R_H8500_IMM32:
111 internal->howto = &r_imm32;
112 break;
113 case R_H8500_PCREL8:
114 internal->howto = &r_pcrel8;
115 break;
116 case R_H8500_PCREL16:
117 internal->howto = &r_pcrel16;
118 break;
119 case R_H8500_HIGH8:
120 internal->howto = &r_high8;
121 break;
122 case R_H8500_HIGH16:
123 internal->howto = &r_high16;
124 break;
125 case R_H8500_LOW16:
126 internal->howto = &r_low16;
127 break;
128 }
129}
130
131#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
132
f4ffd778 133/* Perform any necessary magic to the addend in a reloc entry. */
252b5132 134
252b5132
RH
135#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
136 cache_ptr->addend = ext_reloc.r_offset;
137
252b5132
RH
138#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
139 reloc_processing(relent, reloc, symbols, abfd, section)
140
2c3fc389
NC
141static void
142reloc_processing (arelent * relent,
143 struct internal_reloc *reloc,
144 asymbol ** symbols,
145 bfd * abfd,
146 asection * section)
252b5132
RH
147{
148 relent->address = reloc->r_vaddr;
149 rtype2howto (relent, reloc);
150
151 if (reloc->r_symndx > 0)
f4ffd778 152 relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
252b5132 153 else
f4ffd778 154 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
252b5132 155
252b5132
RH
156 relent->addend = reloc->r_offset;
157 relent->address -= section->vma;
158}
159
160static void
2c3fc389
NC
161extra_case (bfd *in_abfd,
162 struct bfd_link_info *link_info,
163 struct bfd_link_order *link_order,
164 arelent *reloc,
165 bfd_byte *data,
166 unsigned int *src_ptr,
167 unsigned int *dst_ptr)
252b5132
RH
168{
169 bfd_byte *d = data+*dst_ptr;
170 asection *input_section = link_order->u.indirect.section;
f4ffd778 171
252b5132
RH
172 switch (reloc->howto->type)
173 {
174 case R_H8500_IMM8:
175 bfd_put_8 (in_abfd,
176 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
177 d);
178 (*dst_ptr) += 1;
179 (*src_ptr) += 1;
180 break;
181
182 case R_H8500_HIGH8:
183 bfd_put_8 (in_abfd,
184 (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
185 >> 16),
f4ffd778 186 d);
252b5132
RH
187 (*dst_ptr) += 1;
188 (*src_ptr) += 1;
189 break;
190
191 case R_H8500_IMM16:
192 bfd_put_16 (in_abfd,
193 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
f4ffd778 194 d);
252b5132
RH
195 (*dst_ptr) += 2;
196 (*src_ptr) += 2;
197 break;
198
199 case R_H8500_LOW16:
200 bfd_put_16 (in_abfd,
201 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
202 d);
203
204 (*dst_ptr) += 2;
205 (*src_ptr) += 2;
206 break;
5fcfd273 207
252b5132
RH
208 case R_H8500_HIGH16:
209 bfd_put_16 (in_abfd,
210 (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
f4ffd778 211 >> 16),
252b5132
RH
212 d);
213
214 (*dst_ptr) += 2;
215 (*src_ptr) += 2;
216 break;
217
218 case R_H8500_IMM24:
219 {
f4ffd778 220 int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
6e301b2b 221 int o = bfd_get_32 (in_abfd, data+ *dst_ptr -1);
252b5132 222 v = (v & 0x00ffffff) | (o & 0xff00000);
dc810e39 223 bfd_put_32 (in_abfd, (bfd_vma) v, data + *dst_ptr -1);
f4ffd778
NC
224 (*dst_ptr) += 3;
225 (*src_ptr) += 3;;
252b5132
RH
226 }
227 break;
228 case R_H8500_IMM32:
229 {
f4ffd778 230 int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
dc810e39 231 bfd_put_32 (in_abfd, (bfd_vma) v, data + *dst_ptr);
f4ffd778
NC
232 (*dst_ptr) += 4;
233 (*src_ptr) += 4;;
252b5132
RH
234 }
235 break;
236
252b5132
RH
237 case R_H8500_PCREL8:
238 {
239 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
240 input_section);
44da2da1
AM
241 bfd_vma dot = (*dst_ptr
242 + input_section->output_offset
243 + input_section->output_section->vma);
252b5132 244 int gap = dst - dot - 1; /* -1 since were in the odd byte of the
f4ffd778 245 word and the pc's been incremented. */
252b5132
RH
246
247 if (gap > 128 || gap < -128)
248 {
249 if (! ((*link_info->callbacks->reloc_overflow)
dfeffb9f
L
250 (link_info, NULL,
251 bfd_asymbol_name (*reloc->sym_ptr_ptr),
252b5132
RH
252 reloc->howto->name, reloc->addend, input_section->owner,
253 input_section, reloc->address)))
254 abort ();
255 }
256 bfd_put_8 (in_abfd, gap, data + *dst_ptr);
257 (*dst_ptr)++;
258 (*src_ptr)++;
259 break;
260 }
261 case R_H8500_PCREL16:
262 {
263 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
264 input_section);
44da2da1
AM
265 bfd_vma dot = (*dst_ptr
266 + input_section->output_offset
267 + input_section->output_section->vma);
252b5132 268 int gap = dst - dot - 1; /* -1 since were in the odd byte of the
f4ffd778 269 word and the pc's been incremented. */
252b5132
RH
270
271 if (gap > 32767 || gap < -32768)
272 {
273 if (! ((*link_info->callbacks->reloc_overflow)
dfeffb9f
L
274 (link_info, NULL,
275 bfd_asymbol_name (*reloc->sym_ptr_ptr),
252b5132
RH
276 reloc->howto->name, reloc->addend, input_section->owner,
277 input_section, reloc->address)))
278 abort ();
279 }
dc810e39 280 bfd_put_16 (in_abfd, (bfd_vma) gap, data + *dst_ptr);
f4ffd778
NC
281 (*dst_ptr) += 2;
282 (*src_ptr) += 2;
252b5132
RH
283 break;
284 }
285
286 default:
287 abort ();
288 }
289}
290
291#define coff_reloc16_extra_cases extra_case
292
2b5c217d
NC
293#ifndef bfd_pe_print_pdata
294#define bfd_pe_print_pdata NULL
295#endif
296
252b5132
RH
297#include "coffcode.h"
298
252b5132
RH
299#undef coff_bfd_get_relocated_section_contents
300#undef coff_bfd_relax_section
301#define coff_bfd_get_relocated_section_contents \
302 bfd_coff_reloc16_get_relocated_section_contents
303#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
304
3fa78519 305CREATE_BIG_COFF_TARGET_VEC (h8500coff_vec, "coff-h8500", 0, 0, '_', NULL, COFF_SWAP_TABLE)
This page took 0.579359 seconds and 4 git commands to generate.