Prevent illegal memory accesses when attempting to read excessively large COFF line...
[deliverable/binutils-gdb.git] / bfd / elf32-ft32.c
CommitLineData
3f8107ab 1/* ft32-specific support for 32-bit ELF.
2571583a 2 Copyright (C) 2013-2017 Free Software Foundation, Inc.
3f8107ab
AM
3
4 Copied from elf32-moxie.c which is..
2571583a 5 Copyright (C) 2009-2017 Free Software Foundation, Inc.
3f8107ab
AM
6 Free Software Foundation, Inc.
7
8 This file is part of BFD, the Binary File Descriptor library.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
24
25#include "sysdep.h"
26#include "bfd.h"
27#include "libbfd.h"
28#include "elf-bfd.h"
29#include "elf/ft32.h"
30
31/* Forward declarations. */
32
33static reloc_howto_type ft32_elf_howto_table [] =
34{
35 /* This reloc does nothing. */
36 HOWTO (R_FT32_NONE, /* type */
37 0, /* rightshift */
38 2, /* size (0 = byte, 1 = short, 2 = long) */
39 32, /* bitsize */
40 FALSE, /* pc_relative */
41 0, /* bitpos */
42 complain_overflow_bitfield, /* complain_on_overflow */
43 bfd_elf_generic_reloc, /* special_function */
44 "R_FT32_NONE", /* name */
45 FALSE, /* partial_inplace */
46 0, /* src_mask */
47 0, /* dst_mask */
48 FALSE), /* pcrel_offset */
49
50 /* A 32 bit absolute relocation. */
51
52 HOWTO (R_FT32_32, /* type */
53 0, /* rightshift */
54 2, /* size (0 = byte, 1 = short, 2 = long) */
55 32, /* bitsize */
56 FALSE, /* pc_relative */
57 0, /* bitpos */
58 complain_overflow_bitfield, /* complain_on_overflow */
59 bfd_elf_generic_reloc, /* special_function */
60 "R_FT32_32", /* name */
61 FALSE, /* partial_inplace */
62 0x00000000, /* src_mask */
63 0xffffffff, /* dst_mask */
64 FALSE), /* pcrel_offset */
65
66 HOWTO (R_FT32_16, /* type */
67 0, /* rightshift */
68 1, /* size (0 = byte, 1 = short, 2 = long) */
69 16, /* bitsize */
70 FALSE, /* pc_relative */
71 0, /* bitpos */
72 complain_overflow_bitfield, /* complain_on_overflow */
73 bfd_elf_generic_reloc, /* special_function */
74 "R_FT32_16", /* name */
75 FALSE, /* partial_inplace */
76 0x00000000, /* src_mask */
77 0x0000ffff, /* dst_mask */
78 FALSE), /* pcrel_offset */
79
80 HOWTO (R_FT32_8, /* type */
81 0, /* rightshift */
82 0, /* size (0 = byte, 1 = short, 2 = long) */
83 8, /* bitsize */
84 FALSE, /* pc_relative */
85 0, /* bitpos */
86 complain_overflow_signed, /* complain_on_overflow */
87 bfd_elf_generic_reloc, /* special_function */
88 "R_FT32_8", /* name */
89 FALSE, /* partial_inplace */
90 0x00000000, /* src_mask */
91 0x000000ff, /* dst_mask */
92 FALSE), /* pcrel_offset */
93
94 HOWTO (R_FT32_10, /* type */
95 0, /* rightshift */
96 1, /* size (0 = byte, 1 = short, 2 = long) */
97 10, /* bitsize */
98 FALSE, /* pc_relative */
99 4, /* bitpos */
100 complain_overflow_signed, /* complain_on_overflow */
101 bfd_elf_generic_reloc, /* special_function */
102 "R_FT32_10", /* name */
103 FALSE, /* partial_inplace */
104 0x00000000, /* src_mask */
105 0x00003ff0, /* dst_mask */
106 FALSE), /* pcrel_offset */
107
108 HOWTO (R_FT32_20, /* type */
109 0, /* rightshift */
110 2, /* size (0 = byte, 1 = short, 2 = long) */
111 20, /* bitsize */
112 FALSE, /* pc_relative */
113 0, /* bitpos */
114 complain_overflow_dont, /* complain_on_overflow */
115 bfd_elf_generic_reloc, /* special_function */
116 "R_FT32_20", /* name */
117 FALSE, /* partial_inplace */
118 0x00000000, /* src_mask */
119 0x000fffff, /* dst_mask */
120 FALSE), /* pcrel_offset */
121
122 HOWTO (R_FT32_17, /* type */
123 0, /* rightshift */
124 2, /* size (0 = byte, 1 = short, 2 = long) */
125 17, /* bitsize */
126 FALSE, /* pc_relative */
127 0, /* bitpos */
128 complain_overflow_dont, /* complain_on_overflow */
129 bfd_elf_generic_reloc, /* special_function */
130 "R_FT32_17", /* name */
131 FALSE, /* partial_inplace */
132 0x00000000, /* src_mask */
133 0x0001ffff, /* dst_mask */
134 FALSE), /* pcrel_offset */
135
136 HOWTO (R_FT32_18, /* type */
137 2, /* rightshift */
138 2, /* size (0 = byte, 1 = short, 2 = long) */
139 18, /* bitsize */
140 FALSE, /* pc_relative */
141 0, /* bitpos */
ef32532f 142 complain_overflow_dont, /* complain_on_overflow */
3f8107ab
AM
143 bfd_elf_generic_reloc, /* special_function */
144 "R_FT32_18", /* name */
145 FALSE, /* partial_inplace */
146 0x00000000, /* src_mask */
147 0x0003ffff, /* dst_mask */
148 FALSE), /* pcrel_offset */
149
3b4b0a62
JB
150 HOWTO (R_FT32_15, /* type */
151 0, /* rightshift */
152 2, /* size (0 = byte, 1 = short, 2 = long) */
153 15, /* bitsize */
154 FALSE, /* pc_relative */
155 0, /* bitpos */
156 complain_overflow_dont, /* complain_on_overflow */
157 bfd_elf_generic_reloc, /* special_function */
158 "R_FT32_15", /* name */
159 FALSE, /* partial_inplace */
160 0x00000000, /* src_mask */
161 0x00007fff, /* dst_mask */
162 FALSE), /* pcrel_offset */
3f8107ab
AM
163};
164\f
165/* Map BFD reloc types to FT32 ELF reloc types. */
166
167struct ft32_reloc_map
168{
169 bfd_reloc_code_real_type bfd_reloc_val;
170 unsigned int ft32_reloc_val;
171};
172
173static const struct ft32_reloc_map ft32_reloc_map [] =
174{
175 { BFD_RELOC_NONE, R_FT32_NONE },
458653a9 176 { BFD_RELOC_32, R_FT32_32 },
3f8107ab
AM
177 { BFD_RELOC_16, R_FT32_16 },
178 { BFD_RELOC_8, R_FT32_8 },
179 { BFD_RELOC_FT32_10, R_FT32_10 },
180 { BFD_RELOC_FT32_20, R_FT32_20 },
181 { BFD_RELOC_FT32_17, R_FT32_17 },
182 { BFD_RELOC_FT32_18, R_FT32_18 },
3b4b0a62 183 { BFD_RELOC_FT32_15, R_FT32_15 },
3f8107ab
AM
184};
185
186static reloc_howto_type *
187ft32_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
188 bfd_reloc_code_real_type code)
189{
190 unsigned int i;
191
192 for (i = sizeof (ft32_reloc_map) / sizeof (ft32_reloc_map[0]);
193 --i;)
194 if (ft32_reloc_map [i].bfd_reloc_val == code)
195 return & ft32_elf_howto_table [ft32_reloc_map[i].ft32_reloc_val];
196
197 return NULL;
198}
199
200static reloc_howto_type *
201ft32_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
202{
203 unsigned int i;
204
205 for (i = 0;
206 i < sizeof (ft32_elf_howto_table) / sizeof (ft32_elf_howto_table[0]);
207 i++)
208 if (ft32_elf_howto_table[i].name != NULL
209 && strcasecmp (ft32_elf_howto_table[i].name, r_name) == 0)
210 return &ft32_elf_howto_table[i];
211
212 return NULL;
213}
214
215/* Set the howto pointer for an FT32 ELF reloc. */
216
217static void
218ft32_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
219 arelent *cache_ptr,
220 Elf_Internal_Rela *dst)
221{
222 unsigned int r_type;
223
224 r_type = ELF32_R_TYPE (dst->r_info);
225 BFD_ASSERT (r_type < (unsigned int) R_FT32_max);
226 cache_ptr->howto = & ft32_elf_howto_table [r_type];
227}
228\f
229/* Relocate an FT32 ELF section.
230
231 The RELOCATE_SECTION function is called by the new ELF backend linker
232 to handle the relocations for a section.
233
234 The relocs are always passed as Rela structures; if the section
235 actually uses Rel structures, the r_addend field will always be
236 zero.
237
238 This function is responsible for adjusting the section contents as
239 necessary, and (if using Rela relocs and generating a relocatable
240 output file) adjusting the reloc addend as necessary.
241
242 This function does not have to worry about setting the reloc
243 address or the reloc symbol index.
244
245 LOCAL_SYMS is a pointer to the swapped in local symbols.
246
247 LOCAL_SECTIONS is an array giving the section in the input file
248 corresponding to the st_shndx field of each local symbol.
249
250 The global hash table entry for the global symbols can be found
251 via elf_sym_hashes (input_bfd).
252
253 When generating relocatable output, this function must handle
254 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
255 going to be the section symbol corresponding to the output
256 section, which means that the addend must be adjusted
257 accordingly. */
258
259static bfd_boolean
260ft32_elf_relocate_section (bfd *output_bfd,
261 struct bfd_link_info *info,
262 bfd *input_bfd,
263 asection *input_section,
264 bfd_byte *contents,
265 Elf_Internal_Rela *relocs,
266 Elf_Internal_Sym *local_syms,
267 asection **local_sections)
268{
269 Elf_Internal_Shdr *symtab_hdr;
270 struct elf_link_hash_entry **sym_hashes;
271 Elf_Internal_Rela *rel;
272 Elf_Internal_Rela *relend;
273
274 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
275 sym_hashes = elf_sym_hashes (input_bfd);
276 relend = relocs + input_section->reloc_count;
277
278 for (rel = relocs; rel < relend; rel ++)
279 {
280 reloc_howto_type *howto;
281 unsigned long r_symndx;
282 Elf_Internal_Sym *sym;
283 asection *sec;
284 struct elf_link_hash_entry *h;
285 bfd_vma relocation;
286 bfd_reloc_status_type r;
287 const char *name;
288 int r_type;
289
290 r_type = ELF32_R_TYPE (rel->r_info);
291 r_symndx = ELF32_R_SYM (rel->r_info);
292 howto = ft32_elf_howto_table + r_type;
293 h = NULL;
294 sym = NULL;
295 sec = NULL;
296
297 if (r_symndx < symtab_hdr->sh_info)
298 {
299 sym = local_syms + r_symndx;
300 sec = local_sections [r_symndx];
301 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
302
303 name = bfd_elf_string_from_elf_section
304 (input_bfd, symtab_hdr->sh_link, sym->st_name);
305 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
306 }
307 else
308 {
309 bfd_boolean unresolved_reloc, warned, ignored;
310
311 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
312 r_symndx, symtab_hdr, sym_hashes,
313 h, sec, relocation,
314 unresolved_reloc, warned, ignored);
315
316 name = h->root.root.string;
317 }
318
319 if (sec != NULL && discarded_section (sec))
320 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
321 rel, 1, relend, howto, 0, contents);
322
0e1862bb 323 if (bfd_link_relocatable (info))
3f8107ab
AM
324 continue;
325
326 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
327 contents, rel->r_offset,
328 relocation, rel->r_addend);
329
330 if (r != bfd_reloc_ok)
331 {
332 const char * msg = NULL;
333
334 switch (r)
335 {
336 case bfd_reloc_overflow:
1a72702b 337 (*info->callbacks->reloc_overflow)
3f8107ab
AM
338 (info, (h ? &h->root : NULL), name, howto->name,
339 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
340 break;
341
342 case bfd_reloc_undefined:
1a72702b
AM
343 (*info->callbacks->undefined_symbol)
344 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
3f8107ab
AM
345 break;
346
347 case bfd_reloc_outofrange:
348 msg = _("internal error: out of range error");
349 break;
350
351 case bfd_reloc_notsupported:
352 msg = _("internal error: unsupported relocation error");
353 break;
354
355 case bfd_reloc_dangerous:
356 msg = _("internal error: dangerous relocation");
357 break;
358
359 default:
360 msg = _("internal error: unknown error");
361 break;
362 }
363
364 if (msg)
1a72702b
AM
365 (*info->callbacks->warning) (info, msg, name, input_bfd,
366 input_section, rel->r_offset);
3f8107ab
AM
367 }
368 }
369
370 return TRUE;
371}
372\f
373#define ELF_ARCH bfd_arch_ft32
374#define ELF_MACHINE_CODE EM_FT32
375#define ELF_MAXPAGESIZE 0x1
376
377#define TARGET_LITTLE_SYM ft32_elf32_vec
378#define TARGET_LITTLE_NAME "elf32-ft32"
379
380#define elf_info_to_howto_rel NULL
381#define elf_info_to_howto ft32_info_to_howto_rela
382#define elf_backend_relocate_section ft32_elf_relocate_section
383
384#define elf_backend_can_gc_sections 1
385#define elf_backend_rela_normal 1
386
387#define bfd_elf32_bfd_reloc_type_lookup ft32_reloc_type_lookup
388#define bfd_elf32_bfd_reloc_name_lookup ft32_reloc_name_lookup
389
390#include "elf32-target.h"
This page took 0.181173 seconds and 4 git commands to generate.