Update my e-mail address.
[binutils-gdb.git] / bfd / elf32-moxie.c
blobf955096880f45af6115c02cd329d2ea1c94a6fa7
1 /* moxie-specific support for 32-bit ELF.
2 Copyright (C) 2009-2017 Free Software Foundation, Inc.
4 Copied from elf32-fr30.c which is..
5 Copyright (C) 1998-2017 Free Software Foundation, Inc.
7 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
24 #include "sysdep.h"
25 #include "bfd.h"
26 #include "libbfd.h"
27 #include "elf-bfd.h"
28 #include "elf/moxie.h"
30 /* Forward declarations. */
32 static reloc_howto_type moxie_elf_howto_table [] =
34 /* This reloc does nothing. */
35 HOWTO (R_MOXIE_NONE, /* type */
36 0, /* rightshift */
37 3, /* size (0 = byte, 1 = short, 2 = long) */
38 0, /* bitsize */
39 FALSE, /* pc_relative */
40 0, /* bitpos */
41 complain_overflow_dont, /* complain_on_overflow */
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 */
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 */
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. */
80 /* Map BFD reloc types to MOXIE ELF reloc types. */
82 struct moxie_reloc_map
84 bfd_reloc_code_real_type bfd_reloc_val;
85 unsigned int moxie_reloc_val;
88 static const struct moxie_reloc_map moxie_reloc_map [] =
90 { BFD_RELOC_NONE, R_MOXIE_NONE },
91 { BFD_RELOC_32, R_MOXIE_32 },
92 { BFD_RELOC_MOXIE_10_PCREL, R_MOXIE_PCREL10 },
95 static reloc_howto_type *
96 moxie_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
97 bfd_reloc_code_real_type code)
99 unsigned int i;
101 for (i = sizeof (moxie_reloc_map) / sizeof (moxie_reloc_map[0]);
102 i--;)
103 if (moxie_reloc_map [i].bfd_reloc_val == code)
104 return & moxie_elf_howto_table [moxie_reloc_map[i].moxie_reloc_val];
106 return NULL;
109 static reloc_howto_type *
110 moxie_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
112 unsigned int i;
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];
121 return NULL;
124 /* Set the howto pointer for an MOXIE ELF reloc. */
126 static void
127 moxie_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
128 arelent *cache_ptr,
129 Elf_Internal_Rela *dst)
131 unsigned int r_type;
133 r_type = ELF32_R_TYPE (dst->r_info);
134 if (r_type >= (unsigned int) R_MOXIE_max)
136 /* xgettext:c-format */
137 _bfd_error_handler (_("%B: invalid Moxie reloc number: %d"), abfd, r_type);
138 r_type = 0;
140 cache_ptr->howto = & moxie_elf_howto_table [r_type];
143 /* Perform a single relocation. By default we use the standard BFD
144 routines, but a few relocs, we have to do them ourselves. */
146 static bfd_reloc_status_type
147 moxie_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)
154 bfd_reloc_status_type r = bfd_reloc_ok;
156 switch (howto->type)
158 default:
159 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
160 contents, rel->r_offset,
161 relocation, rel->r_addend);
164 return r;
167 /* Relocate an MOXIE ELF section.
169 The RELOCATE_SECTION function is called by the new ELF backend linker
170 to handle the relocations for a section.
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.
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.
180 This function does not have to worry about setting the reloc
181 address or the reloc symbol index.
183 LOCAL_SYMS is a pointer to the swapped in local symbols.
185 LOCAL_SECTIONS is an array giving the section in the input file
186 corresponding to the st_shndx field of each local symbol.
188 The global hash table entry for the global symbols can be found
189 via elf_sym_hashes (input_bfd).
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. */
197 static bfd_boolean
198 moxie_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)
207 Elf_Internal_Shdr *symtab_hdr;
208 struct elf_link_hash_entry **sym_hashes;
209 Elf_Internal_Rela *rel;
210 Elf_Internal_Rela *relend;
212 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
213 sym_hashes = elf_sym_hashes (input_bfd);
214 relend = relocs + input_section->reloc_count;
216 for (rel = relocs; rel < relend; rel ++)
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;
228 r_type = ELF32_R_TYPE (rel->r_info);
229 r_symndx = ELF32_R_SYM (rel->r_info);
230 howto = moxie_elf_howto_table + r_type;
231 h = NULL;
232 sym = NULL;
233 sec = NULL;
235 if (r_symndx < symtab_hdr->sh_info)
237 sym = local_syms + r_symndx;
238 sec = local_sections [r_symndx];
239 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
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;
245 else
247 bfd_boolean unresolved_reloc, warned, ignored;
249 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
250 r_symndx, symtab_hdr, sym_hashes,
251 h, sec, relocation,
252 unresolved_reloc, warned, ignored);
254 name = h->root.root.string;
257 if (sec != NULL && discarded_section (sec))
258 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
259 rel, 1, relend, howto, 0, contents);
261 if (bfd_link_relocatable (info))
262 continue;
264 r = moxie_final_link_relocate (howto, input_bfd, input_section,
265 contents, rel, relocation);
267 if (r != bfd_reloc_ok)
269 const char * msg = NULL;
271 switch (r)
273 case bfd_reloc_overflow:
274 (*info->callbacks->reloc_overflow)
275 (info, (h ? &h->root : NULL), name, howto->name,
276 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
277 break;
279 case bfd_reloc_undefined:
280 (*info->callbacks->undefined_symbol)
281 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
282 break;
284 case bfd_reloc_outofrange:
285 msg = _("internal error: out of range error");
286 break;
288 case bfd_reloc_notsupported:
289 msg = _("internal error: unsupported relocation error");
290 break;
292 case bfd_reloc_dangerous:
293 msg = _("internal error: dangerous relocation");
294 break;
296 default:
297 msg = _("internal error: unknown error");
298 break;
301 if (msg)
302 (*info->callbacks->warning) (info, msg, name, input_bfd,
303 input_section, rel->r_offset);
307 return TRUE;
310 /* Return the section that should be marked against GC for a given
311 relocation. */
313 static asection *
314 moxie_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)
320 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
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. */
327 static bfd_boolean
328 moxie_elf_check_relocs (bfd *abfd,
329 struct bfd_link_info *info,
330 asection *sec,
331 const Elf_Internal_Rela *relocs)
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;
338 if (bfd_link_relocatable (info))
339 return TRUE;
341 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
342 sym_hashes = elf_sym_hashes (abfd);
344 rel_end = relocs + sec->reloc_count;
345 for (rel = relocs; rel < rel_end; rel++)
347 struct elf_link_hash_entry *h;
348 unsigned long r_symndx;
350 r_symndx = ELF32_R_SYM (rel->r_info);
351 if (r_symndx < symtab_hdr->sh_info)
352 h = NULL;
353 else
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;
360 /* PR15323, ref flags aren't set for references in the same
361 object. */
362 h->root.non_ir_ref_regular = 1;
366 return TRUE;
369 #define ELF_ARCH bfd_arch_moxie
370 #define ELF_MACHINE_CODE EM_MOXIE
371 #define ELF_MACHINE_ALT1 EM_MOXIE_OLD
372 #define ELF_MAXPAGESIZE 0x1
374 #define TARGET_BIG_SYM moxie_elf32_be_vec
375 #define TARGET_BIG_NAME "elf32-bigmoxie"
376 #define TARGET_LITTLE_SYM moxie_elf32_le_vec
377 #define TARGET_LITTLE_NAME "elf32-littlemoxie"
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
385 #define elf_backend_can_gc_sections 1
386 #define elf_backend_rela_normal 1
388 #define bfd_elf32_bfd_reloc_type_lookup moxie_reloc_type_lookup
389 #define bfd_elf32_bfd_reloc_name_lookup moxie_reloc_name_lookup
391 #include "elf32-target.h"