coff-z80.c revision 1.1.1.9 1 1.1 skrll /* BFD back-end for Zilog Z80 COFF binaries.
2 1.1.1.9 christos Copyright (C) 2005-2025 Free Software Foundation, Inc.
3 1.1 skrll Contributed by Arnold Metselaar <arnold_m (at) operamail.com>
4 1.1 skrll
5 1.1 skrll This file is part of BFD, the Binary File Descriptor library.
6 1.1 skrll
7 1.1.1.3 christos This program is free software; you can redistribute it and/or modify
8 1.1 skrll it under the terms of the GNU General Public License as published by
9 1.1 skrll the Free Software Foundation; either version 3 of the License, or
10 1.1 skrll (at your option) any later version.
11 1.1 skrll
12 1.1 skrll This program is distributed in the hope that it will be useful,
13 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 skrll GNU General Public License for more details.
16 1.1 skrll
17 1.1 skrll You should have received a copy of the GNU General Public License
18 1.1 skrll along with this program; if not, write to the Free Software
19 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 1.1 skrll MA 02110-1301, USA. */
21 1.1 skrll
22 1.1 skrll #include "sysdep.h"
23 1.1 skrll #include "bfd.h"
24 1.1 skrll #include "libbfd.h"
25 1.1 skrll #include "bfdlink.h"
26 1.1 skrll #include "coff/z80.h"
27 1.1 skrll #include "coff/internal.h"
28 1.1 skrll #include "libcoff.h"
29 1.1.1.6 christos #include "libiberty.h"
30 1.1 skrll
31 1.1 skrll #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 0
32 1.1 skrll
33 1.1.1.7 christos typedef const struct {
34 1.1.1.6 christos bfd_reloc_code_real_type r_type;
35 1.1.1.6 christos reloc_howto_type howto;
36 1.1.1.6 christos } bfd_howto_type;
37 1.1 skrll
38 1.1.1.6 christos #define BFD_EMPTY_HOWTO(rt,x) {rt, EMPTY_HOWTO(x)}
39 1.1.1.6 christos #define BFD_HOWTO(rt,a,b,c,d,e,f,g,h,i,j,k,l,m) {rt, HOWTO(a,b,c,d,e,f,g,h,i,j,k,l,m)}
40 1.1.1.6 christos
41 1.1.1.6 christos static bfd_howto_type howto_table[] =
42 1.1.1.6 christos {
43 1.1.1.6 christos BFD_EMPTY_HOWTO (BFD_RELOC_NONE, 0),
44 1.1.1.6 christos
45 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_32,
46 1.1.1.6 christos R_IMM32, /* type */
47 1.1.1.6 christos 0, /* rightshift */
48 1.1.1.7 christos 4, /* size */
49 1.1.1.6 christos 32, /* bitsize */
50 1.1.1.7 christos false, /* pc_relative */
51 1.1.1.6 christos 0, /* bitpos */
52 1.1.1.6 christos complain_overflow_bitfield, /* complain_on_overflow */
53 1.1.1.6 christos 0, /* special_function */
54 1.1.1.6 christos "r_imm32", /* name */
55 1.1.1.7 christos false, /* partial_inplace */
56 1.1.1.6 christos 0xffffffff, /* src_mask */
57 1.1.1.6 christos 0xffffffff, /* dst_mask */
58 1.1.1.7 christos false), /* pcrel_offset */
59 1.1.1.6 christos
60 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_24,
61 1.1.1.6 christos R_IMM24, /* type */
62 1.1.1.6 christos 0, /* rightshift */
63 1.1.1.7 christos 3, /* size */
64 1.1.1.6 christos 24, /* bitsize */
65 1.1.1.7 christos false, /* pc_relative */
66 1.1.1.6 christos 0, /* bitpos */
67 1.1.1.6 christos complain_overflow_bitfield, /* complain_on_overflow */
68 1.1.1.6 christos 0, /* special_function */
69 1.1.1.6 christos "r_imm24", /* name */
70 1.1.1.7 christos false, /* partial_inplace */
71 1.1.1.6 christos 0x00ffffff, /* src_mask */
72 1.1.1.6 christos 0x00ffffff, /* dst_mask */
73 1.1.1.7 christos false), /* pcrel_offset */
74 1.1.1.6 christos
75 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_16,
76 1.1.1.6 christos R_IMM16, /* type */
77 1.1.1.6 christos 0, /* rightshift */
78 1.1.1.7 christos 2, /* size */
79 1.1.1.6 christos 16, /* bitsize */
80 1.1.1.7 christos false, /* pc_relative */
81 1.1.1.6 christos 0, /* bitpos */
82 1.1.1.6 christos complain_overflow_bitfield, /* complain_on_overflow */
83 1.1.1.6 christos 0, /* special_function */
84 1.1.1.6 christos "r_imm16", /* name */
85 1.1.1.7 christos false, /* partial_inplace */
86 1.1.1.6 christos 0x0000ffff, /* src_mask */
87 1.1.1.6 christos 0x0000ffff, /* dst_mask */
88 1.1.1.7 christos false), /* pcrel_offset */
89 1.1.1.6 christos
90 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_8,
91 1.1.1.6 christos R_IMM8, /* type */
92 1.1.1.6 christos 0, /* rightshift */
93 1.1.1.7 christos 1, /* size */
94 1.1.1.6 christos 8, /* bitsize */
95 1.1.1.7 christos false, /* pc_relative */
96 1.1.1.6 christos 0, /* bitpos */
97 1.1.1.6 christos complain_overflow_bitfield, /* complain_on_overflow */
98 1.1.1.6 christos 0, /* special_function */
99 1.1.1.6 christos "r_imm8", /* name */
100 1.1.1.7 christos false, /* partial_inplace */
101 1.1.1.6 christos 0x000000ff, /* src_mask */
102 1.1.1.6 christos 0x000000ff, /* dst_mask */
103 1.1.1.7 christos false), /* pcrel_offset */
104 1.1.1.6 christos
105 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_8_PCREL,
106 1.1.1.6 christos R_JR, /* type */
107 1.1.1.6 christos 0, /* rightshift */
108 1.1.1.7 christos 1, /* size */
109 1.1.1.6 christos 8, /* bitsize */
110 1.1.1.7 christos true, /* pc_relative */
111 1.1.1.6 christos 0, /* bitpos */
112 1.1.1.6 christos complain_overflow_signed, /* complain_on_overflow */
113 1.1.1.6 christos 0, /* special_function */
114 1.1.1.6 christos "r_jr", /* name */
115 1.1.1.7 christos false, /* partial_inplace */
116 1.1.1.6 christos 0, /* src_mask */
117 1.1.1.6 christos 0xFF, /* dst_mask */
118 1.1.1.7 christos true), /* pcrel_offset */
119 1.1.1.6 christos
120 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_DISP8,
121 1.1.1.6 christos R_OFF8, /* type */
122 1.1.1.6 christos 0, /* rightshift */
123 1.1.1.7 christos 1, /* size */
124 1.1.1.6 christos 8, /* bitsize */
125 1.1.1.7 christos false, /* pc_relative */
126 1.1.1.6 christos 0, /* bitpos */
127 1.1.1.6 christos complain_overflow_signed, /* complain_on_overflow */
128 1.1.1.6 christos 0, /* special_function */
129 1.1.1.6 christos "r_off8", /* name */
130 1.1.1.7 christos false, /* partial_inplace */
131 1.1.1.6 christos 0, /* src_mask */
132 1.1.1.6 christos 0xff, /* dst_mask */
133 1.1.1.7 christos false), /* pcrel_offset */
134 1.1.1.6 christos
135 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_BYTE0,
136 1.1.1.6 christos R_BYTE0, /* type */
137 1.1.1.6 christos 0, /* rightshift */
138 1.1.1.7 christos 1, /* size */
139 1.1.1.6 christos 8, /* bitsize */
140 1.1.1.7 christos false, /* pc_relative */
141 1.1.1.6 christos 0, /* bitpos */
142 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */
143 1.1.1.6 christos 0, /* special_function */
144 1.1.1.6 christos "r_byte0", /* name */
145 1.1.1.7 christos false, /* partial_inplace */
146 1.1.1.6 christos 0, /* src_mask */
147 1.1.1.6 christos 0xff, /* dst_mask */
148 1.1.1.7 christos false), /* pcrel_offset */
149 1.1.1.6 christos
150 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_BYTE1,
151 1.1.1.6 christos R_BYTE1, /* type */
152 1.1.1.6 christos 8, /* rightshift */
153 1.1.1.7 christos 1, /* size */
154 1.1.1.6 christos 8, /* bitsize */
155 1.1.1.7 christos false, /* pc_relative */
156 1.1.1.6 christos 0, /* bitpos */
157 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */
158 1.1.1.6 christos 0, /* special_function */
159 1.1.1.6 christos "r_byte1", /* name */
160 1.1.1.7 christos false, /* partial_inplace */
161 1.1.1.6 christos 0, /* src_mask */
162 1.1.1.6 christos 0xff, /* dst_mask */
163 1.1.1.7 christos false), /* pcrel_offset */
164 1.1.1.6 christos
165 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_BYTE2,
166 1.1.1.6 christos R_BYTE2, /* type */
167 1.1.1.6 christos 16, /* rightshift */
168 1.1.1.7 christos 1, /* size */
169 1.1.1.6 christos 8, /* bitsize */
170 1.1.1.7 christos false, /* pc_relative */
171 1.1.1.6 christos 0, /* bitpos */
172 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */
173 1.1.1.6 christos 0, /* special_function */
174 1.1.1.6 christos "r_byte2", /* name */
175 1.1.1.7 christos false, /* partial_inplace */
176 1.1.1.6 christos 0, /* src_mask */
177 1.1.1.6 christos 0xff, /* dst_mask */
178 1.1.1.7 christos false), /* pcrel_offset */
179 1.1.1.6 christos
180 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_BYTE3,
181 1.1.1.6 christos R_BYTE3, /* type */
182 1.1.1.6 christos 24, /* rightshift */
183 1.1.1.7 christos 1, /* size */
184 1.1.1.6 christos 8, /* bitsize */
185 1.1.1.7 christos false, /* pc_relative */
186 1.1.1.6 christos 0, /* bitpos */
187 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */
188 1.1.1.6 christos 0, /* special_function */
189 1.1.1.6 christos "r_byte3", /* name */
190 1.1.1.7 christos false, /* partial_inplace */
191 1.1.1.6 christos 0, /* src_mask */
192 1.1.1.6 christos 0xff, /* dst_mask */
193 1.1.1.7 christos false), /* pcrel_offset */
194 1.1.1.6 christos
195 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_WORD0,
196 1.1.1.6 christos R_WORD0, /* type */
197 1.1.1.6 christos 0, /* rightshift */
198 1.1.1.7 christos 2, /* size */
199 1.1.1.6 christos 16, /* bitsize */
200 1.1.1.7 christos false, /* pc_relative */
201 1.1.1.6 christos 0, /* bitpos */
202 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */
203 1.1.1.6 christos 0, /* special_function */
204 1.1.1.6 christos "r_word0", /* name */
205 1.1.1.7 christos false, /* partial_inplace */
206 1.1.1.6 christos 0, /* src_mask */
207 1.1.1.6 christos 0xffff, /* dst_mask */
208 1.1.1.7 christos false), /* pcrel_offset */
209 1.1.1.6 christos
210 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_WORD1,
211 1.1.1.6 christos R_WORD1, /* type */
212 1.1.1.6 christos 16, /* rightshift */
213 1.1.1.7 christos 2, /* size */
214 1.1.1.6 christos 16, /* bitsize */
215 1.1.1.7 christos false, /* pc_relative */
216 1.1.1.6 christos 0, /* bitpos */
217 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */
218 1.1.1.6 christos 0, /* special_function */
219 1.1.1.6 christos "r_word1", /* name */
220 1.1.1.7 christos false, /* partial_inplace */
221 1.1.1.6 christos 0, /* src_mask */
222 1.1.1.6 christos 0xffff, /* dst_mask */
223 1.1.1.7 christos false), /* pcrel_offset */
224 1.1.1.7 christos
225 1.1.1.7 christos BFD_HOWTO (BFD_RELOC_Z80_16_BE,
226 1.1.1.7 christos R_IMM16BE, /* type */
227 1.1.1.7 christos 0, /* rightshift */
228 1.1.1.7 christos 2, /* size */
229 1.1.1.7 christos 16, /* bitsize */
230 1.1.1.7 christos false, /* pc_relative */
231 1.1.1.7 christos 0, /* bitpos */
232 1.1.1.7 christos complain_overflow_bitfield, /* complain_on_overflow */
233 1.1.1.7 christos 0, /* special_function */
234 1.1.1.7 christos "r_imm16be", /* name */
235 1.1.1.7 christos false, /* partial_inplace */
236 1.1.1.7 christos 0x0000ffff, /* src_mask */
237 1.1.1.7 christos 0x0000ffff, /* dst_mask */
238 1.1.1.7 christos false), /* pcrel_offset */
239 1.1.1.6 christos };
240 1.1.1.6 christos
241 1.1.1.6 christos #define NUM_HOWTOS ARRAY_SIZE (howto_table)
242 1.1 skrll
243 1.1 skrll #define BADMAG(x) Z80BADMAG(x)
244 1.1 skrll #define Z80 1 /* Customize coffcode.h. */
245 1.1 skrll #define __A_MAGIC_SET__
246 1.1 skrll
247 1.1 skrll /* Code to swap in the reloc. */
248 1.1 skrll
249 1.1 skrll #define SWAP_IN_RELOC_OFFSET H_GET_32
250 1.1 skrll #define SWAP_OUT_RELOC_OFFSET H_PUT_32
251 1.1 skrll
252 1.1 skrll #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
253 1.1 skrll dst->r_stuff[0] = 'S'; \
254 1.1 skrll dst->r_stuff[1] = 'C';
255 1.1 skrll
256 1.1 skrll /* Code to turn a r_type into a howto ptr, uses the above howto table. */
257 1.1 skrll static void
258 1.1 skrll rtype2howto (arelent *internal, struct internal_reloc *dst)
259 1.1 skrll {
260 1.1.1.6 christos unsigned i;
261 1.1.1.6 christos for (i = 0; i < NUM_HOWTOS; i++)
262 1.1 skrll {
263 1.1.1.6 christos if (howto_table[i].howto.type == dst->r_type)
264 1.1.1.6 christos {
265 1.1.1.6 christos internal->howto = &howto_table[i].howto;
266 1.1.1.6 christos return;
267 1.1.1.6 christos }
268 1.1 skrll }
269 1.1.1.6 christos internal->howto = NULL;
270 1.1 skrll }
271 1.1 skrll
272 1.1 skrll #define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry)
273 1.1 skrll
274 1.1 skrll static reloc_howto_type *
275 1.1 skrll coff_z80_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
276 1.1 skrll bfd_reloc_code_real_type code)
277 1.1 skrll {
278 1.1.1.6 christos unsigned i;
279 1.1.1.6 christos for (i = 0; i < NUM_HOWTOS; i++)
280 1.1.1.6 christos if (howto_table[i].r_type == code)
281 1.1.1.6 christos return &howto_table[i].howto;
282 1.1.1.6 christos
283 1.1.1.6 christos BFD_FAIL ();
284 1.1.1.6 christos return NULL;
285 1.1 skrll }
286 1.1 skrll
287 1.1 skrll static reloc_howto_type *
288 1.1 skrll coff_z80_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
289 1.1 skrll const char *r_name)
290 1.1 skrll {
291 1.1.1.6 christos unsigned i;
292 1.1.1.6 christos for (i = 0; i < NUM_HOWTOS; i++)
293 1.1.1.6 christos if (strcasecmp(howto_table[i].howto.name, r_name) == 0)
294 1.1.1.6 christos return &howto_table[i].howto;
295 1.1 skrll
296 1.1 skrll return NULL;
297 1.1 skrll }
298 1.1 skrll
299 1.1 skrll /* Perform any necessary magic to the addend in a reloc entry. */
300 1.1 skrll
301 1.1 skrll #define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
302 1.1 skrll cache_ptr->addend = ext_reloc.r_offset;
303 1.1 skrll
304 1.1 skrll #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
305 1.1 skrll reloc_processing(relent, reloc, symbols, abfd, section)
306 1.1 skrll
307 1.1 skrll static void
308 1.1 skrll reloc_processing (arelent *relent,
309 1.1.1.5 christos struct internal_reloc *reloc,
310 1.1.1.5 christos asymbol **symbols,
311 1.1.1.5 christos bfd *abfd,
312 1.1.1.5 christos asection *section)
313 1.1 skrll {
314 1.1 skrll relent->address = reloc->r_vaddr;
315 1.1 skrll rtype2howto (relent, reloc);
316 1.1 skrll
317 1.1.1.8 christos if (reloc->r_symndx == -1 || symbols == NULL)
318 1.1.1.9 christos relent->sym_ptr_ptr = &bfd_abs_section_ptr->symbol;
319 1.1.1.7 christos else if (reloc->r_symndx >= 0 && reloc->r_symndx < obj_conv_table_size (abfd))
320 1.1 skrll relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
321 1.1 skrll else
322 1.1.1.7 christos {
323 1.1.1.7 christos _bfd_error_handler
324 1.1.1.7 christos /* xgettext:c-format */
325 1.1.1.7 christos (_("%pB: warning: illegal symbol index %ld in relocs"),
326 1.1.1.7 christos abfd, reloc->r_symndx);
327 1.1.1.9 christos relent->sym_ptr_ptr = &bfd_abs_section_ptr->symbol;
328 1.1.1.7 christos }
329 1.1 skrll relent->addend = reloc->r_offset;
330 1.1 skrll relent->address -= section->vma;
331 1.1 skrll }
332 1.1 skrll
333 1.1.1.8 christos static bool
334 1.1 skrll extra_case (bfd *in_abfd,
335 1.1.1.5 christos struct bfd_link_info *link_info,
336 1.1.1.5 christos struct bfd_link_order *link_order,
337 1.1.1.5 christos arelent *reloc,
338 1.1.1.5 christos bfd_byte *data,
339 1.1.1.8 christos size_t *src_ptr,
340 1.1.1.8 christos size_t *dst_ptr)
341 1.1 skrll {
342 1.1 skrll asection * input_section = link_order->u.indirect.section;
343 1.1.1.8 christos bfd_size_type end = bfd_get_section_limit_octets (in_abfd, input_section);
344 1.1.1.8 christos bfd_size_type reloc_size = bfd_get_reloc_size (reloc->howto);
345 1.1.1.8 christos
346 1.1.1.8 christos if (*src_ptr > end
347 1.1.1.8 christos || reloc_size > end - *src_ptr)
348 1.1.1.8 christos {
349 1.1.1.8 christos link_info->callbacks->einfo
350 1.1.1.8 christos /* xgettext:c-format */
351 1.1.1.8 christos (_("%X%P: %pB(%pA): relocation \"%pR\" goes out of range\n"),
352 1.1.1.8 christos in_abfd, input_section, reloc);
353 1.1.1.8 christos return false;
354 1.1.1.8 christos }
355 1.1 skrll
356 1.1.1.8 christos int val = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
357 1.1 skrll switch (reloc->howto->type)
358 1.1 skrll {
359 1.1 skrll case R_OFF8:
360 1.1.1.6 christos if (reloc->howto->partial_inplace)
361 1.1.1.8 christos val += (signed char) (bfd_get_8 (in_abfd, data + *src_ptr)
362 1.1.1.8 christos & reloc->howto->src_mask);
363 1.1.1.8 christos if (val > 127 || val < -128)
364 1.1.1.8 christos {
365 1.1.1.8 christos link_info->callbacks->reloc_overflow
366 1.1.1.4 christos (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr),
367 1.1.1.4 christos reloc->howto->name, reloc->addend, input_section->owner,
368 1.1.1.4 christos input_section, reloc->address);
369 1.1.1.8 christos return false;
370 1.1.1.8 christos }
371 1.1.1.4 christos
372 1.1.1.8 christos bfd_put_8 (in_abfd, val, data + *dst_ptr);
373 1.1.1.8 christos *dst_ptr += 1;
374 1.1.1.8 christos *src_ptr += 1;
375 1.1 skrll break;
376 1.1 skrll
377 1.1.1.6 christos case R_BYTE3:
378 1.1.1.6 christos bfd_put_8 (in_abfd, val >> 24, data + *dst_ptr);
379 1.1.1.8 christos *dst_ptr += 1;
380 1.1.1.8 christos *src_ptr += 1;
381 1.1.1.6 christos break;
382 1.1.1.6 christos
383 1.1.1.6 christos case R_BYTE2:
384 1.1.1.6 christos bfd_put_8 (in_abfd, val >> 16, data + *dst_ptr);
385 1.1.1.8 christos *dst_ptr += 1;
386 1.1.1.8 christos *src_ptr += 1;
387 1.1.1.6 christos break;
388 1.1.1.6 christos
389 1.1.1.6 christos case R_BYTE1:
390 1.1.1.6 christos bfd_put_8 (in_abfd, val >> 8, data + *dst_ptr);
391 1.1.1.8 christos *dst_ptr += 1;
392 1.1.1.8 christos *src_ptr += 1;
393 1.1.1.6 christos break;
394 1.1.1.6 christos
395 1.1 skrll case R_IMM8:
396 1.1.1.6 christos if (reloc->howto->partial_inplace)
397 1.1.1.8 christos val += bfd_get_8 (in_abfd, data + *src_ptr) & reloc->howto->src_mask;
398 1.1.1.7 christos /* Fall through. */
399 1.1.1.6 christos case R_BYTE0:
400 1.1 skrll bfd_put_8 (in_abfd, val, data + *dst_ptr);
401 1.1.1.8 christos *dst_ptr += 1;
402 1.1.1.8 christos *src_ptr += 1;
403 1.1 skrll break;
404 1.1 skrll
405 1.1.1.6 christos case R_WORD1:
406 1.1.1.6 christos bfd_put_16 (in_abfd, val >> 16, data + *dst_ptr);
407 1.1.1.8 christos *dst_ptr += 2;
408 1.1.1.8 christos *src_ptr += 2;
409 1.1.1.6 christos break;
410 1.1.1.6 christos
411 1.1 skrll case R_IMM16:
412 1.1.1.6 christos if (reloc->howto->partial_inplace)
413 1.1.1.8 christos val += bfd_get_16 (in_abfd, data + *src_ptr) & reloc->howto->src_mask;
414 1.1.1.7 christos /* Fall through. */
415 1.1.1.6 christos case R_WORD0:
416 1.1 skrll bfd_put_16 (in_abfd, val, data + *dst_ptr);
417 1.1.1.8 christos *dst_ptr += 2;
418 1.1.1.8 christos *src_ptr += 2;
419 1.1 skrll break;
420 1.1 skrll
421 1.1 skrll case R_IMM24:
422 1.1.1.6 christos if (reloc->howto->partial_inplace)
423 1.1.1.7 christos val += (bfd_get_24 (in_abfd, data + *src_ptr)
424 1.1.1.7 christos & reloc->howto->src_mask);
425 1.1.1.7 christos bfd_put_24 (in_abfd, val, data + *dst_ptr);
426 1.1.1.8 christos *dst_ptr += 3;
427 1.1.1.8 christos *src_ptr += 3;
428 1.1 skrll break;
429 1.1 skrll
430 1.1 skrll case R_IMM32:
431 1.1.1.6 christos if (reloc->howto->partial_inplace)
432 1.1.1.8 christos val += bfd_get_32 (in_abfd, data + *src_ptr) & reloc->howto->src_mask;
433 1.1 skrll bfd_put_32 (in_abfd, val, data + *dst_ptr);
434 1.1.1.8 christos *dst_ptr += 4;
435 1.1.1.8 christos *src_ptr += 4;
436 1.1 skrll break;
437 1.1 skrll
438 1.1 skrll case R_JR:
439 1.1 skrll {
440 1.1.1.8 christos if (reloc->howto->partial_inplace)
441 1.1.1.8 christos val += (signed char) (bfd_get_8 (in_abfd, data + *src_ptr)
442 1.1.1.8 christos & reloc->howto->src_mask);
443 1.1 skrll bfd_vma dot = (*dst_ptr
444 1.1 skrll + input_section->output_offset
445 1.1 skrll + input_section->output_section->vma);
446 1.1.1.8 christos bfd_signed_vma gap = val - dot;
447 1.1 skrll if (gap >= 128 || gap < -128)
448 1.1.1.8 christos {
449 1.1.1.8 christos link_info->callbacks->reloc_overflow
450 1.1.1.8 christos (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr),
451 1.1.1.8 christos reloc->howto->name, reloc->addend, input_section->owner,
452 1.1.1.8 christos input_section, reloc->address);
453 1.1.1.8 christos return false;
454 1.1.1.8 christos }
455 1.1.1.4 christos
456 1.1 skrll bfd_put_8 (in_abfd, gap, data + *dst_ptr);
457 1.1.1.8 christos *dst_ptr += 1;
458 1.1.1.8 christos *src_ptr += 1;
459 1.1 skrll break;
460 1.1 skrll }
461 1.1 skrll
462 1.1.1.7 christos case R_IMM16BE:
463 1.1.1.7 christos if (reloc->howto->partial_inplace)
464 1.1.1.8 christos val += ((bfd_get_8 (in_abfd, data + *src_ptr + 0) * 0x100
465 1.1.1.8 christos + bfd_get_8 (in_abfd, data + *src_ptr + 1))
466 1.1.1.8 christos & reloc->howto->src_mask);
467 1.1.1.7 christos
468 1.1.1.8 christos bfd_put_8 (in_abfd, val >> 8, data + *dst_ptr + 0);
469 1.1.1.8 christos bfd_put_8 (in_abfd, val, data + *dst_ptr + 1);
470 1.1.1.8 christos *dst_ptr += 2;
471 1.1.1.8 christos *src_ptr += 2;
472 1.1.1.7 christos break;
473 1.1.1.7 christos
474 1.1 skrll default:
475 1.1.1.8 christos link_info->callbacks->einfo
476 1.1.1.8 christos /* xgettext:c-format */
477 1.1.1.8 christos (_("%X%P: %pB(%pA): relocation \"%pR\" is not supported\n"),
478 1.1.1.8 christos in_abfd, input_section, reloc);
479 1.1.1.8 christos return false;
480 1.1 skrll }
481 1.1.1.8 christos return true;
482 1.1 skrll }
483 1.1 skrll
484 1.1.1.7 christos static bool
485 1.1.1.6 christos z80_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
486 1.1.1.6 christos const char * name)
487 1.1.1.6 christos {
488 1.1.1.6 christos return (name[0] == '.' && name[1] == 'L') ||
489 1.1.1.6 christos _bfd_coff_is_local_label_name (abfd, name);
490 1.1.1.6 christos }
491 1.1.1.6 christos
492 1.1.1.6 christos #define coff_bfd_is_local_label_name z80_is_local_label_name
493 1.1.1.6 christos
494 1.1 skrll #define coff_reloc16_extra_cases extra_case
495 1.1 skrll #define coff_bfd_reloc_type_lookup coff_z80_reloc_type_lookup
496 1.1 skrll #define coff_bfd_reloc_name_lookup coff_z80_reloc_name_lookup
497 1.1 skrll
498 1.1 skrll #ifndef bfd_pe_print_pdata
499 1.1 skrll #define bfd_pe_print_pdata NULL
500 1.1 skrll #endif
501 1.1 skrll
502 1.1 skrll #include "coffcode.h"
503 1.1 skrll
504 1.1 skrll #undef coff_bfd_get_relocated_section_contents
505 1.1 skrll #define coff_bfd_get_relocated_section_contents \
506 1.1 skrll bfd_coff_reloc16_get_relocated_section_contents
507 1.1 skrll
508 1.1 skrll #undef coff_bfd_relax_section
509 1.1 skrll #define coff_bfd_relax_section bfd_coff_reloc16_relax_section
510 1.1 skrll
511 1.1.1.3 christos CREATE_LITTLE_COFF_TARGET_VEC (z80_coff_vec, "coff-z80", 0,
512 1.1.1.3 christos SEC_CODE | SEC_DATA, '\0', NULL,
513 1.1 skrll COFF_SWAP_TABLE)
514 1.1 skrll
515