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. */
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 */
39 2, /* size (0 = byte, 1 = short, 2 = long) */
41 FALSE
, /* pc_relative */
43 complain_overflow_bitfield
, /* complain_on_overflow */
44 bfd_elf_generic_reloc
, /* special_function */
45 "R_MOXIE_NONE", /* name */
46 FALSE
, /* partial_inplace */
49 FALSE
), /* pcrel_offset */
51 /* A 32 bit absolute relocation. */
52 HOWTO (R_MOXIE_32
, /* type */
54 2, /* size (0 = byte, 1 = short, 2 = long) */
56 FALSE
, /* pc_relative */
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
)
87 for (i
= sizeof (moxie_reloc_map
) / sizeof (moxie_reloc_map
[0]);
89 if (moxie_reloc_map
[i
].bfd_reloc_val
== code
)
90 return & moxie_elf_howto_table
[moxie_reloc_map
[i
].moxie_reloc_val
];
95 static reloc_howto_type
*
96 moxie_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
, const char *r_name
)
101 i
< sizeof (moxie_elf_howto_table
) / sizeof (moxie_elf_howto_table
[0]);
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
];
110 /* Set the howto pointer for an MOXIE ELF reloc. */
113 moxie_info_to_howto_rela (bfd
*abfd ATTRIBUTE_UNUSED
,
115 Elf_Internal_Rela
*dst
)
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
,
130 asection
*input_section
,
132 Elf_Internal_Rela
*rel
,
135 bfd_reloc_status_type r
= bfd_reloc_ok
;
140 r
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
141 contents
, rel
->r_offset
,
142 relocation
, rel
->r_addend
);
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
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
179 moxie_elf_relocate_section (bfd
*output_bfd
,
180 struct bfd_link_info
*info
,
182 asection
*input_section
,
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
;
203 struct elf_link_hash_entry
*h
;
205 bfd_reloc_status_type r
;
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
);
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
;
230 bfd_boolean unresolved_reloc
, warned
;
232 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
233 r_symndx
, symtab_hdr
, sym_hashes
,
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
);
251 if (info
->relocatable
)
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
;
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
);
269 case bfd_reloc_undefined
:
270 r
= info
->callbacks
->undefined_symbol
271 (info
, name
, input_bfd
, input_section
, rel
->r_offset
,
275 case bfd_reloc_outofrange
:
276 msg
= _("internal error: out of range error");
279 case bfd_reloc_notsupported
:
280 msg
= _("internal error: unsupported relocation error");
283 case bfd_reloc_dangerous
:
284 msg
= _("internal error: dangerous relocation");
288 msg
= _("internal error: unknown error");
293 r
= info
->callbacks
->warning
294 (info
, msg
, name
, input_bfd
, input_section
, rel
->r_offset
);
304 /* Return the section that should be marked against GC for a given
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. */
322 moxie_elf_check_relocs (bfd
*abfd
,
323 struct bfd_link_info
*info
,
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
)
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
)
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
;
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"