Rename non_ir_ref to non_ir_ref_regular
[external/binutils.git] / bfd / elf32-moxie.c
1 /* moxie-specific support for 32-bit ELF.
2    Copyright (C) 2009-2017 Free Software Foundation, Inc.
3
4    Copied from elf32-fr30.c which is..
5    Copyright (C) 1998-2017 Free Software Foundation, Inc.
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
32 static reloc_howto_type moxie_elf_howto_table [] =
33 {
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 */
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 */
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.  */
78 };
79 \f
80 /* Map BFD reloc types to MOXIE ELF reloc types.  */
81
82 struct moxie_reloc_map
83 {
84   bfd_reloc_code_real_type bfd_reloc_val;
85   unsigned int moxie_reloc_val;
86 };
87
88 static const struct moxie_reloc_map moxie_reloc_map [] =
89 {
90   { BFD_RELOC_NONE,            R_MOXIE_NONE },
91   { BFD_RELOC_32,              R_MOXIE_32 },
92   { BFD_RELOC_MOXIE_10_PCREL,  R_MOXIE_PCREL10 },
93 };
94
95 static reloc_howto_type *
96 moxie_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]);
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];
105
106   return NULL;
107 }
108
109 static reloc_howto_type *
110 moxie_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
126 static void
127 moxie_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);
134   if (r_type >= (unsigned int) R_MOXIE_max)
135     {
136       /* xgettext:c-format */
137       _bfd_error_handler (_("%B: invalid Moxie reloc number: %d"), abfd, r_type);
138       r_type = 0;
139     }
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
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)
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
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)
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);
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;
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         {
247           bfd_boolean unresolved_reloc, warned, ignored;
248
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);
253
254           name = h->root.root.string;
255         }
256
257       if (sec != NULL && discarded_section (sec))
258         RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
259                                          rel, 1, relend, howto, 0, contents);
260
261       if (bfd_link_relocatable (info))
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:
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;
278
279             case bfd_reloc_undefined:
280               (*info->callbacks->undefined_symbol)
281                 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
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)
302             (*info->callbacks->warning) (info, msg, name, input_bfd,
303                                          input_section, rel->r_offset);
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
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)
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
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)
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
338   if (bfd_link_relocatable (info))
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;
359
360           /* PR15323, ref flags aren't set for references in the same
361              object.  */
362           h->root.non_ir_ref_regular = 1;
363         }
364     }
365
366   return TRUE;
367 }
368 \f
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
373
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"
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"