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