Automatic date update in version.in
[external/binutils.git] / bfd / elf64-nfp.c
1 /* NFP-specific support for 64-bit ELF
2    Copyright (C) 2017-2018 Free Software Foundation, Inc.
3    Contributed by Francois H. Theron <francois.theron@netronome.com>
4
5    This file is part of BFD, the Binary File Descriptor library.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street - Fifth Floor,
20    Boston, MA 02110-1301, USA.  */
21
22 #include "sysdep.h"
23 #include "bfd.h"
24 #include "libbfd.h"
25 #include "elf-bfd.h"
26 #include "elf/nfp.h"
27 #include "bfd_stdint.h"
28
29
30 static bfd_reloc_status_type
31 elf64_nfp_reloc (bfd * abfd ATTRIBUTE_UNUSED,
32                  arelent * reloc_entry,
33                  asymbol * symbol,
34                  void *data ATTRIBUTE_UNUSED,
35                  asection * input_section,
36                  bfd * output_bfd,
37                  char **error_message ATTRIBUTE_UNUSED);
38
39 /* We don't actually apply any relocations in this toolset
40    so we make them all do nothing, but at least display useful
41    names.
42    Most of these are mainly used by the NFP toolchain to resolve things
43    before the final ELF file is created.  */
44 static reloc_howto_type elf_nfp_howto_table[] =
45 {
46   HOWTO (R_NFP_NOTYPE,          /* Type.  */
47          0,                     /* Rightshift.  */
48          3,                     /* Size.  */
49          0,                     /* Bitsize.  */
50          FALSE,                 /* PC_relative.  */
51          0,                     /* Bitpos.  */
52          complain_overflow_dont,/* Complain_on_overflow.  */
53          elf64_nfp_reloc,       /* Special_function.  */
54          "R_NFP_NOTYPE",        /* Name.  */
55          FALSE,                 /* Partial_inplace.  */
56          0,                     /* Src_mask.  */
57          0,                     /* Dst_mask.  */
58          FALSE),                /* PCrel_offset.  */
59   HOWTO (R_NFP_W32LE, 0, 3, 0, FALSE, 0,
60          complain_overflow_dont, elf64_nfp_reloc,
61          "R_NFP_W32LE",
62          FALSE, 0, 0, FALSE),
63   HOWTO (R_NFP_SRC8_A, 0, 3, 0, FALSE, 0,
64          complain_overflow_dont, elf64_nfp_reloc,
65          "R_NFP_SRC8_A",
66          FALSE, 0, 0, FALSE),
67   HOWTO (R_NFP_SRC8_B, 0, 3, 0, FALSE, 0,
68          complain_overflow_dont, elf64_nfp_reloc,
69          "R_NFP_SRC8_B",
70          FALSE, 0, 0, FALSE),
71   HOWTO (R_NFP_IMMED8_I, 0, 3, 0, FALSE, 0,
72          complain_overflow_dont, elf64_nfp_reloc,
73          "R_NFP_IMMED8_I",
74          FALSE, 0, 0, FALSE),
75   HOWTO (R_NFP_SC, 0, 3, 0, FALSE, 0,
76          complain_overflow_dont, elf64_nfp_reloc,
77          "R_NFP_SC",
78          FALSE, 0, 0, FALSE),
79   HOWTO (R_NFP_IMMED_LO16_I_A, 0, 3, 0, FALSE, 0,
80          complain_overflow_dont, elf64_nfp_reloc,
81          "R_NFP_IMMED_LO16_I_A",
82          FALSE, 0, 0, FALSE),
83   HOWTO (R_NFP_IMMED_LO16_I_B, 0, 3, 0, FALSE, 0,
84          complain_overflow_dont, elf64_nfp_reloc,
85          "R_NFP_IMMED_LO16_I_B",
86          TRUE, 0, 0, FALSE),
87   HOWTO (R_NFP_SRC7_B, 0, 3, 0, FALSE, 0,
88          complain_overflow_dont, elf64_nfp_reloc,
89          "R_NFP_SRC7_B",
90          FALSE, 0, 0, FALSE),
91   HOWTO (R_NFP_SRC7_A, 0, 3, 0, FALSE, 0,
92          complain_overflow_dont, elf64_nfp_reloc,
93          "R_NFP_SRC7_A",
94          FALSE, 0, 0, FALSE),
95   HOWTO (R_NFP_SRC8_I_B, 0, 3, 0, FALSE, 0,
96          complain_overflow_dont, elf64_nfp_reloc,
97          "R_NFP_SRC8_I_B",
98          FALSE, 0, 0, FALSE),
99   HOWTO (R_NFP_SRC8_I_A, 0, 3, 0, FALSE, 0,
100          complain_overflow_dont, elf64_nfp_reloc,
101          "R_NFP_SRC8_I_A",
102          FALSE, 0, 0, FALSE),
103   HOWTO (R_NFP_IMMED_HI16_I_A, 0, 3, 0, FALSE, 0,
104          complain_overflow_dont, elf64_nfp_reloc,
105          "R_NFP_IMMED_HI16_I_A",
106          FALSE, 0, 0, FALSE),
107   HOWTO (R_NFP_IMMED_HI16_I_B, 0, 3, 0, FALSE, 0,
108          complain_overflow_dont, elf64_nfp_reloc,
109          "R_NFP_IMMED_HI16_I_B",
110          FALSE, 0, 0, FALSE),
111   HOWTO (R_NFP_W64LE, 0, 3, 0, FALSE, 0,
112          complain_overflow_dont, elf64_nfp_reloc,
113          "R_NFP_W64LE",
114          FALSE, 0, 0, FALSE),
115   HOWTO (R_NFP_SH_INFO, 0, 3, 0, FALSE, 0,
116          complain_overflow_dont, elf64_nfp_reloc,
117          "R_NFP_SH_INFO",
118          FALSE, 0, 0, FALSE),
119   HOWTO (R_NFP_W32BE, 0, 3, 0, FALSE, 0,
120          complain_overflow_dont, elf64_nfp_reloc,
121          "R_NFP_W32BE",
122          FALSE, 0, 0, FALSE),
123   HOWTO (R_NFP_W64BE, 0, 3, 0, FALSE, 0,
124          complain_overflow_dont, elf64_nfp_reloc,
125          "R_NFP_W64BE",
126          FALSE, 0, 0, FALSE),
127   HOWTO (R_NFP_W32_29_24, 0, 3, 0, FALSE, 0,
128          complain_overflow_dont, elf64_nfp_reloc,
129          "R_NFP_W32_29_24",
130          FALSE, 0, 0, FALSE),
131   HOWTO (R_NFP_W32LE_AND, 0, 3, 0, FALSE, 0,
132          complain_overflow_dont, elf64_nfp_reloc,
133          "R_NFP_W32LE_AND",
134          FALSE, 0, 0, FALSE),
135   HOWTO (R_NFP_W32BE_AND, 0, 3, 0, FALSE, 0,
136          complain_overflow_dont, elf64_nfp_reloc,
137          "R_NFP_W32BE_AND",
138          FALSE, 0, 0, FALSE),
139   HOWTO (R_NFP_W32LE_OR, 0, 3, 0, FALSE, 0,
140          complain_overflow_dont, elf64_nfp_reloc,
141          "R_NFP_W32LE_OR",
142          FALSE, 0, 0, FALSE),
143   HOWTO (R_NFP_W32BE_OR, 0, 3, 0, FALSE, 0,
144          complain_overflow_dont, elf64_nfp_reloc,
145          "R_NFP_W32BE_OR",
146          FALSE, 0, 0, FALSE),
147   HOWTO (R_NFP_W64LE_AND, 0, 3, 0, FALSE, 0,
148          complain_overflow_dont, elf64_nfp_reloc,
149          "R_NFP_W64LE_AND",
150          FALSE, 0, 0, FALSE),
151   HOWTO (R_NFP_W64BE_AND, 0, 3, 0, FALSE, 0,
152          complain_overflow_dont, elf64_nfp_reloc,
153          "R_NFP_W64BE_AND",
154          FALSE, 0, 0, FALSE),
155   HOWTO (R_NFP_W64LE_OR, 0, 3, 0, FALSE, 0,
156          complain_overflow_dont, elf64_nfp_reloc,
157          "R_NFP_W64LE_OR",
158          FALSE, 0, 0, FALSE),
159   HOWTO (R_NFP_W64BE_OR, 0, 3, 0, FALSE, 0,
160          complain_overflow_dont, elf64_nfp_reloc,
161          "R_NFP_W64BE_OR",
162          FALSE, 0, 0, FALSE)
163 };
164
165 static bfd_boolean
166 elf64_nfp_object_p (bfd * abfd)
167 {
168   /* If the e_machine value is one of the unofficial ones, we convert
169      it first and set e_flags accordingly for later consistency.  */
170   if (elf_elfheader (abfd)->e_machine == E_NFP_MACH_3200)
171     {
172       elf_elfheader (abfd)->e_machine = EM_NFP;
173       elf_elfheader (abfd)->e_flags &= ~EF_NFP_SET_MACH (~0);
174       elf_elfheader (abfd)->e_flags |= EF_NFP_SET_MACH (E_NFP_MACH_3200);
175     }
176   else if (elf_elfheader (abfd)->e_machine == E_NFP_MACH_6000)
177     {
178       elf_elfheader (abfd)->e_machine = EM_NFP;
179       elf_elfheader (abfd)->e_flags &= ~EF_NFP_SET_MACH (~0);
180       elf_elfheader (abfd)->e_flags |= EF_NFP_SET_MACH (E_NFP_MACH_6000);
181     }
182
183   if (elf_elfheader (abfd)->e_machine == EM_NFP)
184     {
185       int e_mach = EF_NFP_MACH (elf_elfheader (abfd)->e_flags);
186
187       switch (e_mach)
188         {
189         case E_NFP_MACH_3200:
190         case E_NFP_MACH_6000:
191           if (!bfd_default_set_arch_mach (abfd, bfd_arch_nfp, e_mach))
192             return FALSE;
193         default:
194           break;
195         }
196     }
197
198   return TRUE;
199 }
200
201 static bfd_boolean
202 elf64_nfp_section_from_shdr (bfd * abfd,
203                              Elf_Internal_Shdr * hdr,
204                              const char *name, int shindex)
205 {
206   switch (hdr->sh_type)
207     {
208     case SHT_NFP_INITREG:
209     case SHT_NFP_MECONFIG:
210     case SHT_NFP_UDEBUG:
211       return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
212     default:
213       return FALSE;
214     }
215 }
216
217 bfd_reloc_status_type
218 elf64_nfp_reloc (bfd * abfd ATTRIBUTE_UNUSED,
219                  arelent * reloc_entry ATTRIBUTE_UNUSED,
220                  asymbol * symbol ATTRIBUTE_UNUSED,
221                  void *data ATTRIBUTE_UNUSED,
222                  asection * input_section ATTRIBUTE_UNUSED,
223                  bfd * output_bfd ATTRIBUTE_UNUSED,
224                  char **error_message ATTRIBUTE_UNUSED)
225 {
226   return bfd_reloc_ok;
227 }
228
229 static bfd_boolean
230 elf64_nfp_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
231                          arelent * cache_ptr, Elf_Internal_Rela * dst)
232 {
233   unsigned int r_type;
234
235   r_type = ELF64_R_TYPE (dst->r_info);
236   if (r_type >= R_NFP_MAX)
237     {
238       /* xgettext:c-format */
239       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
240                           abfd, r_type);
241       bfd_set_error (bfd_error_bad_value);
242       return FALSE;
243     }
244   cache_ptr->howto = &elf_nfp_howto_table[r_type];
245   return TRUE;
246 }
247
248 static reloc_howto_type *
249 elf64_nfp_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
250                              bfd_reloc_code_real_type code ATTRIBUTE_UNUSED)
251 {
252   return NULL;
253 }
254
255 static reloc_howto_type *
256 elf64_nfp_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED,
257                              const char *r_name ATTRIBUTE_UNUSED)
258 {
259   return NULL;
260 }
261
262 #define ELF_ARCH                bfd_arch_nfp
263 #define ELF_MACHINE_CODE        EM_NFP
264 #define ELF_MACHINE_ALT1        E_NFP_MACH_6000
265 #define ELF_MACHINE_ALT2        E_NFP_MACH_3200
266 #define ELF_MAXPAGESIZE         1
267 #define TARGET_LITTLE_NAME      "elf64-nfp"
268 #define TARGET_LITTLE_SYM       nfp_elf64_vec
269
270 #define elf_backend_object_p            elf64_nfp_object_p
271 #define elf_backend_section_from_shdr   elf64_nfp_section_from_shdr
272 #define elf_info_to_howto               elf64_nfp_info_to_howto
273 #define bfd_elf64_bfd_reloc_type_lookup      elf64_nfp_reloc_type_lookup
274 #define bfd_elf64_bfd_reloc_name_lookup      elf64_nfp_reloc_name_lookup
275
276 #include "elf64-target.h"