gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / elf32-xc16x.c
CommitLineData
d70c5fc7 1/* Infineon XC16X-specific support for 16-bit ELF.
b3adc24a 2 Copyright (C) 2006-2020 Free Software Foundation, Inc.
68ffbac6 3 Contributed by KPIT Cummins Infosystems
d70c5fc7
NC
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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
d70c5fc7
NC
10 (at your option) any later version.
11
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.
16
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, 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
d70c5fc7 21
d70c5fc7 22#include "sysdep.h"
3db64b00 23#include "bfd.h"
d70c5fc7
NC
24#include "libbfd.h"
25#include "elf-bfd.h"
26#include "elf/xc16x.h"
fa8f86ff 27#include "dwarf2.h"
d70c5fc7
NC
28#include "libiberty.h"
29
30static reloc_howto_type xc16x_elf_howto_table [] =
31{
32 /* This reloc does nothing. */
33 HOWTO (R_XC16X_NONE, /* type */
34 0, /* rightshift */
6346d5ca
AM
35 3, /* size (0 = byte, 1 = short, 2 = long) */
36 0, /* bitsize */
d70c5fc7
NC
37 FALSE, /* pc_relative */
38 0, /* bitpos */
6346d5ca 39 complain_overflow_dont, /* complain_on_overflow */
d70c5fc7
NC
40 bfd_elf_generic_reloc, /* special_function */
41 "R_XC16X_NONE", /* name */
42 FALSE, /* partial_inplace */
43 0, /* src_mask */
44 0, /* dst_mask */
45 FALSE), /* pcrel_offset */
46
47 /* An 8 bit absolute relocation. */
48 HOWTO (R_XC16X_ABS_8, /* type */
49 0, /* rightshift */
50 0, /* size (0 = byte, 1 = short, 2 = long) */
51 8, /* bitsize */
52 FALSE, /* pc_relative */
53 8, /* bitpos */
54 complain_overflow_bitfield, /* complain_on_overflow */
55 bfd_elf_generic_reloc, /* special_function */
56 "R_XC16X_ABS_8", /* name */
57 TRUE, /* partial_inplace */
58 0x0000, /* src_mask */
59 0x00ff, /* dst_mask */
60 FALSE), /* pcrel_offset */
61
62 /* A 16 bit absolute relocation. */
63 HOWTO (R_XC16X_ABS_16, /* type */
64 0, /* rightshift */
65 1, /* size (0 = byte, 1 = short, 2 = long) */
66 16, /* bitsize */
67 FALSE, /* pc_relative */
68 0, /* bitpos */
69 complain_overflow_dont, /* complain_on_overflow */
70 bfd_elf_generic_reloc, /* special_function */
71 "R_XC16X_ABS_16", /* name */
72 TRUE, /* partial_inplace */
73 0x00000000, /* src_mask */
74 0x0000ffff, /* dst_mask */
75 FALSE), /* pcrel_offset */
76
77 HOWTO (R_XC16X_ABS_32, /* type */
07d6d2b8
AM
78 0, /* rightshift */
79 2, /* size (0 = byte, 1 = short, 2 = long) */
80 32, /* bitsize */
81 FALSE, /* pc_relative */
82 0, /* bitpos */
83 complain_overflow_bitfield, /* complain_on_overflow */
84 bfd_elf_generic_reloc, /* special_function */
85 "R_XC16X_ABS_32", /* name */
86 TRUE, /* partial_inplace */
87 0x00000000, /* src_mask */
88 0xffffffff, /* dst_mask */
89 FALSE), /* pcrel_offset */
d70c5fc7
NC
90
91
92 /* A PC relative 8 bit relocation. */
93 HOWTO (R_XC16X_8_PCREL, /* type */
94 0, /* rightshift */
95 0, /* size (0 = byte, 1 = short, 2 = long) */
96 8, /* bitsize */
97 TRUE, /* pc_relative */
98 8, /* bitpos */
99 complain_overflow_signed, /* complain_on_overflow */
100 bfd_elf_generic_reloc, /* special_function */
101 "R_XC16X_8_PCREL", /* name */
102 FALSE, /* partial_inplace */
103 0x0000, /* src_mask */
104 0x00ff, /* dst_mask */
105 TRUE), /* pcrel_offset */
106
107 /* Relocation regarding page number. */
108 HOWTO (R_XC16X_PAG, /* type */
07d6d2b8
AM
109 0, /* rightshift */
110 1, /* size (0 = byte, 1 = short, 2 = long) */
111 16, /* bitsize */
112 FALSE, /* pc_relative */
113 0, /* bitpos */
114 complain_overflow_signed, /* complain_on_overflow */
115 bfd_elf_generic_reloc, /* special_function */
116 "R_XC16X_PAG", /* name */
117 TRUE, /* partial_inplace */
118 0x00000000, /* src_mask */
119 0x0000ffff, /* dst_mask */
120 FALSE), /* pcrel_offset */
d70c5fc7
NC
121
122
123 /* Relocation regarding page number. */
124 HOWTO (R_XC16X_POF, /* type */
07d6d2b8
AM
125 0, /* rightshift */
126 1, /* size (0 = byte, 1 = short, 2 = long) */
127 16, /* bitsize */
128 FALSE, /* pc_relative */
129 0, /* bitpos */
130 complain_overflow_signed, /* complain_on_overflow */
131 bfd_elf_generic_reloc, /* special_function */
132 "R_XC16X_POF", /* name */
133 TRUE, /* partial_inplace */
134 0x00000000, /* src_mask */
135 0x0000ffff, /* dst_mask */
136 FALSE), /* pcrel_offset */
d70c5fc7
NC
137
138
139 /* Relocation regarding segment number. */
140 HOWTO (R_XC16X_SEG, /* type */
07d6d2b8
AM
141 0, /* rightshift */
142 1, /* size (0 = byte, 1 = short, 2 = long) */
143 16, /* bitsize */
144 FALSE, /* pc_relative */
145 0, /* bitpos */
146 complain_overflow_signed, /* complain_on_overflow */
147 bfd_elf_generic_reloc, /* special_function */
148 "R_XC16X_SEG", /* name */
149 TRUE, /* partial_inplace */
150 0x00000000, /* src_mask */
151 0x0000ffff, /* dst_mask */
152 FALSE), /* pcrel_offset */
d70c5fc7
NC
153
154 /* Relocation regarding segment offset. */
155 HOWTO (R_XC16X_SOF, /* type */
07d6d2b8
AM
156 0, /* rightshift */
157 1, /* size (0 = byte, 1 = short, 2 = long) */
158 16, /* bitsize */
159 FALSE, /* pc_relative */
160 0, /* bitpos */
161 complain_overflow_signed, /* complain_on_overflow */
162 bfd_elf_generic_reloc, /* special_function */
163 "R_XC16X_SOF", /* name */
164 TRUE, /* partial_inplace */
165 0x00000000, /* src_mask */
166 0x0000ffff, /* dst_mask */
167 FALSE) /* pcrel_offset */
d70c5fc7
NC
168};
169
170
171/* Map BFD reloc types to XC16X ELF reloc types. */
172
173struct xc16x_reloc_map
174{
175 bfd_reloc_code_real_type bfd_reloc_val;
176 unsigned int xc16x_reloc_val;
177};
178
179static const struct xc16x_reloc_map xc16x_reloc_map [] =
180{
07d6d2b8
AM
181 { BFD_RELOC_NONE, R_XC16X_NONE },
182 { BFD_RELOC_8, R_XC16X_ABS_8 },
183 { BFD_RELOC_16, R_XC16X_ABS_16 },
184 { BFD_RELOC_32, R_XC16X_ABS_32 },
185 { BFD_RELOC_8_PCREL, R_XC16X_8_PCREL },
d70c5fc7
NC
186 { BFD_RELOC_XC16X_PAG, R_XC16X_PAG},
187 { BFD_RELOC_XC16X_POF, R_XC16X_POF},
188 { BFD_RELOC_XC16X_SEG, R_XC16X_SEG},
189 { BFD_RELOC_XC16X_SOF, R_XC16X_SOF},
190};
191
192
193/* This function is used to search for correct relocation type from
194 howto structure. */
195
196static reloc_howto_type *
197xc16x_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
198 bfd_reloc_code_real_type code)
199{
200 unsigned int i;
201
202 for (i = ARRAY_SIZE (xc16x_reloc_map); --i;)
203 if (xc16x_reloc_map [i].bfd_reloc_val == code)
204 return & xc16x_elf_howto_table [xc16x_reloc_map[i].xc16x_reloc_val];
205
206 return NULL;
207}
208
157090f7
AM
209static reloc_howto_type *
210xc16x_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
211 const char *r_name)
212{
213 unsigned int i;
214
f3185997 215 for (i = 0; i < ARRAY_SIZE (xc16x_elf_howto_table); i++)
157090f7
AM
216 if (xc16x_elf_howto_table[i].name != NULL
217 && strcasecmp (xc16x_elf_howto_table[i].name, r_name) == 0)
218 return &xc16x_elf_howto_table[i];
219
220 return NULL;
221}
222
209d1499
L
223static reloc_howto_type *
224elf32_xc16x_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, unsigned r_type)
225{
226 if (r_type < ARRAY_SIZE (xc16x_elf_howto_table))
227 return & xc16x_elf_howto_table[r_type];
228
229 return NULL;
230}
231
d70c5fc7
NC
232/* For a particular operand this function is
233 called to finalise the type of relocation. */
234
f3185997
NC
235static bfd_boolean
236elf32_xc16x_info_to_howto (bfd *abfd, arelent *bfd_reloc,
d70c5fc7
NC
237 Elf_Internal_Rela *elf_reloc)
238{
239 unsigned int r;
240 unsigned int i;
241
242 r = ELF32_R_TYPE (elf_reloc->r_info);
243 for (i = 0; i < ARRAY_SIZE (xc16x_elf_howto_table); i++)
244 if (xc16x_elf_howto_table[i].type == r)
245 {
246 bfd_reloc->howto = &xc16x_elf_howto_table[i];
f3185997 247 return TRUE;
d70c5fc7 248 }
f3185997
NC
249 /* xgettext:c-format */
250 _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, r);
251 bfd_set_error (bfd_error_bad_value);
252 return FALSE;
d70c5fc7
NC
253}
254
255static bfd_reloc_status_type
256elf32_xc16x_final_link_relocate (unsigned long r_type,
257 bfd *input_bfd,
258 bfd *output_bfd ATTRIBUTE_UNUSED,
259 asection *input_section ATTRIBUTE_UNUSED,
260 bfd_byte *contents,
261 bfd_vma offset,
262 bfd_vma value,
263 bfd_vma addend,
264 struct bfd_link_info *info ATTRIBUTE_UNUSED,
265 asection *sym_sec ATTRIBUTE_UNUSED,
266 int is_local ATTRIBUTE_UNUSED)
267{
268 bfd_byte *hit_data = contents + offset;
269 bfd_vma val1;
270
271 switch (r_type)
272 {
273 case R_XC16X_NONE:
274 return bfd_reloc_ok;
275
276 case R_XC16X_ABS_16:
277 value += addend;
278 bfd_put_16 (input_bfd, value, hit_data);
279 return bfd_reloc_ok;
280
281 case R_XC16X_8_PCREL:
282 bfd_put_8 (input_bfd, value, hit_data);
283 return bfd_reloc_ok;
284
285 /* Following case is to find page number from actual
286 address for this divide value by 16k i.e. page size. */
287
288 case R_XC16X_PAG:
289 value += addend;
290 value /= 0x4000;
291 bfd_put_16 (input_bfd, value, hit_data);
292 return bfd_reloc_ok;
293
294 /* Following case is to find page offset from actual address
295 for this take modulo of value by 16k i.e. page size. */
296
297 case R_XC16X_POF:
298 value += addend;
299 value %= 0x4000;
300 bfd_put_16 (input_bfd, value, hit_data);
301 return bfd_reloc_ok;
302
303 /* Following case is to find segment number from actual
304 address for this divide value by 64k i.e. segment size. */
305
306 case R_XC16X_SEG:
307 value += addend;
308 value /= 0x10000;
309 bfd_put_16 (input_bfd, value, hit_data);
310 return bfd_reloc_ok;
311
312 /* Following case is to find segment offset from actual address
313 for this take modulo of value by 64k i.e. segment size. */
314
315 case R_XC16X_SOF:
316 value += addend;
317 value %= 0x10000;
318 bfd_put_16 (input_bfd, value, hit_data);
319 return bfd_reloc_ok;
320
321 case R_XC16X_ABS_32:
322 if (!strstr (input_section->name,".debug"))
323 {
324 value += addend;
325 val1 = value;
326 value %= 0x4000;
327 val1 /= 0x4000;
328 val1 = val1 << 16;
329 value += val1;
330 bfd_put_32 (input_bfd, value, hit_data);
331 }
332 else
333 {
334 value += addend;
335 bfd_put_32 (input_bfd, value, hit_data);
336 }
337 return bfd_reloc_ok;
338
339 default:
340 return bfd_reloc_notsupported;
341 }
342}
343
344static bfd_boolean
345elf32_xc16x_relocate_section (bfd *output_bfd,
346 struct bfd_link_info *info,
347 bfd *input_bfd,
348 asection *input_section,
349 bfd_byte *contents,
350 Elf_Internal_Rela *relocs,
351 Elf_Internal_Sym *local_syms,
352 asection **local_sections)
353{
354 Elf_Internal_Shdr *symtab_hdr;
355 struct elf_link_hash_entry **sym_hashes;
356 Elf_Internal_Rela *rel, *relend;
357
d70c5fc7
NC
358 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
359 sym_hashes = elf_sym_hashes (input_bfd);
360
361 rel = relocs;
362 relend = relocs + input_section->reloc_count;
363 for (; rel < relend; rel++)
364 {
365 unsigned int r_type;
366 unsigned long r_symndx;
367 Elf_Internal_Sym *sym;
368 asection *sec;
369 struct elf_link_hash_entry *h;
370 bfd_vma relocation;
d70c5fc7
NC
371
372 /* This is a final link. */
373 r_symndx = ELF32_R_SYM (rel->r_info);
374 r_type = ELF32_R_TYPE (rel->r_info);
375 h = NULL;
376 sym = NULL;
377 sec = NULL;
378 if (r_symndx < symtab_hdr->sh_info)
379 {
380 sym = local_syms + r_symndx;
381 sec = local_sections[r_symndx];
382 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
383 }
384 else
385 {
62d887d4 386 bfd_boolean unresolved_reloc, warned, ignored;
d70c5fc7
NC
387
388 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
389 r_symndx, symtab_hdr, sym_hashes,
390 h, sec, relocation,
62d887d4 391 unresolved_reloc, warned, ignored);
d70c5fc7
NC
392 }
393
dbaa2011 394 if (sec != NULL && discarded_section (sec))
ab96bf03
AM
395 {
396 /* For relocs against symbols from removed linkonce sections,
397 or sections discarded by a linker script, we just want the
e4067dbb 398 section contents cleared. Avoid any special processing. */
ab96bf03 399 reloc_howto_type *howto;
209d1499 400 howto = elf32_xc16x_rtype_to_howto (input_bfd, r_type);
e4067dbb 401 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
545fd46b 402 rel, 1, relend, howto, 0, contents);
ab96bf03
AM
403 }
404
0e1862bb 405 if (bfd_link_relocatable (info))
ab96bf03
AM
406 continue;
407
c7e2358a
AM
408 elf32_xc16x_final_link_relocate (r_type, input_bfd, output_bfd,
409 input_section,
410 contents, rel->r_offset,
411 relocation, rel->r_addend,
412 info, sec, h == NULL);
d70c5fc7
NC
413 }
414
415 return TRUE;
416}
417
418
cc364be6
AM
419static bfd_boolean
420elf32_xc16x_final_write_processing (bfd *abfd)
d70c5fc7
NC
421{
422 unsigned long val;
423
424 switch (bfd_get_mach (abfd))
425 {
426 default:
427 case bfd_mach_xc16x:
428 val = 0x1000;
429 break;
430
431 case bfd_mach_xc16xl:
432 val = 0x1001;
433 break;
434
435 case bfd_mach_xc16xs:
436 val = 0x1002;
437 break;
438 }
439
440 elf_elfheader (abfd)->e_flags |= val;
cc364be6 441 return _bfd_elf_final_write_processing (abfd);
d70c5fc7
NC
442}
443
444static unsigned long
445elf32_xc16x_mach (flagword flags)
68ffbac6 446{
d70c5fc7
NC
447 switch (flags)
448 {
449 case 0x1000:
68ffbac6 450 default:
d70c5fc7
NC
451 return bfd_mach_xc16x;
452
453 case 0x1001:
454 return bfd_mach_xc16xl;
455
456 case 0x1002:
457 return bfd_mach_xc16xs;
458 }
459}
460
461
462static bfd_boolean
463elf32_xc16x_object_p (bfd *abfd)
464{
465 bfd_default_set_arch_mach (abfd, bfd_arch_xc16x,
466 elf32_xc16x_mach (elf_elfheader (abfd)->e_flags));
467 return TRUE;
468}
469
470
471#define ELF_ARCH bfd_arch_xc16x
472#define ELF_MACHINE_CODE EM_XC16X
473#define ELF_MAXPAGESIZE 0x100
474
6d00b590 475#define TARGET_LITTLE_SYM xc16x_elf32_vec
d70c5fc7
NC
476#define TARGET_LITTLE_NAME "elf32-xc16x"
477#define elf_backend_final_write_processing elf32_xc16x_final_write_processing
07d6d2b8 478#define elf_backend_object_p elf32_xc16x_object_p
d70c5fc7
NC
479#define elf_backend_can_gc_sections 1
480#define bfd_elf32_bfd_reloc_type_lookup xc16x_reloc_type_lookup
157090f7 481#define bfd_elf32_bfd_reloc_name_lookup xc16x_reloc_name_lookup
d70c5fc7
NC
482#define elf_info_to_howto elf32_xc16x_info_to_howto
483#define elf_info_to_howto_rel elf32_xc16x_info_to_howto
07d6d2b8 484#define elf_backend_relocate_section elf32_xc16x_relocate_section
d70c5fc7
NC
485#define elf_backend_rela_normal 1
486
487#include "elf32-target.h"
This page took 0.74711 seconds and 4 git commands to generate.