Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / coff-z80.c
CommitLineData
3c9b82ba 1/* BFD back-end for Zilog Z80 COFF binaries.
2571583a 2 Copyright (C) 2005-2017 Free Software Foundation, Inc.
3c9b82ba
NC
3 Contributed by Arnold Metselaar <arnold_m@operamail.com>
4
5 This file is part of BFD, the Binary File Descriptor library.
6
68ffbac6 7 This program is free software; you can redistribute it and/or modify
3c9b82ba 8 it under the terms of the GNU General Public License as published by
cd123cb7 9 the Free Software Foundation; either version 3 of the License, or
3c9b82ba
NC
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
21
3c9b82ba 22#include "sysdep.h"
3db64b00 23#include "bfd.h"
3c9b82ba
NC
24#include "libbfd.h"
25#include "bfdlink.h"
26#include "coff/z80.h"
27#include "coff/internal.h"
28#include "libcoff.h"
29
30#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 0
31
32static reloc_howto_type r_imm32 =
96d4e9de 33HOWTO (R_IMM32, 0, 2, 32, FALSE, 0,
3c9b82ba
NC
34 complain_overflow_dont, 0, "r_imm32", TRUE, 0xffffffff, 0xffffffff,
35 FALSE);
36
134dcee5
AM
37static reloc_howto_type r_imm24 =
38HOWTO (R_IMM24, 0, 1, 24, FALSE, 0,
39 complain_overflow_dont, 0, "r_imm24", TRUE, 0x00ffffff, 0x00ffffff,
40 FALSE);
41
3c9b82ba
NC
42static reloc_howto_type r_imm16 =
43HOWTO (R_IMM16, 0, 1, 16, FALSE, 0,
44 complain_overflow_dont, 0, "r_imm16", TRUE, 0x0000ffff, 0x0000ffff,
45 FALSE);
46
47static reloc_howto_type r_imm8 =
48HOWTO (R_IMM8, 0, 0, 8, FALSE, 0,
49 complain_overflow_bitfield, 0, "r_imm8", TRUE, 0x000000ff, 0x000000ff,
50 FALSE);
51
52static reloc_howto_type r_jr =
68ffbac6 53HOWTO (R_JR, 0, 0, 8, TRUE, 0,
3c9b82ba
NC
54 complain_overflow_signed, 0, "r_jr", FALSE, 0, 0xFF,
55 FALSE);
56
57static reloc_howto_type r_off8 =
68ffbac6 58HOWTO (R_OFF8, 0, 0, 8, FALSE, 0,
3c9b82ba
NC
59 complain_overflow_signed, 0,"r_off8", FALSE, 0, 0xff,
60 FALSE);
61
62
63#define BADMAG(x) Z80BADMAG(x)
64#define Z80 1 /* Customize coffcode.h. */
65#define __A_MAGIC_SET__
66
67/* Code to swap in the reloc. */
68
69#define SWAP_IN_RELOC_OFFSET H_GET_32
70#define SWAP_OUT_RELOC_OFFSET H_PUT_32
71
72#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
73 dst->r_stuff[0] = 'S'; \
74 dst->r_stuff[1] = 'C';
75
76/* Code to turn a r_type into a howto ptr, uses the above howto table. */
77
78static void
79rtype2howto (arelent *internal, struct internal_reloc *dst)
80{
81 switch (dst->r_type)
82 {
83 default:
a1165289 84 internal->howto = NULL;
3c9b82ba
NC
85 break;
86 case R_IMM8:
87 internal->howto = &r_imm8;
88 break;
89 case R_IMM16:
90 internal->howto = &r_imm16;
91 break;
134dcee5
AM
92 case R_IMM24:
93 internal->howto = &r_imm24;
94 break;
3c9b82ba
NC
95 case R_IMM32:
96 internal->howto = &r_imm32;
97 break;
98 case R_JR:
99 internal->howto = &r_jr;
100 break;
101 case R_OFF8:
102 internal->howto = &r_off8;
103 break;
104 }
105}
106
107#define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry)
108
109static reloc_howto_type *
110coff_z80_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
111 bfd_reloc_code_real_type code)
112{
113 switch (code)
114 {
115 case BFD_RELOC_8: return & r_imm8;
116 case BFD_RELOC_16: return & r_imm16;
134dcee5 117 case BFD_RELOC_24: return & r_imm24;
3c9b82ba
NC
118 case BFD_RELOC_32: return & r_imm32;
119 case BFD_RELOC_8_PCREL: return & r_jr;
120 case BFD_RELOC_Z80_DISP8: return & r_off8;
121 default: BFD_FAIL ();
122 return NULL;
123 }
124}
125
157090f7
AM
126static reloc_howto_type *
127coff_z80_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
128 const char *r_name)
129{
130 if (strcasecmp (r_imm8.name, r_name) == 0)
131 return &r_imm8;
132 if (strcasecmp (r_imm16.name, r_name) == 0)
133 return &r_imm16;
134 if (strcasecmp (r_imm24.name, r_name) == 0)
135 return &r_imm24;
136 if (strcasecmp (r_imm32.name, r_name) == 0)
137 return &r_imm32;
138 if (strcasecmp (r_jr.name, r_name) == 0)
139 return &r_jr;
140 if (strcasecmp (r_off8.name, r_name) == 0)
141 return &r_off8;
142
143 return NULL;
144}
145
3c9b82ba
NC
146/* Perform any necessary magic to the addend in a reloc entry. */
147
148#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
149 cache_ptr->addend = ext_reloc.r_offset;
150
151#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
152 reloc_processing(relent, reloc, symbols, abfd, section)
153
154static void
155reloc_processing (arelent *relent,
156 struct internal_reloc *reloc,
157 asymbol **symbols,
158 bfd *abfd,
159 asection *section)
160{
161 relent->address = reloc->r_vaddr;
162 rtype2howto (relent, reloc);
163
164 if (reloc->r_symndx > 0)
165 relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
166 else
167 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
168
169 relent->addend = reloc->r_offset;
170 relent->address -= section->vma;
171}
172
173static void
174extra_case (bfd *in_abfd,
175 struct bfd_link_info *link_info,
176 struct bfd_link_order *link_order,
177 arelent *reloc,
178 bfd_byte *data,
179 unsigned int *src_ptr,
180 unsigned int *dst_ptr)
181{
182 asection * input_section = link_order->u.indirect.section;
183 int val;
184
185 switch (reloc->howto->type)
186 {
187 case R_OFF8:
188 val = bfd_coff_reloc16_get_value (reloc, link_info,
189 input_section);
190 if (val>127 || val<-128) /* Test for overflow. */
1a72702b
AM
191 (*link_info->callbacks->reloc_overflow)
192 (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr),
193 reloc->howto->name, reloc->addend, input_section->owner,
194 input_section, reloc->address);
195
3c9b82ba
NC
196 bfd_put_8 (in_abfd, val, data + *dst_ptr);
197 (*dst_ptr) += 1;
198 (*src_ptr) += 1;
199 break;
200
201 case R_IMM8:
134dcee5 202 val = bfd_get_8 ( in_abfd, data+*src_ptr)
3c9b82ba
NC
203 + bfd_coff_reloc16_get_value (reloc, link_info, input_section);
204 bfd_put_8 (in_abfd, val, data + *dst_ptr);
205 (*dst_ptr) += 1;
206 (*src_ptr) += 1;
207 break;
208
209 case R_IMM16:
210 val = bfd_get_16 ( in_abfd, data+*src_ptr)
211 + bfd_coff_reloc16_get_value (reloc, link_info, input_section);
212 bfd_put_16 (in_abfd, val, data + *dst_ptr);
213 (*dst_ptr) += 2;
214 (*src_ptr) += 2;
215 break;
216
134dcee5
AM
217 case R_IMM24:
218 val = bfd_get_16 ( in_abfd, data+*src_ptr)
219 + (bfd_get_8 ( in_abfd, data+*src_ptr+2) << 16)
220 + bfd_coff_reloc16_get_value (reloc, link_info, input_section);
221 bfd_put_16 (in_abfd, val, data + *dst_ptr);
222 bfd_put_8 (in_abfd, val >> 16, data + *dst_ptr+2);
223 (*dst_ptr) += 3;
224 (*src_ptr) += 3;
225 break;
226
3c9b82ba
NC
227 case R_IMM32:
228 val = bfd_get_32 ( in_abfd, data+*src_ptr)
229 + bfd_coff_reloc16_get_value (reloc, link_info, input_section);
230 bfd_put_32 (in_abfd, val, data + *dst_ptr);
231 (*dst_ptr) += 4;
232 (*src_ptr) += 4;
233 break;
234
235 case R_JR:
236 {
237 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
238 input_section);
44da2da1
AM
239 bfd_vma dot = (*dst_ptr
240 + input_section->output_offset
3c9b82ba
NC
241 + input_section->output_section->vma);
242 int gap = dst - dot - 1; /* -1, Since the offset is relative
243 to the value of PC after reading
244 the offset. */
245
246 if (gap >= 128 || gap < -128)
1a72702b
AM
247 (*link_info->callbacks->reloc_overflow)
248 (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr),
249 reloc->howto->name, reloc->addend, input_section->owner,
250 input_section, reloc->address);
251
3c9b82ba
NC
252 bfd_put_8 (in_abfd, gap, data + *dst_ptr);
253 (*dst_ptr)++;
254 (*src_ptr)++;
255 break;
256 }
257
258 default:
259 abort ();
260 }
261}
262
263#define coff_reloc16_extra_cases extra_case
264#define coff_bfd_reloc_type_lookup coff_z80_reloc_type_lookup
157090f7 265#define coff_bfd_reloc_name_lookup coff_z80_reloc_name_lookup
3c9b82ba 266
2b5c217d
NC
267#ifndef bfd_pe_print_pdata
268#define bfd_pe_print_pdata NULL
269#endif
270
3c9b82ba
NC
271#include "coffcode.h"
272
273#undef coff_bfd_get_relocated_section_contents
274#define coff_bfd_get_relocated_section_contents \
275 bfd_coff_reloc16_get_relocated_section_contents
276
277#undef coff_bfd_relax_section
278#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
279
6d00b590 280CREATE_LITTLE_COFF_TARGET_VEC (z80_coff_vec, "coff-z80", 0,
68ffbac6 281 SEC_CODE | SEC_DATA, '\0', NULL,
3c9b82ba
NC
282 COFF_SWAP_TABLE)
283
This page took 0.507921 seconds and 4 git commands to generate.