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