source: trunk/src/binutils/bfd/coff-z8k.c@ 610

Last change on this file since 610 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: 9.8 KB
Line 
1/* BFD back-end for Zilog Z800n COFF binaries.
2 Copyright 1992, 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by Cygnus Support.
5 Written by Steve Chamberlain, <sac@cygnus.com>.
6
7This file is part of BFD, the Binary File Descriptor library.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, 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/z8k.h"
28#include "coff/internal.h"
29#include "libcoff.h"
30
31static void extra_case PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *, bfd_byte *, unsigned int *, unsigned int *));
32static void reloc_processing PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *));
33static void rtype2howto PARAMS ((arelent *, struct internal_reloc *));
34static int coff_z8k_select_reloc PARAMS ((reloc_howto_type *));
35
36#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
37
38static reloc_howto_type r_imm32 =
39HOWTO (R_IMM32, 0, 2, 32, FALSE, 0,
40 complain_overflow_bitfield, 0, "r_imm32", TRUE, 0xffffffff,
41 0xffffffff, FALSE);
42
43static reloc_howto_type r_imm4l =
44HOWTO (R_IMM4L, 0, 0, 4, FALSE, 0,
45 complain_overflow_bitfield, 0, "r_imm4l", TRUE, 0xf, 0xf, FALSE);
46
47static reloc_howto_type r_da =
48HOWTO (R_IMM16, 0, 1, 16, FALSE, 0,
49 complain_overflow_bitfield, 0, "r_da", TRUE, 0x0000ffff, 0x0000ffff,
50 FALSE);
51
52static reloc_howto_type r_imm8 =
53HOWTO (R_IMM8, 0, 0, 8, FALSE, 0,
54 complain_overflow_bitfield, 0, "r_imm8", TRUE, 0x000000ff, 0x000000ff,
55 FALSE);
56
57static reloc_howto_type r_rel16 =
58HOWTO (R_REL16, 0, 1, 16, FALSE, 0,
59 complain_overflow_bitfield, 0, "r_rel16", TRUE, 0x0000ffff, 0x0000ffff,
60 TRUE);
61
62static reloc_howto_type r_jr =
63HOWTO (R_JR, 0, 0, 8, TRUE, 0, complain_overflow_signed, 0,
64 "r_jr", TRUE, 0, 0, TRUE);
65
66static reloc_howto_type r_disp7 =
67HOWTO (R_DISP7, 0, 0, 7, TRUE, 0, complain_overflow_bitfield, 0,
68 "r_disp7", TRUE, 0, 0, TRUE);
69
70static reloc_howto_type r_callr =
71HOWTO (R_CALLR, 0, 1, 12, TRUE, 0, complain_overflow_signed, 0,
72 "r_callr", TRUE, 0xfff, 0xfff, TRUE);
73
74/* Turn a howto into a reloc number */
75
76static int
77coff_z8k_select_reloc (howto)
78 reloc_howto_type *howto;
79{
80 return howto->type;
81}
82
83#define SELECT_RELOC(x,howto) x.r_type = coff_z8k_select_reloc(howto)
84
85#define BADMAG(x) Z8KBADMAG(x)
86#define Z8K 1 /* Customize coffcode.h */
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_IMM8:
109 internal->howto = &r_imm8;
110 break;
111 case R_IMM16:
112 internal->howto = &r_da;
113 break;
114 case R_JR:
115 internal->howto = &r_jr;
116 break;
117 case R_DISP7:
118 internal->howto = &r_disp7;
119 break;
120 case R_CALLR:
121 internal->howto = &r_callr;
122 break;
123 case R_REL16:
124 internal->howto = &r_rel16;
125 break;
126 case R_IMM32:
127 internal->howto = &r_imm32;
128 break;
129 case R_IMM4L:
130 internal->howto = &r_imm4l;
131 break;
132 }
133}
134
135#define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry)
136
137/* Perform any necessary magic to the addend in a reloc entry. */
138
139#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
140 cache_ptr->addend = ext_reloc.r_offset;
141
142#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
143 reloc_processing(relent, reloc, symbols, abfd, section)
144
145static void
146reloc_processing (relent, reloc, symbols, abfd, section)
147 arelent * relent;
148 struct internal_reloc * reloc;
149 asymbol ** symbols;
150 bfd * abfd;
151 asection * section;
152{
153 relent->address = reloc->r_vaddr;
154 rtype2howto (relent, reloc);
155
156 if (reloc->r_symndx > 0)
157 relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
158 else
159 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
160
161 relent->addend = reloc->r_offset;
162 relent->address -= section->vma;
163}
164
165static void
166extra_case (in_abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)
167 bfd * in_abfd;
168 struct bfd_link_info * link_info;
169 struct bfd_link_order * link_order;
170 arelent * reloc;
171 bfd_byte * data;
172 unsigned int * src_ptr;
173 unsigned int * dst_ptr;
174{
175 asection * input_section = link_order->u.indirect.section;
176
177 switch (reloc->howto->type)
178 {
179 case R_IMM8:
180 bfd_put_8 (in_abfd,
181 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
182 data + *dst_ptr);
183 (*dst_ptr) += 1;
184 (*src_ptr) += 1;
185 break;
186
187 case R_IMM32:
188 /* If no flags are set, assume immediate value. */
189 if (! (*reloc->sym_ptr_ptr)->section->flags)
190 {
191 bfd_put_32 (in_abfd,
192 bfd_coff_reloc16_get_value (reloc, link_info,
193 input_section),
194 data + *dst_ptr);
195 }
196 else
197 {
198 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
199 input_section);
200 /* Adresses are 23 bit, and the layout of those in a 32-bit
201 value is as follows:
202 1AAAAAAA xxxxxxxx AAAAAAAA AAAAAAAA
203 (A - address bits, x - ignore). */
204 dst = (dst & 0xffff) | ((dst & 0xff0000) << 8) | 0x80000000;
205 bfd_put_32 (in_abfd, dst, data + *dst_ptr);
206 }
207 (*dst_ptr) += 4;
208 (*src_ptr) += 4;
209 break;
210
211 case R_IMM4L:
212 bfd_put_8 (in_abfd,
213 ((bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0)
214 | (0x0f
215 & bfd_coff_reloc16_get_value (reloc, link_info,
216 input_section))),
217 data + *dst_ptr);
218 (*dst_ptr) += 1;
219 (*src_ptr) += 1;
220 break;
221
222 case R_IMM16:
223 bfd_put_16 (in_abfd,
224 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
225 data + *dst_ptr);
226 (*dst_ptr) += 2;
227 (*src_ptr) += 2;
228 break;
229
230 case R_JR:
231 {
232 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
233 input_section);
234 bfd_vma dot = (link_order->offset
235 + *dst_ptr
236 + input_section->output_section->vma);
237 int gap = dst - dot - 1; /* -1, since we're in the odd byte of the
238 word and the pc's been incremented. */
239
240 if (gap & 1)
241 abort ();
242 gap /= 2;
243 if (gap > 128 || gap < -128)
244 {
245 if (! ((*link_info->callbacks->reloc_overflow)
246 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
247 reloc->howto->name, reloc->addend, input_section->owner,
248 input_section, reloc->address)))
249 abort ();
250 }
251 bfd_put_8 (in_abfd, gap, data + *dst_ptr);
252 (*dst_ptr)++;
253 (*src_ptr)++;
254 break;
255 }
256
257 case R_DISP7:
258 {
259 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
260 input_section);
261 bfd_vma dot = (link_order->offset
262 + *dst_ptr
263 + input_section->output_section->vma);
264 int gap = dst - dot - 1; /* -1, since we're in the odd byte of the
265 word and the pc's been incremented. */
266
267 if (gap & 1)
268 abort ();
269 gap /= 2;
270
271 if (gap > 0 || gap < -128)
272 {
273 if (! ((*link_info->callbacks->reloc_overflow)
274 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
275 reloc->howto->name, reloc->addend, input_section->owner,
276 input_section, reloc->address)))
277 abort ();
278 }
279 bfd_put_8 (in_abfd,
280 (bfd_get_8 ( in_abfd, data + *dst_ptr) & 0x80) + (-gap & 0x7f),
281 data + *dst_ptr);
282 (*dst_ptr)++;
283 (*src_ptr)++;
284 break;
285 }
286
287 case R_CALLR:
288 {
289 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
290 input_section);
291 bfd_vma dot = (link_order->offset
292 + *dst_ptr
293 + input_section->output_section->vma);
294 int gap = dst - dot - 2;
295
296 if (gap & 1)
297 abort ();
298 gap /= 2;
299 if (gap > 8191 || gap < -8192)
300 {
301 if (! ((*link_info->callbacks->reloc_overflow)
302 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
303 reloc->howto->name, reloc->addend, input_section->owner,
304 input_section, reloc->address)))
305 abort ();
306 }
307 bfd_put_16 (in_abfd,
308 (bfd_get_16 ( in_abfd, data + *dst_ptr) & 0xf000) | (-gap & 0x0fff),
309 data + *dst_ptr);
310 (*dst_ptr) += 2;
311 (*src_ptr) += 2;
312 break;
313 }
314
315 case R_REL16:
316 {
317 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
318 input_section);
319 bfd_vma dot = (link_order->offset
320 + *dst_ptr
321 + input_section->output_section->vma);
322 int gap = dst - dot - 2;
323
324 if (gap > 32767 || gap < -32768)
325 {
326 if (! ((*link_info->callbacks->reloc_overflow)
327 (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
328 reloc->howto->name, reloc->addend, input_section->owner,
329 input_section, reloc->address)))
330 abort ();
331 }
332 bfd_put_16 (in_abfd, (bfd_vma) gap, data + *dst_ptr);
333 (*dst_ptr) += 2;
334 (*src_ptr) += 2;
335 break;
336 }
337
338 default:
339 abort ();
340 }
341}
342
343#define coff_reloc16_extra_cases extra_case
344
345#include "coffcode.h"
346
347#undef coff_bfd_get_relocated_section_contents
348#undef coff_bfd_relax_section
349#define coff_bfd_get_relocated_section_contents \
350 bfd_coff_reloc16_get_relocated_section_contents
351#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
352
353CREATE_BIG_COFF_TARGET_VEC (z8kcoff_vec, "coff-z8k", 0, 0, '_', NULL)
Note: See TracBrowser for help on using the repository browser.