arm: PR gas/25472 Enable DSP instructions with +mve
[binutils-gdb.git] / bfd / elf32-z80.c
blob888606e7b5cc4bf643668424d51203340dd34530
1 /* Zilog (e)Z80-specific support for 32-bit ELF
2 Copyright (C) 1999-2019 Free Software Foundation, Inc.
3 (Heavily copied from the S12Z port by Sergey Belyashov (sergey.belyashov@gmail.com))
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
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.
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. */
22 #include "sysdep.h"
23 #include "bfd.h"
24 #include "bfdlink.h"
25 #include "libbfd.h"
26 #include "elf-bfd.h"
28 #include "elf/z80.h"
30 /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */
31 #define OCTETS_PER_BYTE(ABFD, SEC) 1
33 /* Relocation functions. */
34 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
35 (bfd *, bfd_reloc_code_real_type);
36 static bfd_boolean z80_info_to_howto_rel
37 (bfd *, arelent *, Elf_Internal_Rela *);
39 typedef struct {
40 bfd_reloc_code_real_type r_type;
41 reloc_howto_type howto;
42 } bfd_howto_type;
44 #define BFD_EMPTY_HOWTO(rt,x) {rt, EMPTY_HOWTO(x)}
45 #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)}
47 static const
48 bfd_howto_type elf_z80_howto_table[] =
50 /* This reloc does nothing. */
51 BFD_HOWTO (BFD_RELOC_NONE,
52 R_Z80_NONE, /* type */
53 0, /* rightshift */
54 3, /* size (0 = byte, 1 = short, 2 = long) */
55 0, /* bitsize */
56 FALSE, /* pc_relative */
57 0, /* bitpos */
58 complain_overflow_dont,/* complain_on_overflow */
59 bfd_elf_generic_reloc, /* special_function */
60 "R_NONE", /* name */
61 FALSE, /* partial_inplace */
62 0, /* src_mask */
63 0, /* dst_mask */
64 FALSE), /* pcrel_offset */
66 /* A 8 bit relocation */
67 BFD_HOWTO (BFD_RELOC_8,
68 R_Z80_8, /* type */
69 0, /* rightshift */
70 0, /* size (0 = byte, 1 = short, 2 = long) */
71 8, /* bitsize */
72 FALSE, /* pc_relative */
73 0, /* bitpos */
74 complain_overflow_bitfield, /* complain_on_overflow */
75 bfd_elf_generic_reloc, /* special_function */
76 "r_imm8", /* name */
77 FALSE, /* partial_inplace */
78 0x00, /* src_mask */
79 0xff, /* dst_mask */
80 FALSE), /* pcrel_offset */
82 /* A 8 bit index register displacement relocation */
83 BFD_HOWTO (BFD_RELOC_Z80_DISP8,
84 R_Z80_8_DIS, /* type */
85 0, /* rightshift */
86 0, /* size (0 = byte, 1 = short, 2 = long) */
87 8, /* bitsize */
88 FALSE, /* pc_relative */
89 0, /* bitpos */
90 complain_overflow_signed, /* complain_on_overflow */
91 bfd_elf_generic_reloc, /* special_function */
92 "r_off", /* name */
93 FALSE, /* partial_inplace */
94 0x00, /* src_mask */
95 0xff, /* dst_mask */
96 FALSE), /* pcrel_offset */
98 /* A 8 bit PC-rel relocation */
99 BFD_HOWTO (BFD_RELOC_8_PCREL,
100 R_Z80_8_PCREL, /* type */
101 0, /* rightshift */
102 0, /* size (0 = byte, 1 = short, 2 = long) */
103 8, /* bitsize */
104 TRUE, /* pc_relative */
105 0, /* bitpos */
106 complain_overflow_signed, /* complain_on_overflow */
107 bfd_elf_generic_reloc, /* special_function */
108 "r_jr", /* name */
109 FALSE, /* partial_inplace */
110 0x00, /* src_mask */
111 0xff, /* dst_mask */
112 TRUE), /* pcrel_offset */
114 /* An 16 bit absolute relocation */
115 BFD_HOWTO (BFD_RELOC_16,
116 R_Z80_16, /* type */
117 0, /* rightshift */
118 1, /* size (0 = byte, 1 = short, 2 = long) */
119 16, /* bitsize */
120 FALSE, /* pc_relative */
121 0, /* bitpos */
122 complain_overflow_bitfield, /* complain_on_overflow */
123 bfd_elf_generic_reloc, /* special_function */
124 "r_imm16", /* name */
125 FALSE, /* partial_inplace */
126 0x00000000, /* src_mask */
127 0x0000ffff, /* dst_mask */
128 FALSE), /* pcrel_offset */
130 /* A 24 bit absolute relocation emitted by ADL mode operands */
131 BFD_HOWTO (BFD_RELOC_24,
132 R_Z80_24, /* type */
133 0, /* rightshift */
134 5, /* size (0 = byte, 1 = short, 2 = long) */
135 24, /* bitsize */
136 FALSE, /* pc_relative */
137 0, /* bitpos */
138 complain_overflow_bitfield, /* complain_on_overflow */
139 bfd_elf_generic_reloc, /* special_function */
140 "r_imm24", /* name */
141 FALSE, /* partial_inplace */
142 0x00000000, /* src_mask */
143 0x00ffffff, /* dst_mask */
144 FALSE), /* pcrel_offset */
146 BFD_HOWTO (BFD_RELOC_32,
147 R_Z80_32, /* type */
148 0, /* rightshift */
149 2, /* size (0 = byte, 1 = short, 2 = long) */
150 32, /* bitsize */
151 FALSE, /* pc_relative */
152 0, /* bitpos */
153 complain_overflow_dont,/* complain_on_overflow */
154 bfd_elf_generic_reloc, /* special_function */
155 "r_imm32", /* name */
156 FALSE, /* partial_inplace */
157 0x00000000, /* src_mask */
158 0xffffffff, /* dst_mask */
159 FALSE), /* pcrel_offset */
161 /* First (lowest) 8 bits of multibyte relocation */
162 BFD_HOWTO (BFD_RELOC_Z80_BYTE0,
163 R_Z80_BYTE0, /* type */
164 0, /* rightshift */
165 0, /* size (0 = byte, 1 = short, 2 = long) */
166 32, /* bitsize */
167 FALSE, /* pc_relative */
168 0, /* bitpos */
169 complain_overflow_dont,/* complain_on_overflow */
170 bfd_elf_generic_reloc, /* special_function */
171 "r_byte0", /* name */
172 FALSE, /* partial_inplace */
173 0, /* src_mask */
174 0xff, /* dst_mask */
175 FALSE), /* pcrel_offset */
177 /* Second 8 bits of multibyte relocation */
178 BFD_HOWTO (BFD_RELOC_Z80_BYTE1,
179 R_Z80_BYTE1, /* type */
180 8, /* rightshift */
181 0, /* size (0 = byte, 1 = short, 2 = long) */
182 32, /* bitsize */
183 FALSE, /* pc_relative */
184 0, /* bitpos */
185 complain_overflow_dont,/* complain_on_overflow */
186 bfd_elf_generic_reloc, /* special_function */
187 "r_byte1", /* name */
188 FALSE, /* partial_inplace */
189 0, /* src_mask */
190 0xff, /* dst_mask */
191 FALSE), /* pcrel_offset */
193 /* Third 8 bits of multibyte relocation */
194 BFD_HOWTO (BFD_RELOC_Z80_BYTE2,
195 R_Z80_BYTE2, /* type */
196 16, /* rightshift */
197 0, /* size (0 = byte, 1 = short, 2 = long) */
198 32, /* bitsize */
199 FALSE, /* pc_relative */
200 0, /* bitpos */
201 complain_overflow_dont,/* complain_on_overflow */
202 bfd_elf_generic_reloc, /* special_function */
203 "r_byte2", /* name */
204 FALSE, /* partial_inplace */
205 0, /* src_mask */
206 0xff, /* dst_mask */
207 FALSE), /* pcrel_offset */
209 /* Fourth (highest) 8 bits of multibyte relocation */
210 BFD_HOWTO (BFD_RELOC_Z80_BYTE3,
211 R_Z80_BYTE3, /* type */
212 24, /* rightshift */
213 0, /* size (0 = byte, 1 = short, 2 = long) */
214 32, /* bitsize */
215 FALSE, /* pc_relative */
216 0, /* bitpos */
217 complain_overflow_dont,/* complain_on_overflow */
218 bfd_elf_generic_reloc, /* special_function */
219 "r_byte3", /* name */
220 FALSE, /* partial_inplace */
221 0, /* src_mask */
222 0xff, /* dst_mask */
223 FALSE), /* pcrel_offset */
225 /* An 16 bit absolute relocation of lower word of multibyte value */
226 BFD_HOWTO (BFD_RELOC_Z80_WORD0,
227 R_Z80_WORD0, /* type */
228 0, /* rightshift */
229 1, /* size (0 = byte, 1 = short, 2 = long) */
230 32, /* bitsize */
231 FALSE, /* pc_relative */
232 0, /* bitpos */
233 complain_overflow_dont,/* complain_on_overflow */
234 bfd_elf_generic_reloc, /* special_function */
235 "r_word0", /* name */
236 FALSE, /* partial_inplace */
237 0, /* src_mask */
238 0xffff, /* dst_mask */
239 FALSE), /* pcrel_offset */
241 /* An 16 bit absolute relocation of higher word of multibyte value */
242 BFD_HOWTO (BFD_RELOC_Z80_WORD1,
243 R_Z80_WORD1, /* type */
244 16, /* rightshift */
245 1, /* size (0 = byte, 1 = short, 2 = long) */
246 32, /* bitsize */
247 FALSE, /* pc_relative */
248 0, /* bitpos */
249 complain_overflow_dont,/* complain_on_overflow */
250 bfd_elf_generic_reloc, /* special_function */
251 "r_word1", /* name */
252 FALSE, /* partial_inplace */
253 0, /* src_mask */
254 0xffff, /* dst_mask */
255 FALSE), /* pcrel_offset */
258 static reloc_howto_type *
259 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
260 bfd_reloc_code_real_type code)
262 enum
264 table_size = sizeof (elf_z80_howto_table) / sizeof (elf_z80_howto_table[0])
266 unsigned int i;
268 for (i = 0; i < table_size; i++)
270 if (elf_z80_howto_table[i].r_type == code)
271 return &elf_z80_howto_table[i].howto;
274 printf ("%s:%d Not found type %d\n", __FILE__, __LINE__, code);
276 return NULL;
279 static reloc_howto_type *
280 bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
282 enum
284 table_size = sizeof (elf_z80_howto_table) / sizeof (elf_z80_howto_table[0])
286 unsigned int i;
288 for (i = 0; i < table_size; i++)
290 if (elf_z80_howto_table[i].howto.name != NULL
291 && strcasecmp (elf_z80_howto_table[i].howto.name, r_name) == 0)
292 return &elf_z80_howto_table[i].howto;
295 return NULL;
298 /* Set the howto pointer for an z80 ELF reloc. */
300 static bfd_boolean
301 z80_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
303 enum
305 table_size = sizeof (elf_z80_howto_table) / sizeof (elf_z80_howto_table[0])
307 unsigned int i;
308 unsigned int r_type = ELF32_R_TYPE (dst->r_info);
310 for (i = 0; i < table_size; i++)
312 if (elf_z80_howto_table[i].howto.type == r_type)
314 cache_ptr->howto = &elf_z80_howto_table[i].howto;
315 return TRUE;
319 /* xgettext:c-format */
320 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
321 abfd, r_type);
322 bfd_set_error (bfd_error_bad_value);
323 return FALSE;
326 static bfd_boolean
327 z80_elf_set_mach_from_flags (bfd *abfd)
329 int mach;
330 switch (elf_elfheader (abfd)->e_flags)
332 case EF_Z80_MACH_GBZ80:
333 mach = bfd_mach_gbz80;
334 break;
335 case EF_Z80_MACH_Z80:
336 mach = bfd_mach_z80;
337 break;
338 case EF_Z80_MACH_Z180:
339 mach = bfd_mach_z180;
340 break;
341 case EF_Z80_MACH_EZ80_Z80:
342 mach = bfd_mach_ez80_z80;
343 break;
344 case EF_Z80_MACH_EZ80_ADL:
345 mach = bfd_mach_ez80_adl;
346 break;
347 case EF_Z80_MACH_R800:
348 mach = bfd_mach_r800;
349 break;
350 default:
351 mach = bfd_mach_z80;
352 break;
355 bfd_default_set_arch_mach (abfd, bfd_arch_z80, mach);
356 return TRUE;
359 static int
360 z80_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
361 const char * name)
363 return (name[0] == '.' && name[1] == 'L') ||
364 _bfd_elf_is_local_label_name (abfd, name);
368 #define ELF_ARCH bfd_arch_z80
369 #define ELF_MACHINE_CODE EM_Z80
370 #define ELF_MAXPAGESIZE 0x10000
372 #define TARGET_LITTLE_SYM z80_elf32_vec
373 #define TARGET_LITTLE_NAME "elf32-z80"
375 #define elf_info_to_howto NULL
376 #define elf_info_to_howto_rel z80_info_to_howto_rel
377 #define elf_backend_object_p z80_elf_set_mach_from_flags
378 #define bfd_elf32_bfd_is_local_label_name z80_is_local_label_name
380 #include "elf32-target.h"