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. */
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
*);
40 bfd_reloc_code_real_type r_type
;
41 reloc_howto_type howto
;
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)}
48 bfd_howto_type elf_z80_howto_table
[] =
50 /* This reloc does nothing. */
51 BFD_HOWTO (BFD_RELOC_NONE
,
52 R_Z80_NONE
, /* type */
54 3, /* size (0 = byte, 1 = short, 2 = long) */
56 FALSE
, /* pc_relative */
58 complain_overflow_dont
,/* complain_on_overflow */
59 bfd_elf_generic_reloc
, /* special_function */
61 FALSE
, /* partial_inplace */
64 FALSE
), /* pcrel_offset */
66 /* A 8 bit relocation */
67 BFD_HOWTO (BFD_RELOC_8
,
70 0, /* size (0 = byte, 1 = short, 2 = long) */
72 FALSE
, /* pc_relative */
74 complain_overflow_bitfield
, /* complain_on_overflow */
75 bfd_elf_generic_reloc
, /* special_function */
77 FALSE
, /* partial_inplace */
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 */
86 0, /* size (0 = byte, 1 = short, 2 = long) */
88 FALSE
, /* pc_relative */
90 complain_overflow_signed
, /* complain_on_overflow */
91 bfd_elf_generic_reloc
, /* special_function */
93 FALSE
, /* partial_inplace */
96 FALSE
), /* pcrel_offset */
98 /* A 8 bit PC-rel relocation */
99 BFD_HOWTO (BFD_RELOC_8_PCREL
,
100 R_Z80_8_PCREL
, /* type */
102 0, /* size (0 = byte, 1 = short, 2 = long) */
104 TRUE
, /* pc_relative */
106 complain_overflow_signed
, /* complain_on_overflow */
107 bfd_elf_generic_reloc
, /* special_function */
109 FALSE
, /* partial_inplace */
112 TRUE
), /* pcrel_offset */
114 /* An 16 bit absolute relocation */
115 BFD_HOWTO (BFD_RELOC_16
,
118 1, /* size (0 = byte, 1 = short, 2 = long) */
120 FALSE
, /* pc_relative */
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
,
134 5, /* size (0 = byte, 1 = short, 2 = long) */
136 FALSE
, /* pc_relative */
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
,
149 2, /* size (0 = byte, 1 = short, 2 = long) */
151 FALSE
, /* pc_relative */
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 */
165 0, /* size (0 = byte, 1 = short, 2 = long) */
167 FALSE
, /* pc_relative */
169 complain_overflow_dont
,/* complain_on_overflow */
170 bfd_elf_generic_reloc
, /* special_function */
171 "r_byte0", /* name */
172 FALSE
, /* partial_inplace */
175 FALSE
), /* pcrel_offset */
177 /* Second 8 bits of multibyte relocation */
178 BFD_HOWTO (BFD_RELOC_Z80_BYTE1
,
179 R_Z80_BYTE1
, /* type */
181 0, /* size (0 = byte, 1 = short, 2 = long) */
183 FALSE
, /* pc_relative */
185 complain_overflow_dont
,/* complain_on_overflow */
186 bfd_elf_generic_reloc
, /* special_function */
187 "r_byte1", /* name */
188 FALSE
, /* partial_inplace */
191 FALSE
), /* pcrel_offset */
193 /* Third 8 bits of multibyte relocation */
194 BFD_HOWTO (BFD_RELOC_Z80_BYTE2
,
195 R_Z80_BYTE2
, /* type */
197 0, /* size (0 = byte, 1 = short, 2 = long) */
199 FALSE
, /* pc_relative */
201 complain_overflow_dont
,/* complain_on_overflow */
202 bfd_elf_generic_reloc
, /* special_function */
203 "r_byte2", /* name */
204 FALSE
, /* partial_inplace */
207 FALSE
), /* pcrel_offset */
209 /* Fourth (highest) 8 bits of multibyte relocation */
210 BFD_HOWTO (BFD_RELOC_Z80_BYTE3
,
211 R_Z80_BYTE3
, /* type */
213 0, /* size (0 = byte, 1 = short, 2 = long) */
215 FALSE
, /* pc_relative */
217 complain_overflow_dont
,/* complain_on_overflow */
218 bfd_elf_generic_reloc
, /* special_function */
219 "r_byte3", /* name */
220 FALSE
, /* partial_inplace */
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 */
229 1, /* size (0 = byte, 1 = short, 2 = long) */
231 FALSE
, /* pc_relative */
233 complain_overflow_dont
,/* complain_on_overflow */
234 bfd_elf_generic_reloc
, /* special_function */
235 "r_word0", /* name */
236 FALSE
, /* partial_inplace */
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 */
245 1, /* size (0 = byte, 1 = short, 2 = long) */
247 FALSE
, /* pc_relative */
249 complain_overflow_dont
,/* complain_on_overflow */
250 bfd_elf_generic_reloc
, /* special_function */
251 "r_word1", /* name */
252 FALSE
, /* partial_inplace */
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
)
264 table_size
= sizeof (elf_z80_howto_table
) / sizeof (elf_z80_howto_table
[0])
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
);
279 static reloc_howto_type
*
280 bfd_elf32_bfd_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
, const char *r_name
)
284 table_size
= sizeof (elf_z80_howto_table
) / sizeof (elf_z80_howto_table
[0])
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
;
298 /* Set the howto pointer for an z80 ELF reloc. */
301 z80_info_to_howto_rel (bfd
*abfd
, arelent
*cache_ptr
, Elf_Internal_Rela
*dst
)
305 table_size
= sizeof (elf_z80_howto_table
) / sizeof (elf_z80_howto_table
[0])
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
;
319 /* xgettext:c-format */
320 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
322 bfd_set_error (bfd_error_bad_value
);
327 z80_elf_set_mach_from_flags (bfd
*abfd
)
330 switch (elf_elfheader (abfd
)->e_flags
)
332 case EF_Z80_MACH_GBZ80
:
333 mach
= bfd_mach_gbz80
;
335 case EF_Z80_MACH_Z80
:
338 case EF_Z80_MACH_Z180
:
339 mach
= bfd_mach_z180
;
341 case EF_Z80_MACH_EZ80_Z80
:
342 mach
= bfd_mach_ez80_z80
;
344 case EF_Z80_MACH_EZ80_ADL
:
345 mach
= bfd_mach_ez80_adl
;
347 case EF_Z80_MACH_R800
:
348 mach
= bfd_mach_r800
;
355 bfd_default_set_arch_mach (abfd
, bfd_arch_z80
, mach
);
360 z80_is_local_label_name (bfd
* abfd ATTRIBUTE_UNUSED
,
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"