source: trunk/src/binutils/bfd/coff-h8500.c@ 1036

Last change on this file since 1036 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 8.8 KB
Line 
1/* BFD back-end for Renesas H8/500 COFF binaries.
2 Copyright 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Contributed by Cygnus Support.
5 Written by Steve Chamberlain, <sac@cygnus.com>.
6
7 This file is part of BFD, the Binary File Descriptor library.
8
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
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
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.
18
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
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23#include "bfd.h"
24#include "sysdep.h"
25#include "libbfd.h"
26#include "bfdlink.h"
27#include "coff/h8500.h"
28#include "coff/internal.h"
29#include "libcoff.h"
30
31static int coff_h8500_select_reloc PARAMS ((reloc_howto_type *));
32static void rtype2howto PARAMS ((arelent *, struct internal_reloc *));
33static void reloc_processing PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *));
34static void extra_case PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *, bfd_byte *, unsigned int *, unsigned int *));
35
36#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
37
38static reloc_howto_type r_imm8 =
39HOWTO (R_H8500_IMM8, 0, 1, 8, FALSE, 0,
40 complain_overflow_bitfield, 0, "r_imm8", TRUE, 0x000000ff, 0x000000ff, FALSE);
41
42static reloc_howto_type r_imm16 =
43HOWTO (R_H8500_IMM16, 0, 1, 16, FALSE, 0,
44 complain_overflow_bitfield, 0, "r_imm16", TRUE, 0x0000ffff, 0x0000ffff, FALSE);
45
46static reloc_howto_type r_imm24 =
47HOWTO (R_H8500_IMM24, 0, 1, 24, FALSE, 0,
48 complain_overflow_bitfield, 0, "r_imm24", TRUE, 0x00ffffff, 0x00ffffff, FALSE);
49
50static reloc_howto_type r_imm32 =
51HOWTO (R_H8500_IMM32, 0, 1, 32, FALSE, 0,
52 complain_overflow_bitfield, 0, "r_imm32", TRUE, 0xffffffff, 0xffffffff, FALSE);
53
54static reloc_howto_type r_high8 =
55HOWTO (R_H8500_HIGH8, 0, 1, 8, FALSE, 0,
56 complain_overflow_dont, 0, "r_high8", TRUE, 0x000000ff, 0x000000ff, FALSE);
57
58static reloc_howto_type r_low16 =
59HOWTO (R_H8500_LOW16, 0, 1, 16, FALSE, 0,
60 complain_overflow_dont, 0, "r_low16", TRUE, 0x0000ffff, 0x0000ffff, FALSE);
61
62static reloc_howto_type r_pcrel8 =
63HOWTO (R_H8500_PCREL8, 0, 1, 8, TRUE, 0, complain_overflow_signed, 0, "r_pcrel8", TRUE, 0, 0, TRUE);
64
65static reloc_howto_type r_pcrel16 =
66HOWTO (R_H8500_PCREL16, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0, "r_pcrel16", TRUE, 0, 0, TRUE);
67
68static reloc_howto_type r_high16 =
69HOWTO (R_H8500_HIGH16, 0, 1, 8, FALSE, 0,
70 complain_overflow_dont, 0, "r_high16", TRUE, 0x000ffff, 0x0000ffff, FALSE);
71
72
73/* Turn a howto into a reloc number. */
74
75static int
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
84#define BADMAG(x) H8500BADMAG(x)
85#define H8500 1 /* Customize coffcode.h */
86
87#define __A_MAGIC_SET__
88
89/* Code to swap in the reloc. */
90#define SWAP_IN_RELOC_OFFSET H_GET_32
91#define SWAP_OUT_RELOC_OFFSET H_PUT_32
92#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
93 dst->r_stuff[0] = 'S'; \
94 dst->r_stuff[1] = 'C';
95
96/* Code to turn a r_type into a howto ptr, uses the above howto table. */
97
98static void
99rtype2howto (internal, dst)
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
140/* Perform any necessary magic to the addend in a reloc entry. */
141
142#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
143 cache_ptr->addend = ext_reloc.r_offset;
144
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)
159 relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
160 else
161 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
162
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;
179
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),
194 d);
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),
202 d);
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;
215
216 case R_H8500_HIGH16:
217 bfd_put_16 (in_abfd,
218 (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
219 >> 16),
220 d);
221
222 (*dst_ptr) += 2;
223 (*src_ptr) += 2;
224 break;
225
226 case R_H8500_IMM24:
227 {
228 int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
229 int o = bfd_get_32 (in_abfd, data+ *dst_ptr -1);
230 v = (v & 0x00ffffff) | (o & 0xff00000);
231 bfd_put_32 (in_abfd, (bfd_vma) v, data + *dst_ptr -1);
232 (*dst_ptr) += 3;
233 (*src_ptr) += 3;;
234 }
235 break;
236 case R_H8500_IMM32:
237 {
238 int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
239 bfd_put_32 (in_abfd, (bfd_vma) v, data + *dst_ptr);
240 (*dst_ptr) += 4;
241 (*src_ptr) += 4;;
242 }
243 break;
244
245 case R_H8500_PCREL8:
246 {
247 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
248 input_section);
249 bfd_vma dot = link_order->offset
250 + *dst_ptr
251 + link_order->u.indirect.section->output_section->vma;
252 int gap = dst - dot - 1; /* -1 since were in the odd byte of the
253 word and the pc's been incremented. */
254
255 if (gap > 128 || gap < -128)
256 {
257 if (! ((*link_info->callbacks->reloc_overflow)
258 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
259 reloc->howto->name, reloc->addend, input_section->owner,
260 input_section, reloc->address)))
261 abort ();
262 }
263 bfd_put_8 (in_abfd, gap, data + *dst_ptr);
264 (*dst_ptr)++;
265 (*src_ptr)++;
266 break;
267 }
268 case R_H8500_PCREL16:
269 {
270 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
271 input_section);
272 bfd_vma dot = link_order->offset
273 + *dst_ptr
274 + link_order->u.indirect.section->output_section->vma;
275 int gap = dst - dot - 1; /* -1 since were in the odd byte of the
276 word and the pc's been incremented. */
277
278 if (gap > 32767 || gap < -32768)
279 {
280 if (! ((*link_info->callbacks->reloc_overflow)
281 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
282 reloc->howto->name, reloc->addend, input_section->owner,
283 input_section, reloc->address)))
284 abort ();
285 }
286 bfd_put_16 (in_abfd, (bfd_vma) gap, data + *dst_ptr);
287 (*dst_ptr) += 2;
288 (*src_ptr) += 2;
289 break;
290 }
291
292 default:
293 abort ();
294 }
295}
296
297#define coff_reloc16_extra_cases extra_case
298
299#include "coffcode.h"
300
301#undef coff_bfd_get_relocated_section_contents
302#undef coff_bfd_relax_section
303#define coff_bfd_get_relocated_section_contents \
304 bfd_coff_reloc16_get_relocated_section_contents
305#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
306
307CREATE_BIG_COFF_TARGET_VEC (h8500coff_vec, "coff-h8500", 0, 0, '_', NULL)
Note: See TracBrowser for help on using the repository browser.