sync toplevel with gcc
[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,
2b5c217d 3 2005, 2007, 2008 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
NC
32static int coff_h8500_select_reloc PARAMS ((reloc_howto_type *));
33static void rtype2howto PARAMS ((arelent *, struct internal_reloc *));
34static void reloc_processing PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *));
35static void extra_case PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *, bfd_byte *, unsigned int *, unsigned int *));
36
252b5132
RH
37#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
38
39static reloc_howto_type r_imm8 =
b34976b6
AM
40HOWTO (R_H8500_IMM8, 0, 1, 8, FALSE, 0,
41 complain_overflow_bitfield, 0, "r_imm8", TRUE, 0x000000ff, 0x000000ff, FALSE);
252b5132
RH
42
43static reloc_howto_type r_imm16 =
b34976b6
AM
44HOWTO (R_H8500_IMM16, 0, 1, 16, FALSE, 0,
45 complain_overflow_bitfield, 0, "r_imm16", TRUE, 0x0000ffff, 0x0000ffff, FALSE);
252b5132
RH
46
47static reloc_howto_type r_imm24 =
b34976b6
AM
48HOWTO (R_H8500_IMM24, 0, 1, 24, FALSE, 0,
49 complain_overflow_bitfield, 0, "r_imm24", TRUE, 0x00ffffff, 0x00ffffff, FALSE);
252b5132
RH
50
51static reloc_howto_type r_imm32 =
b34976b6
AM
52HOWTO (R_H8500_IMM32, 0, 1, 32, FALSE, 0,
53 complain_overflow_bitfield, 0, "r_imm32", TRUE, 0xffffffff, 0xffffffff, FALSE);
252b5132 54
252b5132 55static reloc_howto_type r_high8 =
b34976b6
AM
56HOWTO (R_H8500_HIGH8, 0, 1, 8, FALSE, 0,
57 complain_overflow_dont, 0, "r_high8", TRUE, 0x000000ff, 0x000000ff, FALSE);
252b5132
RH
58
59static reloc_howto_type r_low16 =
b34976b6
AM
60HOWTO (R_H8500_LOW16, 0, 1, 16, FALSE, 0,
61 complain_overflow_dont, 0, "r_low16", TRUE, 0x0000ffff, 0x0000ffff, FALSE);
252b5132
RH
62
63static reloc_howto_type r_pcrel8 =
b34976b6 64HOWTO (R_H8500_PCREL8, 0, 1, 8, TRUE, 0, complain_overflow_signed, 0, "r_pcrel8", TRUE, 0, 0, TRUE);
252b5132 65
252b5132 66static reloc_howto_type r_pcrel16 =
b34976b6 67HOWTO (R_H8500_PCREL16, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0, "r_pcrel16", TRUE, 0, 0, TRUE);
252b5132
RH
68
69static reloc_howto_type r_high16 =
b34976b6
AM
70HOWTO (R_H8500_HIGH16, 0, 1, 8, FALSE, 0,
71 complain_overflow_dont, 0, "r_high16", TRUE, 0x000ffff, 0x0000ffff, FALSE);
f4ffd778
NC
72\f
73/* Turn a howto into a reloc number. */
252b5132 74
5fcfd273 75static int
252b5132
RH
76coff_h8500_select_reloc (howto)
77 reloc_howto_type *howto;
78{
79 return howto->type;
80}
81
82#define SELECT_RELOC(x,howto) x.r_type = coff_h8500_select_reloc(howto)
83
252b5132
RH
84#define BADMAG(x) H8500BADMAG(x)
85#define H8500 1 /* Customize coffcode.h */
86
87#define __A_MAGIC_SET__
88
f4ffd778 89/* Code to swap in the reloc. */
dc810e39
AM
90#define SWAP_IN_RELOC_OFFSET H_GET_32
91#define SWAP_OUT_RELOC_OFFSET H_PUT_32
252b5132
RH
92#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
93 dst->r_stuff[0] = 'S'; \
94 dst->r_stuff[1] = 'C';
95
f4ffd778 96/* Code to turn a r_type into a howto ptr, uses the above howto table. */
252b5132
RH
97
98static void
f4ffd778 99rtype2howto (internal, dst)
252b5132
RH
100 arelent * internal;
101 struct internal_reloc *dst;
102{
103 switch (dst->r_type)
104 {
105 default:
106 abort ();
107 break;
108 case R_H8500_IMM8:
109 internal->howto = &r_imm8;
110 break;
111 case R_H8500_IMM16:
112 internal->howto = &r_imm16;
113 break;
114 case R_H8500_IMM24:
115 internal->howto = &r_imm24;
116 break;
117 case R_H8500_IMM32:
118 internal->howto = &r_imm32;
119 break;
120 case R_H8500_PCREL8:
121 internal->howto = &r_pcrel8;
122 break;
123 case R_H8500_PCREL16:
124 internal->howto = &r_pcrel16;
125 break;
126 case R_H8500_HIGH8:
127 internal->howto = &r_high8;
128 break;
129 case R_H8500_HIGH16:
130 internal->howto = &r_high16;
131 break;
132 case R_H8500_LOW16:
133 internal->howto = &r_low16;
134 break;
135 }
136}
137
138#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
139
f4ffd778 140/* Perform any necessary magic to the addend in a reloc entry. */
252b5132 141
252b5132
RH
142#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
143 cache_ptr->addend = ext_reloc.r_offset;
144
252b5132
RH
145#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
146 reloc_processing(relent, reloc, symbols, abfd, section)
147
148static void reloc_processing (relent, reloc, symbols, abfd, section)
149 arelent * relent;
150 struct internal_reloc *reloc;
151 asymbol ** symbols;
152 bfd * abfd;
153 asection * section;
154{
155 relent->address = reloc->r_vaddr;
156 rtype2howto (relent, reloc);
157
158 if (reloc->r_symndx > 0)
f4ffd778 159 relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
252b5132 160 else
f4ffd778 161 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
252b5132 162
252b5132
RH
163 relent->addend = reloc->r_offset;
164 relent->address -= section->vma;
165}
166
167static void
168extra_case (in_abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)
169 bfd *in_abfd;
170 struct bfd_link_info *link_info;
171 struct bfd_link_order *link_order;
172 arelent *reloc;
173 bfd_byte *data;
174 unsigned int *src_ptr;
175 unsigned int *dst_ptr;
176{
177 bfd_byte *d = data+*dst_ptr;
178 asection *input_section = link_order->u.indirect.section;
f4ffd778 179
252b5132
RH
180 switch (reloc->howto->type)
181 {
182 case R_H8500_IMM8:
183 bfd_put_8 (in_abfd,
184 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
185 d);
186 (*dst_ptr) += 1;
187 (*src_ptr) += 1;
188 break;
189
190 case R_H8500_HIGH8:
191 bfd_put_8 (in_abfd,
192 (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
193 >> 16),
f4ffd778 194 d);
252b5132
RH
195 (*dst_ptr) += 1;
196 (*src_ptr) += 1;
197 break;
198
199 case R_H8500_IMM16:
200 bfd_put_16 (in_abfd,
201 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
f4ffd778 202 d);
252b5132
RH
203 (*dst_ptr) += 2;
204 (*src_ptr) += 2;
205 break;
206
207 case R_H8500_LOW16:
208 bfd_put_16 (in_abfd,
209 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
210 d);
211
212 (*dst_ptr) += 2;
213 (*src_ptr) += 2;
214 break;
5fcfd273 215
252b5132
RH
216 case R_H8500_HIGH16:
217 bfd_put_16 (in_abfd,
218 (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
f4ffd778 219 >> 16),
252b5132
RH
220 d);
221
222 (*dst_ptr) += 2;
223 (*src_ptr) += 2;
224 break;
225
226 case R_H8500_IMM24:
227 {
f4ffd778 228 int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
6e301b2b 229 int o = bfd_get_32 (in_abfd, data+ *dst_ptr -1);
252b5132 230 v = (v & 0x00ffffff) | (o & 0xff00000);
dc810e39 231 bfd_put_32 (in_abfd, (bfd_vma) v, data + *dst_ptr -1);
f4ffd778
NC
232 (*dst_ptr) += 3;
233 (*src_ptr) += 3;;
252b5132
RH
234 }
235 break;
236 case R_H8500_IMM32:
237 {
f4ffd778 238 int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
dc810e39 239 bfd_put_32 (in_abfd, (bfd_vma) v, data + *dst_ptr);
f4ffd778
NC
240 (*dst_ptr) += 4;
241 (*src_ptr) += 4;;
252b5132
RH
242 }
243 break;
244
252b5132
RH
245 case R_H8500_PCREL8:
246 {
247 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
248 input_section);
44da2da1
AM
249 bfd_vma dot = (*dst_ptr
250 + input_section->output_offset
251 + input_section->output_section->vma);
252b5132 252 int gap = dst - dot - 1; /* -1 since were in the odd byte of the
f4ffd778 253 word and the pc's been incremented. */
252b5132
RH
254
255 if (gap > 128 || gap < -128)
256 {
257 if (! ((*link_info->callbacks->reloc_overflow)
dfeffb9f
L
258 (link_info, NULL,
259 bfd_asymbol_name (*reloc->sym_ptr_ptr),
252b5132
RH
260 reloc->howto->name, reloc->addend, input_section->owner,
261 input_section, reloc->address)))
262 abort ();
263 }
264 bfd_put_8 (in_abfd, gap, data + *dst_ptr);
265 (*dst_ptr)++;
266 (*src_ptr)++;
267 break;
268 }
269 case R_H8500_PCREL16:
270 {
271 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
272 input_section);
44da2da1
AM
273 bfd_vma dot = (*dst_ptr
274 + input_section->output_offset
275 + input_section->output_section->vma);
252b5132 276 int gap = dst - dot - 1; /* -1 since were in the odd byte of the
f4ffd778 277 word and the pc's been incremented. */
252b5132
RH
278
279 if (gap > 32767 || gap < -32768)
280 {
281 if (! ((*link_info->callbacks->reloc_overflow)
dfeffb9f
L
282 (link_info, NULL,
283 bfd_asymbol_name (*reloc->sym_ptr_ptr),
252b5132
RH
284 reloc->howto->name, reloc->addend, input_section->owner,
285 input_section, reloc->address)))
286 abort ();
287 }
dc810e39 288 bfd_put_16 (in_abfd, (bfd_vma) gap, data + *dst_ptr);
f4ffd778
NC
289 (*dst_ptr) += 2;
290 (*src_ptr) += 2;
252b5132
RH
291 break;
292 }
293
294 default:
295 abort ();
296 }
297}
298
299#define coff_reloc16_extra_cases extra_case
300
2b5c217d
NC
301#ifndef bfd_pe_print_pdata
302#define bfd_pe_print_pdata NULL
303#endif
304
252b5132
RH
305#include "coffcode.h"
306
252b5132
RH
307#undef coff_bfd_get_relocated_section_contents
308#undef coff_bfd_relax_section
309#define coff_bfd_get_relocated_section_contents \
310 bfd_coff_reloc16_get_relocated_section_contents
311#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
312
3fa78519 313CREATE_BIG_COFF_TARGET_VEC (h8500coff_vec, "coff-h8500", 0, 0, '_', NULL, COFF_SWAP_TABLE)
This page took 0.481499 seconds and 4 git commands to generate.