4b92b7794f377919799fea8dbed122ca43498891
[deliverable/binutils-gdb.git] / gas / config / tc-bpf.c
1 /* tc-bpf.c -- Assembler for the Linux eBPF.
2 Copyright (C) 2019 Free Software Foundation, Inc.
3 Contributed by Oracle, Inc.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS 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, or (at your option)
10 any later version.
11
12 GAS 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 GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
21
22 #include "as.h"
23 #include "subsegs.h"
24 #include "symcat.h"
25 #include "opcodes/bpf-desc.h"
26 #include "opcodes/bpf-opc.h"
27 #include "cgen.h"
28 #include "elf/common.h"
29 #include "elf/bpf.h"
30 #include "dwarf2dbg.h"
31
32 const char comment_chars[] = ";";
33 const char line_comment_chars[] = "#";
34 const char line_separator_chars[] = "`";
35 const char EXP_CHARS[] = "eE";
36 const char FLT_CHARS[] = "fFdD";
37
38 /* The target specific pseudo-ops which we support. */
39 const pseudo_typeS md_pseudo_table[] =
40 {
41 { "half", cons, 2 },
42 { "word", cons, 4 },
43 { "dword", cons, 8 },
44 { "lcomm", s_lcomm, 1 },
45 { NULL, NULL, 0 }
46 };
47
48 /* ISA handling. */
49 static CGEN_BITSET *bpf_isa;
50
51 \f
52
53 /* Command-line options processing. */
54
55 enum options
56 {
57 OPTION_LITTLE_ENDIAN = OPTION_MD_BASE,
58 OPTION_BIG_ENDIAN
59 };
60
61 struct option md_longopts[] =
62 {
63 { "EL", no_argument, NULL, OPTION_LITTLE_ENDIAN },
64 { "EB", no_argument, NULL, OPTION_BIG_ENDIAN },
65 { NULL, no_argument, NULL, 0 },
66 };
67
68 size_t md_longopts_size = sizeof (md_longopts);
69
70 const char * md_shortopts = "";
71
72 extern int target_big_endian;
73
74 /* Whether target_big_endian has been set while parsing command-line
75 arguments. */
76 static int set_target_endian = 0;
77
78 int
79 md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
80 {
81 switch (c)
82 {
83 case OPTION_BIG_ENDIAN:
84 set_target_endian = 1;
85 target_big_endian = 1;
86 break;
87 case OPTION_LITTLE_ENDIAN:
88 set_target_endian = 1;
89 target_big_endian = 0;
90 break;
91 default:
92 return 0;
93 }
94
95 return 1;
96 }
97
98 void
99 md_show_usage (FILE * stream)
100 {
101 fprintf (stream, _("\nBPF options:\n"));
102 fprintf (stream, _("\
103 --EL generate code for a little endian machine\n\
104 --EB generate code for a big endian machine\n"));
105 }
106
107 \f
108 void
109 md_begin (void)
110 {
111 /* Initialize the `cgen' interface. */
112
113 /* If not specified in the command line, use the host
114 endianness. */
115 if (!set_target_endian)
116 {
117 #ifdef WORDS_BIGENDIAN
118 target_big_endian = 1;
119 #else
120 target_big_endian = 0;
121 #endif
122 }
123
124 /* Set the ISA, which depends on the target endianness. */
125 bpf_isa = cgen_bitset_create (ISA_MAX);
126 if (target_big_endian)
127 cgen_bitset_set (bpf_isa, ISA_EBPFBE);
128 else
129 cgen_bitset_set (bpf_isa, ISA_EBPFLE);
130
131 /* Set the machine number and endian. */
132 gas_cgen_cpu_desc = bpf_cgen_cpu_open (CGEN_CPU_OPEN_ENDIAN,
133 target_big_endian ?
134 CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE,
135 CGEN_CPU_OPEN_ISAS,
136 bpf_isa,
137 CGEN_CPU_OPEN_END);
138 bpf_cgen_init_asm (gas_cgen_cpu_desc);
139
140 /* This is a callback from cgen to gas to parse operands. */
141 cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
142
143 /* Set the machine type. */
144 bfd_default_set_arch_mach (stdoutput, bfd_arch_bpf, bfd_mach_bpf);
145 }
146
147 valueT
148 md_section_align (segT segment, valueT size)
149 {
150 int align = bfd_get_section_alignment (stdoutput, segment);
151
152 return ((size + (1 << align) - 1) & -(1 << align));
153 }
154
155 \f
156 /* Functions concerning relocs. */
157
158 /* The location from which a PC relative jump should be calculated,
159 given a PC relative reloc. */
160
161 long
162 md_pcrel_from_section (fixS *fixP, segT sec)
163 {
164 if (fixP->fx_addsy != (symbolS *) NULL
165 && (! S_IS_DEFINED (fixP->fx_addsy)
166 || (S_GET_SEGMENT (fixP->fx_addsy) != sec)
167 || S_IS_EXTERNAL (fixP->fx_addsy)
168 || S_IS_WEAK (fixP->fx_addsy)))
169 {
170 /* The symbol is undefined (or is defined but not in this section).
171 Let the linker figure it out. */
172 return 0;
173 }
174
175 return fixP->fx_where + fixP->fx_frag->fr_address;
176 }
177
178 /* Write a value out to the object file, using the appropriate endianness. */
179
180 void
181 md_number_to_chars (char * buf, valueT val, int n)
182 {
183 if (target_big_endian)
184 number_to_chars_bigendian (buf, val, n);
185 else
186 number_to_chars_littleendian (buf, val, n);
187 }
188
189 arelent *
190 tc_gen_reloc (asection *sec, fixS *fix)
191 {
192 return gas_cgen_tc_gen_reloc (sec, fix);
193 }
194
195 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP. This
196 is called when the operand is an expression that couldn't be fully
197 resolved. Returns BFD_RELOC_NONE if no reloc type can be found.
198 *FIXP may be modified if desired. */
199
200 bfd_reloc_code_real_type
201 md_cgen_lookup_reloc (const CGEN_INSN *insn ATTRIBUTE_UNUSED,
202 const CGEN_OPERAND *operand,
203 fixS *fixP)
204 {
205 switch (operand->type)
206 {
207 case BPF_OPERAND_OFFSET16:
208 return BFD_RELOC_BPF_16;
209 case BPF_OPERAND_IMM32:
210 return BFD_RELOC_BPF_32;
211 case BPF_OPERAND_IMM64:
212 return BFD_RELOC_BPF_64;
213 case BPF_OPERAND_DISP16:
214 fixP->fx_pcrel = 1;
215 return BFD_RELOC_BPF_DISP16;
216 case BPF_OPERAND_DISP32:
217 fixP->fx_pcrel = 1;
218 return BFD_RELOC_BPF_DISP32;
219 default:
220 break;
221 }
222 return BFD_RELOC_NONE;
223 }
224 \f
225 /* *FRAGP has been relaxed to its final size, and now needs to have
226 the bytes inside it modified to conform to the new size.
227
228 Called after relaxation is finished.
229 fragP->fr_type == rs_machine_dependent.
230 fragP->fr_subtype is the subtype of what the address relaxed to. */
231
232 void
233 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
234 segT sec ATTRIBUTE_UNUSED,
235 fragS *fragP ATTRIBUTE_UNUSED)
236 {
237 as_fatal (_("convert_frag called"));
238 }
239
240 int
241 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
242 segT segment ATTRIBUTE_UNUSED)
243 {
244 as_fatal (_("estimate_size_before_relax called"));
245 return 0;
246 }
247
248 \f
249 void
250 md_apply_fix (fixS *fixP, valueT *valP, segT seg)
251 {
252 /* Some fixups for instructions require special attention. This is
253 handled in the code block below. */
254 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
255 {
256 int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
257 const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
258 opindex);
259 char *where;
260
261 switch (operand->type)
262 {
263 case BPF_OPERAND_DISP32:
264 /* eBPF supports two kind of CALL instructions: the so
265 called pseudo calls ("bpf to bpf") and external calls
266 ("bpf to kernel").
267
268 Both kind of calls use the same instruction (CALL).
269 However, external calls are constructed by passing a
270 constant argument to the instruction, whereas pseudo
271 calls result from expressions involving symbols. In
272 practice, instructions requiring a fixup are interpreted
273 as pseudo-calls. If we are executing this code, this is
274 a pseudo call.
275
276 The kernel expects for pseudo-calls to be annotated by
277 having BPF_PSEUDO_CALL in the SRC field of the
278 instruction. But beware the infamous nibble-swapping of
279 eBPF and take endianness into account here.
280
281 Note that the CALL instruction has only one operand, so
282 this code is executed only once per instruction. */
283 where = fixP->fx_frag->fr_literal + fixP->fx_where;
284 cgen_put_insn_value (gas_cgen_cpu_desc, (unsigned char *) where + 1, 8,
285 target_big_endian ? 0x01 : 0x10);
286 /* Fallthrough. */
287 case BPF_OPERAND_DISP16:
288 /* The PC-relative displacement fields in jump instructions
289 shouldn't be in bytes. Instead, they hold the number of
290 64-bit words to the target, _minus one_. */
291 *valP = (((long) (*valP)) - 8) / 8;
292 break;
293 default:
294 break;
295 }
296 }
297
298 /* And now invoke CGEN's handler, which will eventually install
299 *valP into the corresponding operand. */
300 gas_cgen_md_apply_fix (fixP, valP, seg);
301 }
302
303 void
304 md_assemble (char *str)
305 {
306 const CGEN_INSN *insn;
307 char *errmsg;
308 CGEN_FIELDS fields;
309
310 #if CGEN_INT_INSN_P
311 CGEN_INSN_INT buffer[CGEN_MAX_INSN_SIZE / sizeof (CGEN_INT_INSN_P)];
312 #else
313 unsigned char buffer[CGEN_MAX_INSN_SIZE];
314 memset (buffer, 0, CGEN_MAX_INSN_SIZE); /* XXX to remove when CGEN
315 is fixed to handle
316 opcodes-in-words
317 properly. */
318 #endif
319
320 gas_cgen_init_parse ();
321 insn = bpf_cgen_assemble_insn (gas_cgen_cpu_desc, str, &fields,
322 buffer, &errmsg);
323
324 if (insn == NULL)
325 {
326 as_bad ("%s", errmsg);
327 return;
328 }
329
330 gas_cgen_finish_insn (insn, buffer, CGEN_FIELDS_BITSIZE (&fields),
331 0, /* zero to ban relaxable insns. */
332 NULL); /* NULL so results not returned here. */
333 }
334
335 void
336 md_operand (expressionS *expressionP)
337 {
338 gas_cgen_md_operand (expressionP);
339 }
340
341
342 symbolS *
343 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
344 {
345 return NULL;
346 }
347
348 \f
349 /* Turn a string in input_line_pointer into a floating point constant
350 of type TYPE, and store the appropriate bytes in *LITP. The number
351 of LITTLENUMS emitted is stored in *SIZEP. An error message is
352 returned, or NULL on OK. */
353
354 const char *
355 md_atof (int type, char *litP, int *sizeP)
356 {
357 return ieee_md_atof (type, litP, sizeP, FALSE);
358 }
This page took 0.039811 seconds and 3 git commands to generate.