]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/coff-z8k.c
gdb/testsuite: Add gdb.arch/aarch64-mops-watchpoint.exp
[thirdparty/binutils-gdb.git] / bfd / coff-z8k.c
CommitLineData
252b5132 1/* BFD back-end for Zilog Z800n COFF binaries.
fd67aa11 2 Copyright (C) 1992-2024 Free Software Foundation, Inc.
252b5132
RH
3 Contributed by Cygnus Support.
4 Written by Steve Chamberlain, <sac@cygnus.com>.
5
c0524131 6 This file is part of BFD, the Binary File Descriptor library.
252b5132 7
c0524131
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
c0524131 11 (at your option) any later version.
252b5132 12
c0524131
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
c0524131
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/z8k.h"
28#include "coff/internal.h"
29#include "libcoff.h"
30
31#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
32
33static reloc_howto_type r_imm32 =
c94cb026 34HOWTO (R_IMM32, 0, 4, 32, false, 0,
0a1b45a2
AM
35 complain_overflow_bitfield, 0, "r_imm32", true, 0xffffffff,
36 0xffffffff, false);
252b5132
RH
37
38static reloc_howto_type r_imm4l =
c94cb026 39HOWTO (R_IMM4L, 0, 1, 4, false, 0,
0a1b45a2 40 complain_overflow_bitfield, 0, "r_imm4l", true, 0xf, 0xf, false);
252b5132
RH
41
42static reloc_howto_type r_da =
c94cb026 43HOWTO (R_IMM16, 0, 2, 16, false, 0,
0a1b45a2
AM
44 complain_overflow_bitfield, 0, "r_da", true, 0x0000ffff, 0x0000ffff,
45 false);
252b5132
RH
46
47static reloc_howto_type r_imm8 =
c94cb026 48HOWTO (R_IMM8, 0, 1, 8, false, 0,
0a1b45a2
AM
49 complain_overflow_bitfield, 0, "r_imm8", true, 0x000000ff, 0x000000ff,
50 false);
252b5132 51
6840198f 52static reloc_howto_type r_rel16 =
c94cb026 53HOWTO (R_REL16, 0, 2, 16, false, 0,
0a1b45a2
AM
54 complain_overflow_bitfield, 0, "r_rel16", true, 0x0000ffff, 0x0000ffff,
55 true);
6840198f 56
252b5132 57static reloc_howto_type r_jr =
c94cb026 58HOWTO (R_JR, 1, 1, 8, true, 0, complain_overflow_signed, 0,
0a1b45a2 59 "r_jr", true, 0xff, 0xff, true);
252b5132 60
6840198f 61static reloc_howto_type r_disp7 =
c94cb026 62HOWTO (R_DISP7, 0, 1, 7, true, 0, complain_overflow_bitfield, 0,
0a1b45a2 63 "r_disp7", true, 0x7f, 0x7f, true);
6840198f
NC
64
65static reloc_howto_type r_callr =
c94cb026 66HOWTO (R_CALLR, 1, 2, 12, true, 0, complain_overflow_signed, 0,
0a1b45a2 67 "r_callr", true, 0xfff, 0xfff, true);
6840198f 68
252b5132 69#define BADMAG(x) Z8KBADMAG(x)
c0524131 70#define Z8K 1 /* Customize coffcode.h. */
252b5132
RH
71#define __A_MAGIC_SET__
72
f4ffd778 73/* Code to swap in the reloc. */
dc810e39
AM
74#define SWAP_IN_RELOC_OFFSET H_GET_32
75#define SWAP_OUT_RELOC_OFFSET H_PUT_32
252b5132
RH
76#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
77 dst->r_stuff[0] = 'S'; \
78 dst->r_stuff[1] = 'C';
79
f4ffd778 80/* Code to turn a r_type into a howto ptr, uses the above howto table. */
252b5132
RH
81
82static void
552585ed 83rtype2howto (arelent *internal, struct internal_reloc *dst)
252b5132
RH
84{
85 switch (dst->r_type)
86 {
87 default:
a1165289 88 internal->howto = NULL;
252b5132
RH
89 break;
90 case R_IMM8:
91 internal->howto = &r_imm8;
92 break;
93 case R_IMM16:
94 internal->howto = &r_da;
95 break;
96 case R_JR:
97 internal->howto = &r_jr;
98 break;
6840198f
NC
99 case R_DISP7:
100 internal->howto = &r_disp7;
101 break;
102 case R_CALLR:
103 internal->howto = &r_callr;
104 break;
105 case R_REL16:
106 internal->howto = &r_rel16;
107 break;
252b5132
RH
108 case R_IMM32:
109 internal->howto = &r_imm32;
110 break;
111 case R_IMM4L:
112 internal->howto = &r_imm4l;
113 break;
114 }
115}
116
f4ffd778 117#define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry)
252b5132 118
c0524131
NC
119static reloc_howto_type *
120coff_z8k_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
07d6d2b8 121 bfd_reloc_code_real_type code)
c0524131
NC
122{
123 switch (code)
124 {
07d6d2b8
AM
125 case BFD_RELOC_8: return & r_imm8;
126 case BFD_RELOC_16: return & r_da;
127 case BFD_RELOC_32: return & r_imm32;
128 case BFD_RELOC_8_PCREL: return & r_jr;
129 case BFD_RELOC_16_PCREL: return & r_rel16;
130 case BFD_RELOC_Z8K_DISP7: return & r_disp7;
131 case BFD_RELOC_Z8K_CALLR: return & r_callr;
132 case BFD_RELOC_Z8K_IMM4L: return & r_imm4l;
c0524131
NC
133 default: BFD_FAIL ();
134 return 0;
135 }
136}
137
157090f7
AM
138static reloc_howto_type *
139coff_z8k_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
140 const char *r_name)
141{
142 if (strcasecmp (r_imm8.name, r_name) == 0)
143 return &r_imm8;
144 if (strcasecmp (r_da.name, r_name) == 0)
145 return &r_da;
146 if (strcasecmp (r_imm32.name, r_name) == 0)
147 return &r_imm32;
148 if (strcasecmp (r_jr.name, r_name) == 0)
149 return &r_jr;
150 if (strcasecmp (r_rel16.name, r_name) == 0)
151 return &r_rel16;
152 if (strcasecmp (r_disp7.name, r_name) == 0)
153 return &r_disp7;
154 if (strcasecmp (r_callr.name, r_name) == 0)
155 return &r_callr;
156 if (strcasecmp (r_imm4l.name, r_name) == 0)
157 return &r_imm4l;
158
159 return NULL;
160}
161
f4ffd778 162/* Perform any necessary magic to the addend in a reloc entry. */
252b5132 163
252b5132
RH
164#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
165 cache_ptr->addend = ext_reloc.r_offset;
166
252b5132
RH
167#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
168 reloc_processing(relent, reloc, symbols, abfd, section)
169
cbfe05c4 170static void
552585ed 171reloc_processing (arelent *relent,
07d6d2b8
AM
172 struct internal_reloc *reloc,
173 asymbol **symbols,
174 bfd *abfd,
175 asection *section)
252b5132
RH
176{
177 relent->address = reloc->r_vaddr;
178 rtype2howto (relent, reloc);
179
e6b6fad2 180 if (reloc->r_symndx == -1 || symbols == NULL)
e039f7ed
AM
181 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
182 else if (reloc->r_symndx >= 0 && reloc->r_symndx < obj_conv_table_size (abfd))
879db8be 183 relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
252b5132 184 else
e039f7ed
AM
185 {
186 _bfd_error_handler
187 /* xgettext:c-format */
188 (_("%pB: warning: illegal symbol index %ld in relocs"),
189 abfd, reloc->r_symndx);
190 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
191 }
252b5132
RH
192 relent->addend = reloc->r_offset;
193 relent->address -= section->vma;
194}
195
d64c8f71 196static bool
552585ed 197extra_case (bfd *in_abfd,
07d6d2b8
AM
198 struct bfd_link_info *link_info,
199 struct bfd_link_order *link_order,
200 arelent *reloc,
201 bfd_byte *data,
d64c8f71
AM
202 size_t *src_ptr,
203 size_t *dst_ptr)
252b5132 204{
879db8be 205 asection * input_section = link_order->u.indirect.section;
d64c8f71
AM
206 bfd_size_type end = bfd_get_section_limit_octets (in_abfd, input_section);
207 bfd_size_type reloc_size = bfd_get_reloc_size (reloc->howto);
208
209 if (*src_ptr > end
210 || reloc_size > end - *src_ptr)
211 {
212 link_info->callbacks->einfo
213 /* xgettext:c-format */
214 (_("%X%P: %pB(%pA): relocation \"%pR\" goes out of range\n"),
215 in_abfd, input_section, reloc);
216 return false;
217 }
252b5132
RH
218
219 switch (reloc->howto->type)
220 {
221 case R_IMM8:
222 bfd_put_8 (in_abfd,
223 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
224 data + *dst_ptr);
d64c8f71
AM
225 *dst_ptr += 1;
226 *src_ptr += 1;
252b5132
RH
227 break;
228
229 case R_IMM32:
3c25c5f6
NC
230 /* If no flags are set, assume immediate value. */
231 if (! (*reloc->sym_ptr_ptr)->section->flags)
232 {
233 bfd_put_32 (in_abfd,
234 bfd_coff_reloc16_get_value (reloc, link_info,
235 input_section),
236 data + *dst_ptr);
237 }
238 else
239 {
240 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
241 input_section);
5c4491d3 242 /* Addresses are 23 bit, and the layout of those in a 32-bit
3c25c5f6
NC
243 value is as follows:
244 1AAAAAAA xxxxxxxx AAAAAAAA AAAAAAAA
245 (A - address bits, x - ignore). */
246 dst = (dst & 0xffff) | ((dst & 0xff0000) << 8) | 0x80000000;
247 bfd_put_32 (in_abfd, dst, data + *dst_ptr);
248 }
d64c8f71
AM
249 *dst_ptr += 4;
250 *src_ptr += 4;
252b5132
RH
251 break;
252
253 case R_IMM4L:
254 bfd_put_8 (in_abfd,
cbfe05c4 255 ((bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0)
d64c8f71
AM
256 | (0x0f & bfd_coff_reloc16_get_value (reloc, link_info,
257 input_section))),
252b5132 258 data + *dst_ptr);
d64c8f71
AM
259 *dst_ptr += 1;
260 *src_ptr += 1;
252b5132
RH
261 break;
262
263 case R_IMM16:
264 bfd_put_16 (in_abfd,
265 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
266 data + *dst_ptr);
d64c8f71
AM
267 *dst_ptr += 2;
268 *src_ptr += 2;
252b5132
RH
269 break;
270
271 case R_JR:
272 {
273 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
274 input_section);
44da2da1
AM
275 bfd_vma dot = (*dst_ptr
276 + input_section->output_offset
252b5132 277 + input_section->output_section->vma);
d64c8f71
AM
278 /* -1, since we're in the odd byte of the word and the pc has
279 been incremented. */
280 bfd_signed_vma gap = dst - dot - 1;
281
282 if ((gap & 1) != 0 || gap > 254 || gap < -256)
283 {
284 link_info->callbacks->reloc_overflow
285 (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr),
286 reloc->howto->name, reloc->addend, input_section->owner,
287 input_section, reloc->address);
288 return false;
289 }
290
291 bfd_put_8 (in_abfd, gap / 2, data + *dst_ptr);
292 *dst_ptr += 1;
293 *src_ptr += 1;
252b5132
RH
294 break;
295 }
6840198f
NC
296
297 case R_DISP7:
298 {
299 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
300 input_section);
44da2da1
AM
301 bfd_vma dot = (*dst_ptr
302 + input_section->output_offset
6840198f 303 + input_section->output_section->vma);
d64c8f71 304 bfd_signed_vma gap = dst - dot - 1;
6840198f 305
d64c8f71
AM
306 if ((gap & 1) != 0 || gap > 0 || gap < -254)
307 {
308 link_info->callbacks->reloc_overflow
309 (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr),
310 reloc->howto->name, reloc->addend, input_section->owner,
311 input_section, reloc->address);
312 return false;
313 }
1a72702b 314
6840198f 315 bfd_put_8 (in_abfd,
d64c8f71
AM
316 ((bfd_get_8 (in_abfd, data + *dst_ptr) & 0x80)
317 + (-gap / 2 & 0x7f)),
07d6d2b8 318 data + *dst_ptr);
d64c8f71
AM
319 *dst_ptr += 1;
320 *src_ptr += 1;
6840198f
NC
321 break;
322 }
323
324 case R_CALLR:
325 {
326 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
327 input_section);
44da2da1
AM
328 bfd_vma dot = (*dst_ptr
329 + input_section->output_offset
6840198f 330 + input_section->output_section->vma);
d64c8f71 331 bfd_signed_vma gap = dst - dot - 2;
6840198f 332
d64c8f71
AM
333 if ((gap & 1) != 0 || gap > 4096 || gap < -4095)
334 {
335 link_info->callbacks->reloc_overflow
336 (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr),
337 reloc->howto->name, reloc->addend, input_section->owner,
338 input_section, reloc->address);
339 return false;
340 }
1a72702b 341
6840198f 342 bfd_put_16 (in_abfd,
d64c8f71
AM
343 ((bfd_get_16 (in_abfd, data + *dst_ptr) & 0xf000)
344 | (-gap / 2 & 0x0fff)),
07d6d2b8 345 data + *dst_ptr);
d64c8f71
AM
346 *dst_ptr += 2;
347 *src_ptr += 2;
6840198f
NC
348 break;
349 }
350
351 case R_REL16:
352 {
353 bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
354 input_section);
44da2da1
AM
355 bfd_vma dot = (*dst_ptr
356 + input_section->output_offset
6840198f 357 + input_section->output_section->vma);
d64c8f71 358 bfd_signed_vma gap = dst - dot - 2;
6840198f
NC
359
360 if (gap > 32767 || gap < -32768)
d64c8f71
AM
361 {
362 link_info->callbacks->reloc_overflow
363 (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr),
364 reloc->howto->name, reloc->addend, input_section->owner,
365 input_section, reloc->address);
366 return false;
367 }
368
369 bfd_put_16 (in_abfd, gap, data + *dst_ptr);
370 *dst_ptr += 2;
371 *src_ptr += 2;
6840198f
NC
372 break;
373 }
879db8be 374
252b5132 375 default:
d64c8f71
AM
376 link_info->callbacks->einfo
377 /* xgettext:c-format */
378 (_("%X%P: %pB(%pA): relocation \"%pR\" is not supported\n"),
379 in_abfd, input_section, reloc);
380 return false;
252b5132 381 }
d64c8f71 382 return true;
252b5132
RH
383}
384
c0524131
NC
385#define coff_reloc16_extra_cases extra_case
386#define coff_bfd_reloc_type_lookup coff_z8k_reloc_type_lookup
157090f7 387#define coff_bfd_reloc_name_lookup coff_z8k_reloc_name_lookup
252b5132 388
2b5c217d
NC
389#ifndef bfd_pe_print_pdata
390#define bfd_pe_print_pdata NULL
391#endif
392
252b5132
RH
393#include "coffcode.h"
394
252b5132 395#undef coff_bfd_get_relocated_section_contents
252b5132
RH
396#define coff_bfd_get_relocated_section_contents \
397 bfd_coff_reloc16_get_relocated_section_contents
c0524131
NC
398
399#undef coff_bfd_relax_section
252b5132
RH
400#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
401
6d00b590 402CREATE_BIG_COFF_TARGET_VEC (z8k_coff_vec, "coff-z8k", 0, 0, '_', NULL, COFF_SWAP_TABLE)