gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / elf32-pj.c
CommitLineData
0bcb993b 1/* picoJava specific support for 32-bit ELF
b3adc24a 2 Copyright (C) 1999-2020 Free Software Foundation, Inc.
0bcb993b
ILT
3 Contributed by Steve Chamberlan of Transmeta (sac@pobox.com).
4
47b0e7ad 5 This file is part of BFD, the Binary File Descriptor library.
0bcb993b 6
47b0e7ad
NC
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
cd123cb7 9 the Free Software Foundation; either version 3 of the License, or
47b0e7ad 10 (at your option) any later version.
0bcb993b 11
47b0e7ad
NC
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.
0bcb993b 16
47b0e7ad
NC
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
cd123cb7
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
0bcb993b 21
0bcb993b 22#include "sysdep.h"
3db64b00 23#include "bfd.h"
0bcb993b
ILT
24#include "bfdlink.h"
25#include "libbfd.h"
26#include "elf-bfd.h"
27#include "elf/pj.h"
28
47b0e7ad
NC
29/* This function is used for normal relocs. This is like the COFF
30 function, and is almost certainly incorrect for other ELF targets. */
31
32static bfd_reloc_status_type
33pj_elf_reloc (bfd *abfd,
34 arelent *reloc_entry,
35 asymbol *symbol_in,
36 void * data,
37 asection *input_section,
38 bfd *output_bfd,
39 char **error_message ATTRIBUTE_UNUSED)
40{
41 unsigned long insn;
42 bfd_vma sym_value;
43 enum elf_pj_reloc_type r_type;
44 bfd_vma addr = reloc_entry->address;
45 bfd_byte *hit_data = addr + (bfd_byte *) data;
46
47 r_type = (enum elf_pj_reloc_type) reloc_entry->howto->type;
48
49 if (output_bfd != NULL)
50 {
51 /* Partial linking--do nothing. */
52 reloc_entry->address += input_section->output_offset;
53 return bfd_reloc_ok;
54 }
55
56 if (symbol_in != NULL
e1cbf07a 57 && (symbol_in->flags & BSF_WEAK) == 0
47b0e7ad
NC
58 && bfd_is_und_section (symbol_in->section))
59 return bfd_reloc_undefined;
60
61 if (bfd_is_com_section (symbol_in->section))
62 sym_value = 0;
63 else
64 sym_value = (symbol_in->value +
65 symbol_in->section->output_section->vma +
66 symbol_in->section->output_offset);
67
68 switch (r_type)
69 {
70 case R_PJ_DATA_DIR32:
71 insn = bfd_get_32 (abfd, hit_data);
72 insn += sym_value + reloc_entry->addend;
73 bfd_put_32 (abfd, (bfd_vma) insn, hit_data);
74 break;
75
76 /* Relocations in code are always bigendian, no matter what the
77 data endianness is. */
78
79 case R_PJ_CODE_DIR32:
80 insn = bfd_getb32 (hit_data);
81 insn += sym_value + reloc_entry->addend;
82 bfd_putb32 ((bfd_vma) insn, hit_data);
83 break;
84
85 case R_PJ_CODE_REL16:
86 insn = bfd_getb16 (hit_data);
87 insn += sym_value + reloc_entry->addend
07d6d2b8
AM
88 - (input_section->output_section->vma
89 + input_section->output_offset);
47b0e7ad
NC
90 bfd_putb16 ((bfd_vma) insn, hit_data);
91 break;
92 case R_PJ_CODE_LO16:
93 insn = bfd_getb16 (hit_data);
94 insn += sym_value + reloc_entry->addend;
95 bfd_putb16 ((bfd_vma) insn, hit_data);
96 break;
97
98 case R_PJ_CODE_HI16:
99 insn = bfd_getb16 (hit_data);
100 insn += (sym_value + reloc_entry->addend) >> 16;
101 bfd_putb16 ((bfd_vma) insn, hit_data);
102 break;
103
104 default:
105 abort ();
106 break;
107 }
108
109 return bfd_reloc_ok;
110}
0bcb993b
ILT
111
112static reloc_howto_type pj_elf_howto_table[] =
113{
114 /* No relocation. */
115 HOWTO (R_PJ_NONE, /* type */
116 0, /* rightshift */
6346d5ca 117 3, /* size (0 = byte, 1 = short, 2 = long) */
0bcb993b 118 0, /* bitsize */
b34976b6 119 FALSE, /* pc_relative */
0bcb993b
ILT
120 0, /* bitpos */
121 complain_overflow_dont, /* complain_on_overflow */
122 pj_elf_reloc, /* special_function */
123 "R_PJ_NONE", /* name */
b34976b6 124 FALSE, /* partial_inplace */
0bcb993b
ILT
125 0, /* src_mask */
126 0, /* dst_mask */
b34976b6 127 FALSE), /* pcrel_offset */
0bcb993b 128
b34976b6 129 /* 32 bit absolute relocation. Setting partial_inplace to TRUE and
0bcb993b 130 src_mask to a non-zero value is similar to the COFF toolchain. */
47b0e7ad 131 HOWTO (R_PJ_DATA_DIR32, /* type */
0bcb993b
ILT
132 0, /* rightshift */
133 2, /* size (0 = byte, 1 = short, 2 = long) */
134 32, /* bitsize */
b34976b6 135 FALSE, /* pc_relative */
0bcb993b
ILT
136 0, /* bitpos */
137 complain_overflow_bitfield, /* complain_on_overflow */
138 pj_elf_reloc, /* special_function */
139 "R_PJ_DIR32", /* name */
b34976b6 140 TRUE, /* partial_inplace */
0bcb993b
ILT
141 0xffffffff, /* src_mask */
142 0xffffffff, /* dst_mask */
b34976b6 143 FALSE), /* pcrel_offset */
0bcb993b
ILT
144
145 /* 32 bit PC relative relocation. */
47b0e7ad 146 HOWTO (R_PJ_CODE_REL32, /* type */
0bcb993b
ILT
147 0, /* rightshift */
148 2, /* size (0 = byte, 1 = short, 2 = long) */
149 32, /* bitsize */
b34976b6 150 TRUE, /* pc_relative */
0bcb993b
ILT
151 0, /* bitpos */
152 complain_overflow_signed, /* complain_on_overflow */
153 pj_elf_reloc, /* special_function */
154 "R_PJ_REL32", /* name */
b34976b6 155 FALSE, /* partial_inplace */
0bcb993b
ILT
156 0, /* src_mask */
157 0xffffffff, /* dst_mask */
b34976b6 158 TRUE), /* pcrel_offset */
0bcb993b
ILT
159
160/* 16 bit PC relative relocation. */
47b0e7ad 161 HOWTO (R_PJ_CODE_REL16, /* type */
0bcb993b
ILT
162 0, /* rightshift */
163 1, /* size (0 = byte, 1 = short, 2 = long) */
164 16, /* bitsize */
b34976b6 165 TRUE, /* pc_relative */
0bcb993b
ILT
166 0, /* bitpos */
167 complain_overflow_signed, /* complain_on_overf6w */
168 pj_elf_reloc, /* special_function */
169 "R_PJ_REL16", /* name */
b34976b6 170 FALSE, /* partial_inplace */
0bcb993b
ILT
171 0xffff, /* src_mask */
172 0xffff, /* dst_mask */
b34976b6 173 TRUE), /* pcrel_offset */
0bcb993b
ILT
174 EMPTY_HOWTO (4),
175 EMPTY_HOWTO (5),
176 HOWTO (R_PJ_CODE_DIR32, /* type */
177 0, /* rightshift */
178 2, /* size (0 = byte, 1 = short, 2 = long) */
179 32, /* bitsize */
b34976b6 180 FALSE, /* pc_relative */
0bcb993b
ILT
181 0, /* bitpos */
182 complain_overflow_bitfield, /* complain_on_overflow */
183 pj_elf_reloc, /* special_function */
184 "R_PJ_CODE_DIR32", /* name */
b34976b6 185 TRUE, /* partial_inplace */
0bcb993b
ILT
186 0xffffffff, /* src_mask */
187 0xffffffff, /* dst_mask */
b34976b6 188 FALSE), /* pcrel_offset */
0bcb993b
ILT
189
190 EMPTY_HOWTO (7),
191 EMPTY_HOWTO (8),
192 EMPTY_HOWTO (9),
193 EMPTY_HOWTO (10),
194 EMPTY_HOWTO (11),
195 EMPTY_HOWTO (12),
196
197 HOWTO (R_PJ_CODE_LO16, /* type */
198 0, /* rightshift */
199 1, /* size (0 = byte, 1 = short, 2 = long) */
200 16, /* bitsize */
b34976b6 201 FALSE, /* pc_relative */
0bcb993b
ILT
202 0, /* bitpos */
203 complain_overflow_unsigned, /* complain_on_overflow */
204 pj_elf_reloc, /* special_function */
205 "R_PJ_LO16", /* name */
b34976b6 206 FALSE, /* partial_inplace */
0bcb993b
ILT
207 0xffff, /* src_mask */
208 0xffff, /* dst_mask */
b34976b6 209 TRUE), /* pcrel_offset */
0bcb993b 210
0bcb993b
ILT
211 HOWTO (R_PJ_CODE_HI16, /* type */
212 16, /* rightshift */
213 1, /* size (0 = byte, 1 = short, 2 = long) */
214 16, /* bitsize */
b34976b6 215 FALSE, /* pc_relative */
0bcb993b
ILT
216 0, /* bitpos */
217 complain_overflow_unsigned, /* complain_on_overflow */
218 pj_elf_reloc, /* special_function */
219 "R_PJ_HI16", /* name */
b34976b6 220 FALSE, /* partial_inplace */
0bcb993b
ILT
221 0xffff, /* src_mask */
222 0xffff, /* dst_mask */
b34976b6 223 TRUE), /* pcrel_offset */
0bcb993b 224
47b0e7ad 225 /* GNU extension to record C++ vtable hierarchy. */
07d6d2b8
AM
226 HOWTO (R_PJ_GNU_VTINHERIT, /* type */
227 0, /* rightshift */
228 2, /* size (0 = byte, 1 = short, 2 = long) */
229 0, /* bitsize */
230 FALSE, /* pc_relative */
231 0, /* bitpos */
232 complain_overflow_dont, /* complain_on_overflow */
233 NULL, /* special_function */
234 "R_PJ_GNU_VTINHERIT", /* name */
235 FALSE, /* partial_inplace */
236 0, /* src_mask */
237 0, /* dst_mask */
238 FALSE), /* pcrel_offset */
0bcb993b 239
47b0e7ad 240 /* GNU extension to record C++ vtable member usage. */
0bcb993b 241 HOWTO (R_PJ_GNU_VTENTRY, /* type */
07d6d2b8
AM
242 0, /* rightshift */
243 2, /* size (0 = byte, 1 = short, 2 = long) */
244 0, /* bitsize */
245 FALSE, /* pc_relative */
246 0, /* bitpos */
247 complain_overflow_dont, /* complain_on_overflow */
248 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
249 "R_PJ_GNU_VTENTRY", /* name */
250 FALSE, /* partial_inplace */
251 0, /* src_mask */
252 0, /* dst_mask */
253 FALSE), /* pcrel_offset */
0bcb993b
ILT
254};
255
0bcb993b
ILT
256/* This structure is used to map BFD reloc codes to PJ ELF relocs. */
257
258struct elf_reloc_map
259{
260 bfd_reloc_code_real_type bfd_reloc_val;
261 unsigned char elf_reloc_val;
262};
263
264/* An array mapping BFD reloc codes to PJ ELF relocs. */
265
266static const struct elf_reloc_map pj_reloc_map[] =
267{
07d6d2b8
AM
268 { BFD_RELOC_NONE, R_PJ_NONE },
269 { BFD_RELOC_32, R_PJ_DATA_DIR32 },
270 { BFD_RELOC_PJ_CODE_DIR16, R_PJ_CODE_DIR16 },
271 { BFD_RELOC_PJ_CODE_DIR32, R_PJ_CODE_DIR32 },
272 { BFD_RELOC_PJ_CODE_LO16, R_PJ_CODE_LO16 },
273 { BFD_RELOC_PJ_CODE_HI16, R_PJ_CODE_HI16 },
274 { BFD_RELOC_PJ_CODE_REL32, R_PJ_CODE_REL32 },
275 { BFD_RELOC_PJ_CODE_REL16, R_PJ_CODE_REL16 },
0bcb993b
ILT
276 { BFD_RELOC_VTABLE_INHERIT, R_PJ_GNU_VTINHERIT },
277 { BFD_RELOC_VTABLE_ENTRY, R_PJ_GNU_VTENTRY },
278};
279
280/* Given a BFD reloc code, return the howto structure for the
281 corresponding PJ ELf reloc. */
282
283static reloc_howto_type *
47b0e7ad
NC
284pj_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
285 bfd_reloc_code_real_type code)
0bcb993b
ILT
286{
287 unsigned int i;
c3668558 288
0bcb993b 289 for (i = 0; i < sizeof (pj_reloc_map) / sizeof (struct elf_reloc_map); i++)
47b0e7ad
NC
290 if (pj_reloc_map[i].bfd_reloc_val == code)
291 return & pj_elf_howto_table[(int) pj_reloc_map[i].elf_reloc_val];
0bcb993b
ILT
292
293 return NULL;
294}
295
157090f7
AM
296static reloc_howto_type *
297pj_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
298 const char *r_name)
299{
300 unsigned int i;
301
302 for (i = 0;
303 i < sizeof (pj_elf_howto_table) / sizeof (pj_elf_howto_table[0]);
304 i++)
305 if (pj_elf_howto_table[i].name != NULL
306 && strcasecmp (pj_elf_howto_table[i].name, r_name) == 0)
307 return &pj_elf_howto_table[i];
308
309 return NULL;
310}
311
0bcb993b
ILT
312/* Given an ELF reloc, fill in the howto field of a relent. */
313
f3185997 314static bfd_boolean
0aa13fee 315pj_elf_info_to_howto (bfd *abfd,
47b0e7ad
NC
316 arelent *cache_ptr,
317 Elf_Internal_Rela *dst)
0bcb993b
ILT
318{
319 unsigned int r;
320
321 r = ELF32_R_TYPE (dst->r_info);
322
cd21f5da
NC
323 if (r >= R_PJ_max)
324 {
695344c0 325 /* xgettext:c-format */
0aa13fee 326 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
4eca0228 327 abfd, r);
cd21f5da 328 bfd_set_error (bfd_error_bad_value);
f3185997 329 return FALSE;
cd21f5da 330 }
0bcb993b
ILT
331
332 cache_ptr->howto = &pj_elf_howto_table[r];
f3185997 333 return TRUE;
0bcb993b
ILT
334}
335
336/* Take this moment to fill in the special picoJava bits in the
c3668558 337 e_flags field. */
0bcb993b 338
cc364be6
AM
339static bfd_boolean
340pj_elf_final_write_processing (bfd *abfd)
0bcb993b 341{
47b0e7ad
NC
342 elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_ARCH;
343 elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_GNUCALLS;
cc364be6 344 return _bfd_elf_final_write_processing (abfd);
0bcb993b
ILT
345}
346
6d00b590 347#define TARGET_BIG_SYM pj_elf32_vec
0bcb993b 348#define TARGET_BIG_NAME "elf32-pj"
6d00b590 349#define TARGET_LITTLE_SYM pj_elf32_le_vec
0bcb993b
ILT
350#define TARGET_LITTLE_NAME "elf32-pjl"
351#define ELF_ARCH bfd_arch_pj
352#define ELF_MACHINE_CODE EM_PJ
aa4f99bb 353#define ELF_MACHINE_ALT1 EM_PJ_OLD
0bcb993b 354#define ELF_MAXPAGESIZE 0x1000
157090f7
AM
355#define bfd_elf32_bfd_get_relocated_section_contents \
356 bfd_generic_get_relocated_section_contents
07d6d2b8 357#define bfd_elf32_bfd_reloc_type_lookup pj_elf_reloc_type_lookup
157090f7
AM
358#define bfd_elf32_bfd_reloc_name_lookup pj_elf_reloc_name_lookup
359#define elf_backend_final_write_processing pj_elf_final_write_processing
07d6d2b8 360#define elf_info_to_howto pj_elf_info_to_howto
0bcb993b 361#include "elf32-target.h"
This page took 1.029171 seconds and 4 git commands to generate.