fix set but unused variable warnings
[external/binutils.git] / bfd / elf32-moxie.c
1 /* moxie-specific support for 32-bit ELF.
2    Copyright 2009, 2010 Free Software Foundation, Inc.
3
4    Copied from elf32-fr30.c which is..
5    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
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/moxie.h"
30
31 /* Forward declarations.  */
32
33 static reloc_howto_type moxie_elf_howto_table [] =
34 {
35   /* This reloc does nothing.  */
36   HOWTO (R_MOXIE_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_MOXIE_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   HOWTO (R_MOXIE_32,            /* type */
52          0,                     /* rightshift */
53          2,                     /* size (0 = byte, 1 = short, 2 = long) */
54          32,                    /* bitsize */
55          FALSE,                 /* pc_relative */
56          0,                     /* bitpos */
57          complain_overflow_bitfield, /* complain_on_overflow */
58          bfd_elf_generic_reloc, /* special_function */
59          "R_MOXIE_32",          /* name */
60          FALSE,                 /* partial_inplace */
61          0x00000000,            /* src_mask */
62          0xffffffff,            /* dst_mask */
63          FALSE),                /* pcrel_offset */
64
65   /* A 10 bit PC-relative relocation.  */
66   HOWTO (R_MOXIE_PCREL10,       /* type.  */
67          1,                     /* rightshift.  */
68          1,                     /* size (0 = byte, 1 = short, 2 = long).  */
69          10,                    /* bitsize.  */
70          TRUE,                  /* pc_relative.  */
71          0,                     /* bitpos.  */
72          complain_overflow_signed, /* complain_on_overflow.  */
73          bfd_elf_generic_reloc, /* special_function.  */
74          "R_MOXIE_PCREL10",             /* name.  */
75          FALSE,                 /* partial_inplace.  */
76          0,                     /* src_mask.  */
77          0x000003FF,            /* dst_mask.  */
78          TRUE),                 /* pcrel_offset.  */
79 };
80 \f
81 /* Map BFD reloc types to MOXIE ELF reloc types.  */
82
83 struct moxie_reloc_map
84 {
85   bfd_reloc_code_real_type bfd_reloc_val;
86   unsigned int moxie_reloc_val;
87 };
88
89 static const struct moxie_reloc_map moxie_reloc_map [] =
90 {
91   { BFD_RELOC_NONE,            R_MOXIE_NONE },
92   { BFD_RELOC_32,              R_MOXIE_32 },
93   { BFD_RELOC_MOXIE_10_PCREL,  R_MOXIE_PCREL10 },
94 };
95
96 static reloc_howto_type *
97 moxie_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
98                          bfd_reloc_code_real_type code)
99 {
100   unsigned int i;
101
102   for (i = sizeof (moxie_reloc_map) / sizeof (moxie_reloc_map[0]);
103        --i;)
104     if (moxie_reloc_map [i].bfd_reloc_val == code)
105       return & moxie_elf_howto_table [moxie_reloc_map[i].moxie_reloc_val];
106
107   return NULL;
108 }
109
110 static reloc_howto_type *
111 moxie_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
112 {
113   unsigned int i;
114
115   for (i = 0;
116        i < sizeof (moxie_elf_howto_table) / sizeof (moxie_elf_howto_table[0]);
117        i++)
118     if (moxie_elf_howto_table[i].name != NULL
119         && strcasecmp (moxie_elf_howto_table[i].name, r_name) == 0)
120       return &moxie_elf_howto_table[i];
121
122   return NULL;
123 }
124
125 /* Set the howto pointer for an MOXIE ELF reloc.  */
126
127 static void
128 moxie_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
129                           arelent *cache_ptr,
130                           Elf_Internal_Rela *dst)
131 {
132   unsigned int r_type;
133
134   r_type = ELF32_R_TYPE (dst->r_info);
135   BFD_ASSERT (r_type < (unsigned int) R_MOXIE_max);
136   cache_ptr->howto = & moxie_elf_howto_table [r_type];
137 }
138 \f
139 /* Perform a single relocation.  By default we use the standard BFD
140    routines, but a few relocs, we have to do them ourselves.  */
141
142 static bfd_reloc_status_type
143 moxie_final_link_relocate (reloc_howto_type *howto,
144                            bfd *input_bfd,
145                            asection *input_section,
146                            bfd_byte *contents,
147                            Elf_Internal_Rela *rel,
148                            bfd_vma relocation)
149 {
150   bfd_reloc_status_type r = bfd_reloc_ok;
151
152   switch (howto->type)
153     {
154     default:
155       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
156                                     contents, rel->r_offset,
157                                     relocation, rel->r_addend);
158     }
159
160   return r;
161 }
162 \f
163 /* Relocate an MOXIE ELF section.
164
165    The RELOCATE_SECTION function is called by the new ELF backend linker
166    to handle the relocations for a section.
167
168    The relocs are always passed as Rela structures; if the section
169    actually uses Rel structures, the r_addend field will always be
170    zero.
171
172    This function is responsible for adjusting the section contents as
173    necessary, and (if using Rela relocs and generating a relocatable
174    output file) adjusting the reloc addend as necessary.
175
176    This function does not have to worry about setting the reloc
177    address or the reloc symbol index.
178
179    LOCAL_SYMS is a pointer to the swapped in local symbols.
180
181    LOCAL_SECTIONS is an array giving the section in the input file
182    corresponding to the st_shndx field of each local symbol.
183
184    The global hash table entry for the global symbols can be found
185    via elf_sym_hashes (input_bfd).
186
187    When generating relocatable output, this function must handle
188    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
189    going to be the section symbol corresponding to the output
190    section, which means that the addend must be adjusted
191    accordingly.  */
192
193 static bfd_boolean
194 moxie_elf_relocate_section (bfd *output_bfd,
195                             struct bfd_link_info *info,
196                             bfd *input_bfd,
197                             asection *input_section,
198                             bfd_byte *contents,
199                             Elf_Internal_Rela *relocs,
200                             Elf_Internal_Sym *local_syms,
201                             asection **local_sections)
202 {
203   Elf_Internal_Shdr *symtab_hdr;
204   struct elf_link_hash_entry **sym_hashes;
205   Elf_Internal_Rela *rel;
206   Elf_Internal_Rela *relend;
207
208   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
209   sym_hashes = elf_sym_hashes (input_bfd);
210   relend     = relocs + input_section->reloc_count;
211
212   for (rel = relocs; rel < relend; rel ++)
213     {
214       reloc_howto_type *howto;
215       unsigned long r_symndx;
216       Elf_Internal_Sym *sym;
217       asection *sec;
218       struct elf_link_hash_entry *h;
219       bfd_vma relocation;
220       bfd_reloc_status_type r;
221       const char *name;
222       int r_type;
223
224       r_type = ELF32_R_TYPE (rel->r_info);
225       r_symndx = ELF32_R_SYM (rel->r_info);
226       howto  = moxie_elf_howto_table + r_type;
227       h      = NULL;
228       sym    = NULL;
229       sec    = NULL;
230
231       if (r_symndx < symtab_hdr->sh_info)
232         {
233           sym = local_syms + r_symndx;
234           sec = local_sections [r_symndx];
235           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
236
237           name = bfd_elf_string_from_elf_section
238             (input_bfd, symtab_hdr->sh_link, sym->st_name);
239           name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
240         }
241       else
242         {
243           bfd_boolean unresolved_reloc, warned;
244
245           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
246                                    r_symndx, symtab_hdr, sym_hashes,
247                                    h, sec, relocation,
248                                    unresolved_reloc, warned);
249
250           name = h->root.root.string;
251         }
252
253       if (sec != NULL && elf_discarded_section (sec))
254         {
255           /* For relocs against symbols from removed linkonce sections,
256              or sections discarded by a linker script, we just want the
257              section contents zeroed.  Avoid any special processing.  */
258           _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
259           rel->r_info = 0;
260           rel->r_addend = 0;
261           continue;
262         }
263
264       if (info->relocatable)
265         continue;
266
267       r = moxie_final_link_relocate (howto, input_bfd, input_section,
268                                      contents, rel, relocation);
269
270       if (r != bfd_reloc_ok)
271         {
272           const char * msg = NULL;
273
274           switch (r)
275             {
276             case bfd_reloc_overflow:
277               r = info->callbacks->reloc_overflow
278                 (info, (h ? &h->root : NULL), name, howto->name,
279                  (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
280               break;
281
282             case bfd_reloc_undefined:
283               r = info->callbacks->undefined_symbol
284                 (info, name, input_bfd, input_section, rel->r_offset,
285                  TRUE);
286               break;
287
288             case bfd_reloc_outofrange:
289               msg = _("internal error: out of range error");
290               break;
291
292             case bfd_reloc_notsupported:
293               msg = _("internal error: unsupported relocation error");
294               break;
295
296             case bfd_reloc_dangerous:
297               msg = _("internal error: dangerous relocation");
298               break;
299
300             default:
301               msg = _("internal error: unknown error");
302               break;
303             }
304
305           if (msg)
306             r = info->callbacks->warning
307               (info, msg, name, input_bfd, input_section, rel->r_offset);
308
309           if (! r)
310             return FALSE;
311         }
312     }
313
314   return TRUE;
315 }
316 \f
317 /* Return the section that should be marked against GC for a given
318    relocation.  */
319
320 static asection *
321 moxie_elf_gc_mark_hook (asection *sec,
322                         struct bfd_link_info *info,
323                         Elf_Internal_Rela *rel,
324                         struct elf_link_hash_entry *h,
325                         Elf_Internal_Sym *sym)
326 {
327   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
328 }
329
330 /* Look through the relocs for a section during the first phase.
331    Since we don't do .gots or .plts, we just need to consider the
332    virtual table relocs for gc.  */
333
334 static bfd_boolean
335 moxie_elf_check_relocs (bfd *abfd,
336                         struct bfd_link_info *info,
337                         asection *sec,
338                         const Elf_Internal_Rela *relocs)
339 {
340   Elf_Internal_Shdr *symtab_hdr;
341   struct elf_link_hash_entry **sym_hashes;
342   const Elf_Internal_Rela *rel;
343   const Elf_Internal_Rela *rel_end;
344
345   if (info->relocatable)
346     return TRUE;
347
348   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
349   sym_hashes = elf_sym_hashes (abfd);
350
351   rel_end = relocs + sec->reloc_count;
352   for (rel = relocs; rel < rel_end; rel++)
353     {
354       struct elf_link_hash_entry *h;
355       unsigned long r_symndx;
356
357       r_symndx = ELF32_R_SYM (rel->r_info);
358       if (r_symndx < symtab_hdr->sh_info)
359         h = NULL;
360       else
361         {
362           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
363           while (h->root.type == bfd_link_hash_indirect
364                  || h->root.type == bfd_link_hash_warning)
365             h = (struct elf_link_hash_entry *) h->root.u.i.link;
366         }
367     }
368
369   return TRUE;
370 }
371 \f
372 #define ELF_ARCH                bfd_arch_moxie
373 #define ELF_MACHINE_CODE        EM_MOXIE
374 #define ELF_MAXPAGESIZE         0x1
375
376 #define TARGET_BIG_SYM          bfd_elf32_moxie_vec
377 #define TARGET_BIG_NAME         "elf32-moxie"
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"