Remove a white space.
[binutils.git] / bfd / elf32-moxie.c
blobe3f01d2e8cad25776ec4ab382c89e2059d2dbf6b
1 /* moxie-specific support for 32-bit ELF.
2 Copyright 2008 Anthony Green.
3 Copyright 2009 Free Software Foundation, Inc.
5 Copied from elf32-fr30.c which is..
6 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
7 Free Software Foundation, Inc.
9 This file is part of BFD, the Binary File Descriptor library.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
24 MA 02110-1301, USA. */
26 #include "sysdep.h"
27 #include "bfd.h"
28 #include "libbfd.h"
29 #include "elf-bfd.h"
30 #include "elf/moxie.h"
32 /* Forward declarations. */
34 static reloc_howto_type moxie_elf_howto_table [] =
36 /* This reloc does nothing. */
37 HOWTO (R_MOXIE_NONE, /* type */
38 0, /* rightshift */
39 2, /* size (0 = byte, 1 = short, 2 = long) */
40 32, /* bitsize */
41 FALSE, /* pc_relative */
42 0, /* bitpos */
43 complain_overflow_bitfield, /* complain_on_overflow */
44 bfd_elf_generic_reloc, /* special_function */
45 "R_MOXIE_NONE", /* name */
46 FALSE, /* partial_inplace */
47 0, /* src_mask */
48 0, /* dst_mask */
49 FALSE), /* pcrel_offset */
51 /* A 32 bit absolute relocation. */
52 HOWTO (R_MOXIE_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_MOXIE_32", /* name */
61 FALSE, /* partial_inplace */
62 0x00000000, /* src_mask */
63 0xffffffff, /* dst_mask */
64 FALSE), /* pcrel_offset */
67 /* Map BFD reloc types to MOXIE ELF reloc types. */
69 struct moxie_reloc_map
71 bfd_reloc_code_real_type bfd_reloc_val;
72 unsigned int moxie_reloc_val;
75 static const struct moxie_reloc_map moxie_reloc_map [] =
77 { BFD_RELOC_NONE, R_MOXIE_NONE },
78 { BFD_RELOC_32, R_MOXIE_32 },
81 static reloc_howto_type *
82 moxie_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
83 bfd_reloc_code_real_type code)
85 unsigned int i;
87 for (i = sizeof (moxie_reloc_map) / sizeof (moxie_reloc_map[0]);
88 --i;)
89 if (moxie_reloc_map [i].bfd_reloc_val == code)
90 return & moxie_elf_howto_table [moxie_reloc_map[i].moxie_reloc_val];
92 return NULL;
95 static reloc_howto_type *
96 moxie_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
98 unsigned int i;
100 for (i = 0;
101 i < sizeof (moxie_elf_howto_table) / sizeof (moxie_elf_howto_table[0]);
102 i++)
103 if (moxie_elf_howto_table[i].name != NULL
104 && strcasecmp (moxie_elf_howto_table[i].name, r_name) == 0)
105 return &moxie_elf_howto_table[i];
107 return NULL;
110 /* Set the howto pointer for an MOXIE ELF reloc. */
112 static void
113 moxie_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
114 arelent *cache_ptr,
115 Elf_Internal_Rela *dst)
117 unsigned int r_type;
119 r_type = ELF32_R_TYPE (dst->r_info);
120 BFD_ASSERT (r_type < (unsigned int) R_MOXIE_max);
121 cache_ptr->howto = & moxie_elf_howto_table [r_type];
124 /* Perform a single relocation. By default we use the standard BFD
125 routines, but a few relocs, we have to do them ourselves. */
127 static bfd_reloc_status_type
128 moxie_final_link_relocate (reloc_howto_type *howto,
129 bfd *input_bfd,
130 asection *input_section,
131 bfd_byte *contents,
132 Elf_Internal_Rela *rel,
133 bfd_vma relocation)
135 bfd_reloc_status_type r = bfd_reloc_ok;
137 switch (howto->type)
139 default:
140 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
141 contents, rel->r_offset,
142 relocation, rel->r_addend);
145 return r;
148 /* Relocate an MOXIE ELF section.
150 The RELOCATE_SECTION function is called by the new ELF backend linker
151 to handle the relocations for a section.
153 The relocs are always passed as Rela structures; if the section
154 actually uses Rel structures, the r_addend field will always be
155 zero.
157 This function is responsible for adjusting the section contents as
158 necessary, and (if using Rela relocs and generating a relocatable
159 output file) adjusting the reloc addend as necessary.
161 This function does not have to worry about setting the reloc
162 address or the reloc symbol index.
164 LOCAL_SYMS is a pointer to the swapped in local symbols.
166 LOCAL_SECTIONS is an array giving the section in the input file
167 corresponding to the st_shndx field of each local symbol.
169 The global hash table entry for the global symbols can be found
170 via elf_sym_hashes (input_bfd).
172 When generating relocatable output, this function must handle
173 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
174 going to be the section symbol corresponding to the output
175 section, which means that the addend must be adjusted
176 accordingly. */
178 static bfd_boolean
179 moxie_elf_relocate_section (bfd *output_bfd,
180 struct bfd_link_info *info,
181 bfd *input_bfd,
182 asection *input_section,
183 bfd_byte *contents,
184 Elf_Internal_Rela *relocs,
185 Elf_Internal_Sym *local_syms,
186 asection **local_sections)
188 Elf_Internal_Shdr *symtab_hdr;
189 struct elf_link_hash_entry **sym_hashes;
190 Elf_Internal_Rela *rel;
191 Elf_Internal_Rela *relend;
193 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
194 sym_hashes = elf_sym_hashes (input_bfd);
195 relend = relocs + input_section->reloc_count;
197 for (rel = relocs; rel < relend; rel ++)
199 reloc_howto_type *howto;
200 unsigned long r_symndx;
201 Elf_Internal_Sym *sym;
202 asection *sec;
203 struct elf_link_hash_entry *h;
204 bfd_vma relocation;
205 bfd_reloc_status_type r;
206 const char *name;
207 int r_type;
209 r_type = ELF32_R_TYPE (rel->r_info);
211 r_symndx = ELF32_R_SYM (rel->r_info);
213 howto = moxie_elf_howto_table + ELF32_R_TYPE (rel->r_info);
214 h = NULL;
215 sym = NULL;
216 sec = NULL;
218 if (r_symndx < symtab_hdr->sh_info)
220 sym = local_syms + r_symndx;
221 sec = local_sections [r_symndx];
222 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
224 name = bfd_elf_string_from_elf_section
225 (input_bfd, symtab_hdr->sh_link, sym->st_name);
226 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
228 else
230 bfd_boolean unresolved_reloc, warned;
232 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
233 r_symndx, symtab_hdr, sym_hashes,
234 h, sec, relocation,
235 unresolved_reloc, warned);
237 name = h->root.root.string;
240 if (sec != NULL && elf_discarded_section (sec))
242 /* For relocs against symbols from removed linkonce sections,
243 or sections discarded by a linker script, we just want the
244 section contents zeroed. Avoid any special processing. */
245 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
246 rel->r_info = 0;
247 rel->r_addend = 0;
248 continue;
251 if (info->relocatable)
252 continue;
254 r = moxie_final_link_relocate (howto, input_bfd, input_section,
255 contents, rel, relocation);
257 if (r != bfd_reloc_ok)
259 const char * msg = NULL;
261 switch (r)
263 case bfd_reloc_overflow:
264 r = info->callbacks->reloc_overflow
265 (info, (h ? &h->root : NULL), name, howto->name,
266 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
267 break;
269 case bfd_reloc_undefined:
270 r = info->callbacks->undefined_symbol
271 (info, name, input_bfd, input_section, rel->r_offset,
272 TRUE);
273 break;
275 case bfd_reloc_outofrange:
276 msg = _("internal error: out of range error");
277 break;
279 case bfd_reloc_notsupported:
280 msg = _("internal error: unsupported relocation error");
281 break;
283 case bfd_reloc_dangerous:
284 msg = _("internal error: dangerous relocation");
285 break;
287 default:
288 msg = _("internal error: unknown error");
289 break;
292 if (msg)
293 r = info->callbacks->warning
294 (info, msg, name, input_bfd, input_section, rel->r_offset);
296 if (! r)
297 return FALSE;
301 return TRUE;
304 /* Return the section that should be marked against GC for a given
305 relocation. */
307 static asection *
308 moxie_elf_gc_mark_hook (asection *sec,
309 struct bfd_link_info *info,
310 Elf_Internal_Rela *rel,
311 struct elf_link_hash_entry *h,
312 Elf_Internal_Sym *sym)
314 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
317 /* Look through the relocs for a section during the first phase.
318 Since we don't do .gots or .plts, we just need to consider the
319 virtual table relocs for gc. */
321 static bfd_boolean
322 moxie_elf_check_relocs (bfd *abfd,
323 struct bfd_link_info *info,
324 asection *sec,
325 const Elf_Internal_Rela *relocs)
327 Elf_Internal_Shdr *symtab_hdr;
328 struct elf_link_hash_entry **sym_hashes;
329 const Elf_Internal_Rela *rel;
330 const Elf_Internal_Rela *rel_end;
332 if (info->relocatable)
333 return TRUE;
335 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
336 sym_hashes = elf_sym_hashes (abfd);
338 rel_end = relocs + sec->reloc_count;
339 for (rel = relocs; rel < rel_end; rel++)
341 struct elf_link_hash_entry *h;
342 unsigned long r_symndx;
344 r_symndx = ELF32_R_SYM (rel->r_info);
345 if (r_symndx < symtab_hdr->sh_info)
346 h = NULL;
347 else
349 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
350 while (h->root.type == bfd_link_hash_indirect
351 || h->root.type == bfd_link_hash_warning)
352 h = (struct elf_link_hash_entry *) h->root.u.i.link;
356 return TRUE;
359 #define ELF_ARCH bfd_arch_moxie
360 #define ELF_MACHINE_CODE EM_MOXIE
361 #define ELF_MAXPAGESIZE 0x1
363 #define TARGET_BIG_SYM bfd_elf32_moxie_vec
364 #define TARGET_BIG_NAME "elf32-moxie"
366 #define elf_info_to_howto_rel NULL
367 #define elf_info_to_howto moxie_info_to_howto_rela
368 #define elf_backend_relocate_section moxie_elf_relocate_section
369 #define elf_backend_gc_mark_hook moxie_elf_gc_mark_hook
370 #define elf_backend_check_relocs moxie_elf_check_relocs
372 #define elf_backend_can_gc_sections 1
373 #define elf_backend_rela_normal 1
375 #define bfd_elf32_bfd_reloc_type_lookup moxie_reloc_type_lookup
376 #define bfd_elf32_bfd_reloc_name_lookup moxie_reloc_name_lookup
378 #include "elf32-target.h"