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