xref: /netbsd-src/external/gpl3/binutils/dist/gas/config/tc-bpf.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /* tc-bpf.c -- Assembler for the Linux eBPF.
2    Copyright (C) 2019-2024 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 "opcode/bpf.h"
26 #include "elf/common.h"
27 #include "elf/bpf.h"
28 #include "dwarf2dbg.h"
29 #include "libiberty.h"
30 #include <ctype.h>
31 
32 /* Data structure representing a parsed BPF instruction.  */
33 
34 struct bpf_insn
35 {
36   enum bpf_insn_id id;
37   int size; /* Instruction size in bytes.  */
38   bpf_insn_word opcode;
39   uint8_t dst;
40   uint8_t src;
41   expressionS offset16;
42   expressionS imm32;
43   expressionS imm64;
44   expressionS disp16;
45   expressionS disp32;
46 
47   unsigned int has_dst : 1;
48   unsigned int has_src : 1;
49   unsigned int has_offset16 : 1;
50   unsigned int has_disp16 : 1;
51   unsigned int has_disp32 : 1;
52   unsigned int has_imm32 : 1;
53   unsigned int has_imm64 : 1;
54 
55   unsigned int is_relaxable : 1;
56   expressionS *relaxed_exp;
57 };
58 
59 const char comment_chars[]        = "#";
60 const char line_comment_chars[]   = "#";
61 const char line_separator_chars[] = ";`";
62 const char EXP_CHARS[]            = "eE";
63 const char FLT_CHARS[]            = "fFdD";
64 
65 /* Like s_lcomm_internal in gas/read.c but the alignment string
66    is allowed to be optional.  */
67 
68 static symbolS *
pe_lcomm_internal(int needs_align,symbolS * symbolP,addressT size)69 pe_lcomm_internal (int needs_align, symbolS *symbolP, addressT size)
70 {
71   addressT align = 0;
72 
73   SKIP_WHITESPACE ();
74 
75   if (needs_align
76       && *input_line_pointer == ',')
77     {
78       align = parse_align (needs_align - 1);
79 
80       if (align == (addressT) -1)
81 	return NULL;
82     }
83   else
84     {
85       if (size >= 8)
86 	align = 3;
87       else if (size >= 4)
88 	align = 2;
89       else if (size >= 2)
90 	align = 1;
91       else
92 	align = 0;
93     }
94 
95   bss_alloc (symbolP, size, align);
96   return symbolP;
97 }
98 
99 static void
pe_lcomm(int needs_align)100 pe_lcomm (int needs_align)
101 {
102   s_comm_internal (needs_align * 2, pe_lcomm_internal);
103 }
104 
105 /* The target specific pseudo-ops which we support.  */
106 const pseudo_typeS md_pseudo_table[] =
107 {
108     { "half",      cons,              2 },
109     { "word",      cons,              4 },
110     { "dword",     cons,              8 },
111     { "lcomm",	   pe_lcomm,	      1 },
112     { NULL,        NULL,              0 }
113 };
114 
115 
116 
117 /* Command-line options processing.  */
118 
119 enum options
120 {
121   OPTION_LITTLE_ENDIAN = OPTION_MD_BASE,
122   OPTION_BIG_ENDIAN,
123   OPTION_XBPF,
124   OPTION_DIALECT,
125   OPTION_ISA_SPEC,
126   OPTION_NO_RELAX,
127 };
128 
129 struct option md_longopts[] =
130 {
131   { "EL", no_argument, NULL, OPTION_LITTLE_ENDIAN },
132   { "EB", no_argument, NULL, OPTION_BIG_ENDIAN },
133   { "mxbpf", no_argument, NULL, OPTION_XBPF },
134   { "mdialect", required_argument, NULL, OPTION_DIALECT},
135   { "misa-spec", required_argument, NULL, OPTION_ISA_SPEC},
136   { "mno-relax", no_argument, NULL, OPTION_NO_RELAX},
137   { NULL,          no_argument, NULL, 0 },
138 };
139 
140 size_t md_longopts_size = sizeof (md_longopts);
141 
142 const char * md_shortopts = "";
143 
144 /* BPF supports little-endian and big-endian variants.  The following
145    global records what endianness to use.  It can be configured using
146    command-line options.  It defaults to the host endianness
147    initialized in md_begin.  */
148 
149 static int set_target_endian = 0;
150 extern int target_big_endian;
151 
152 /* Whether to relax branch instructions.  Default is yes.  Can be
153    changed using the -mno-relax command line option.  */
154 
155 static int do_relax = 1;
156 
157 /* The ISA specification can be one of BPF_V1, BPF_V2, BPF_V3, BPF_V4
158    or BPF_XPBF.  The ISA spec to use can be configured using
159    command-line options.  It defaults to the latest BPF spec.  */
160 
161 static int isa_spec = BPF_V4;
162 
163 /* The assembler supports two different dialects: "normal" syntax and
164    "pseudoc" syntax.  The dialect to use can be configured using
165    command-line options.  */
166 
167 enum target_asm_dialect
168 {
169   DIALECT_NORMAL,
170   DIALECT_PSEUDOC
171 };
172 
173 static int asm_dialect = DIALECT_NORMAL;
174 
175 int
md_parse_option(int c,const char * arg)176 md_parse_option (int c, const char * arg)
177 {
178   switch (c)
179     {
180     case OPTION_BIG_ENDIAN:
181       set_target_endian = 1;
182       target_big_endian = 1;
183       break;
184     case OPTION_LITTLE_ENDIAN:
185       set_target_endian = 0;
186       target_big_endian = 0;
187       break;
188     case OPTION_DIALECT:
189       if (strcmp (arg, "normal") == 0)
190         asm_dialect = DIALECT_NORMAL;
191       else if (strcmp (arg, "pseudoc") == 0)
192         asm_dialect = DIALECT_PSEUDOC;
193       else
194         as_fatal (_("-mdialect=%s is not valid.  Expected normal or pseudoc"),
195                   arg);
196       break;
197     case OPTION_ISA_SPEC:
198       if (strcmp (arg, "v1") == 0)
199         isa_spec = BPF_V1;
200       else if (strcmp (arg, "v2") == 0)
201         isa_spec = BPF_V2;
202       else if (strcmp (arg, "v3") == 0)
203         isa_spec = BPF_V3;
204       else if (strcmp (arg, "v4") == 0)
205         isa_spec = BPF_V4;
206       else if (strcmp (arg, "xbpf") == 0)
207         isa_spec = BPF_XBPF;
208       else
209         as_fatal (_("-misa-spec=%s is not valid.  Expected v1, v2, v3, v4 o xbpf"),
210                   arg);
211       break;
212     case OPTION_XBPF:
213       /* This is an alias for -misa-spec=xbpf.  */
214       isa_spec = BPF_XBPF;
215       break;
216     case OPTION_NO_RELAX:
217       do_relax = 0;
218       break;
219     default:
220       return 0;
221     }
222 
223   return 1;
224 }
225 
226 void
md_show_usage(FILE * stream)227 md_show_usage (FILE * stream)
228 {
229   fprintf (stream, _("\nBPF options:\n"));
230   fprintf (stream, _("\
231 BPF options:\n\
232   -EL                         generate code for a little endian machine\n\
233   -EB                         generate code for a big endian machine\n\
234   -mdialect=DIALECT           set the assembly dialect (normal, pseudoc)\n\
235   -misa-spec                  set the BPF ISA spec (v1, v2, v3, v4, xbpf)\n\
236   -mxbpf                      alias for -misa-spec=xbpf\n"));
237 }
238 
239 
240 /* This function is called once, at assembler startup time.  This
241    should set up all the tables, etc that the MD part of the assembler
242    needs.  */
243 
244 void
md_begin(void)245 md_begin (void)
246 {
247   /* If not specified in the command line, use the host
248      endianness.  */
249   if (!set_target_endian)
250     {
251 #ifdef WORDS_BIGENDIAN
252       target_big_endian = 1;
253 #else
254       target_big_endian = 0;
255 #endif
256     }
257 
258   /* Ensure that lines can begin with '*' in BPF store pseudoc instruction.  */
259   lex_type['*'] |= LEX_BEGIN_NAME;
260 
261   /* Set the machine type. */
262   bfd_default_set_arch_mach (stdoutput, bfd_arch_bpf, bfd_mach_bpf);
263 }
264 
265 /* Round up a section size to the appropriate boundary.  */
266 
267 valueT
md_section_align(segT segment,valueT size)268 md_section_align (segT segment, valueT size)
269 {
270   int align = bfd_section_alignment (segment);
271 
272   return ((size + (1 << align) - 1) & -(1 << align));
273 }
274 
275 /* Return non-zero if the indicated VALUE has overflowed the maximum
276    range expressible by an signed number with the indicated number of
277    BITS.  */
278 
279 static bool
signed_overflow(offsetT value,unsigned bits)280 signed_overflow (offsetT value, unsigned bits)
281 {
282   offsetT lim;
283   if (bits >= sizeof (offsetT) * 8)
284     return false;
285   lim = (offsetT) 1 << (bits - 1);
286   return (value < -lim || value >= lim);
287 }
288 
289 /* Return non-zero if the two's complement encoding of VALUE would
290    overflow an immediate field of width BITS bits.  */
291 
292 static bool
immediate_overflow(int64_t value,unsigned bits)293 immediate_overflow (int64_t value, unsigned bits)
294 {
295   if (value < 0)
296     return signed_overflow (value, bits);
297   else
298     {
299       valueT lim;
300 
301       if (bits >= sizeof (valueT) * 8)
302         return false;
303 
304       lim = (valueT) 1 << bits;
305       return ((valueT) value >= lim);
306     }
307 }
308 
309 
310 /* Functions concerning relocs.  */
311 
312 /* The location from which a PC relative jump should be calculated,
313    given a PC relative reloc.  */
314 
315 long
md_pcrel_from_section(fixS * fixP,segT sec)316 md_pcrel_from_section (fixS *fixP, segT sec)
317 {
318   if (fixP->fx_addsy != (symbolS *) NULL
319       && (! S_IS_DEFINED (fixP->fx_addsy)
320           || (S_GET_SEGMENT (fixP->fx_addsy) != sec)
321           || S_IS_EXTERNAL (fixP->fx_addsy)
322           || S_IS_WEAK (fixP->fx_addsy)))
323     {
324         /* The symbol is undefined (or is defined but not in this section).
325          Let the linker figure it out.  */
326       return 0;
327     }
328 
329   return fixP->fx_where + fixP->fx_frag->fr_address;
330 }
331 
332 /* Write a value out to the object file, using the appropriate endianness.  */
333 
334 void
md_number_to_chars(char * buf,valueT val,int n)335 md_number_to_chars (char * buf, valueT val, int n)
336 {
337   if (target_big_endian)
338     number_to_chars_bigendian (buf, val, n);
339   else
340     number_to_chars_littleendian (buf, val, n);
341 }
342 
343 arelent *
tc_gen_reloc(asection * sec ATTRIBUTE_UNUSED,fixS * fixP)344 tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, fixS *fixP)
345 {
346   bfd_reloc_code_real_type r_type = fixP->fx_r_type;
347   arelent *reloc;
348 
349   reloc = XNEW (arelent);
350 
351   if (fixP->fx_pcrel)
352    {
353       r_type = (r_type == BFD_RELOC_8 ? BFD_RELOC_8_PCREL
354                 : r_type == BFD_RELOC_16 ? BFD_RELOC_16_PCREL
355                 : r_type == BFD_RELOC_24 ? BFD_RELOC_24_PCREL
356                 : r_type == BFD_RELOC_32 ? BFD_RELOC_32_PCREL
357                 : r_type == BFD_RELOC_64 ? BFD_RELOC_64_PCREL
358                 : r_type);
359    }
360 
361   reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type);
362 
363   if (reloc->howto == (reloc_howto_type *) NULL)
364     {
365       as_bad_where (fixP->fx_file, fixP->fx_line,
366 		    _("relocation is not supported"));
367       return NULL;
368     }
369 
370   //XXX  gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
371 
372   reloc->sym_ptr_ptr = XNEW (asymbol *);
373   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
374 
375   /* Use fx_offset for these cases.  */
376   if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
377       || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
378     reloc->addend = fixP->fx_offset;
379   else
380     reloc->addend = fixP->fx_addnumber;
381 
382   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
383   return reloc;
384 }
385 
386 
387 /* Relaxations supported by this assembler.  */
388 
389 #define RELAX_BRANCH_ENCODE(uncond, constant, length)    \
390   ((relax_substateT)                                     \
391    (0xc0000000                                           \
392     | ((uncond) ? 1 : 0)                                 \
393     | ((constant) ? 2 : 0)                               \
394     | ((length) << 2)))
395 
396 #define RELAX_BRANCH_P(i) (((i) & 0xf0000000) == 0xc0000000)
397 #define RELAX_BRANCH_LENGTH(i) (((i) >> 2) & 0xff)
398 #define RELAX_BRANCH_CONST(i) (((i) & 2) != 0)
399 #define RELAX_BRANCH_UNCOND(i) (((i) & 1) != 0)
400 
401 
402 /* Compute the length of a branch sequence, and adjust the stored
403    length accordingly.  If FRAG is NULL, the worst-case length is
404    returned.  */
405 
406 static unsigned
relaxed_branch_length(fragS * fragp,asection * sec,int update)407 relaxed_branch_length (fragS *fragp, asection *sec, int update)
408 {
409   int length, uncond;
410 
411   if (!fragp)
412     return 8 * 3;
413 
414   uncond = RELAX_BRANCH_UNCOND (fragp->fr_subtype);
415   length = RELAX_BRANCH_LENGTH (fragp->fr_subtype);
416 
417   if (uncond)
418     /* Length is the same for both JA and JAL.  */
419     length = 8;
420   else
421     {
422       if (RELAX_BRANCH_CONST (fragp->fr_subtype))
423         {
424           int64_t val = fragp->fr_offset;
425 
426           if (val < -32768 || val > 32767)
427             length =  8 * 3;
428           else
429             length = 8;
430         }
431       else if (fragp->fr_symbol != NULL
432           && S_IS_DEFINED (fragp->fr_symbol)
433           && !S_IS_WEAK (fragp->fr_symbol)
434           && sec == S_GET_SEGMENT (fragp->fr_symbol))
435         {
436           offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset;
437 
438           /* Convert to 64-bit words, minus one.  */
439           val = (val - 8) / 8;
440 
441           /* See if it fits in the signed 16-bits field.  */
442           if (val < -32768 || val > 32767)
443             length = 8 * 3;
444           else
445             length = 8;
446         }
447       else
448         /* Use short version, and let the linker relax instead, if
449            appropriate and if supported.  */
450         length = 8;
451     }
452 
453   if (update)
454     fragp->fr_subtype = RELAX_BRANCH_ENCODE (uncond,
455                                              RELAX_BRANCH_CONST (fragp->fr_subtype),
456                                              length);
457 
458   return length;
459 }
460 
461 /* Estimate the size of a variant frag before relaxing.  */
462 
463 int
md_estimate_size_before_relax(fragS * fragp,asection * sec)464 md_estimate_size_before_relax (fragS *fragp, asection *sec)
465 {
466   return (fragp->fr_var = relaxed_branch_length (fragp, sec, true));
467 }
468 
469 /* Read a BPF instruction word from BUF.  */
470 
471 static uint64_t
read_insn_word(bfd_byte * buf)472 read_insn_word (bfd_byte *buf)
473 {
474   return bfd_getb64 (buf);
475 }
476 
477 /* Write the given signed 16-bit value in the given BUFFER using the
478    target endianness.  */
479 
480 static void
encode_int16(int16_t value,char * buffer)481 encode_int16 (int16_t value, char *buffer)
482 {
483   uint16_t val = value;
484 
485   if (target_big_endian)
486     {
487       buffer[0] = (val >> 8) & 0xff;
488       buffer[1] = val & 0xff;
489     }
490   else
491     {
492       buffer[1] = (val >> 8) & 0xff;
493       buffer[0] = val & 0xff;
494     }
495 }
496 
497 /* Write the given signed 32-bit value in the given BUFFER using the
498    target endianness.  */
499 
500 static void
encode_int32(int32_t value,char * buffer)501 encode_int32 (int32_t value, char *buffer)
502 {
503   uint32_t val = value;
504 
505   if (target_big_endian)
506     {
507       buffer[0] = (val >> 24) & 0xff;
508       buffer[1] = (val >> 16) & 0xff;
509       buffer[2] = (val >> 8) & 0xff;
510       buffer[3] = val & 0xff;
511     }
512   else
513     {
514       buffer[3] = (val >> 24) & 0xff;
515       buffer[2] = (val >> 16) & 0xff;
516       buffer[1] = (val >> 8) & 0xff;
517       buffer[0] = value & 0xff;
518     }
519 }
520 
521 /* Write a BPF instruction to BUF.  */
522 
523 static void
write_insn_bytes(bfd_byte * buf,char * bytes)524 write_insn_bytes (bfd_byte *buf, char *bytes)
525 {
526   int i;
527 
528   for (i = 0; i < 8; ++i)
529     md_number_to_chars ((char *) buf + i, (valueT) bytes[i], 1);
530 }
531 
532 /* *FRAGP has been relaxed to its final size, and now needs to have
533    the bytes inside it modified to conform to the new size.
534 
535    Called after relaxation is finished.
536    fragP->fr_type == rs_machine_dependent.
537    fragP->fr_subtype is the subtype of what the address relaxed to.  */
538 
539 void
md_convert_frag(bfd * abfd ATTRIBUTE_UNUSED,segT sec ATTRIBUTE_UNUSED,fragS * fragp ATTRIBUTE_UNUSED)540 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
541 		 segT sec ATTRIBUTE_UNUSED,
542 		 fragS *fragp ATTRIBUTE_UNUSED)
543 {
544   bfd_byte *buf = (bfd_byte *) fragp->fr_literal + fragp->fr_fix;
545   expressionS exp;
546   fixS *fixp;
547   bpf_insn_word word;
548   int disp_is_known = 0;
549   int64_t disp_to_target = 0;
550 
551   uint64_t code;
552 
553   gas_assert (RELAX_BRANCH_P (fragp->fr_subtype));
554 
555   /* Expression to be used in any resulting relocation in the relaxed
556      instructions.  */
557   exp.X_op = O_symbol;
558   exp.X_add_symbol = fragp->fr_symbol;
559   exp.X_add_number = fragp->fr_offset;
560 
561   gas_assert (fragp->fr_var == RELAX_BRANCH_LENGTH (fragp->fr_subtype));
562 
563   /* Read an instruction word from the instruction to be relaxed, and
564      get the code.  */
565   word = read_insn_word (buf);
566   code = (word >> 60) & 0xf;
567 
568   /* Determine whether the 16-bit displacement to the target is known
569      at this point.  */
570   if (RELAX_BRANCH_CONST (fragp->fr_subtype))
571     {
572       disp_to_target = fragp->fr_offset;
573       disp_is_known = 1;
574     }
575   else if (fragp->fr_symbol != NULL
576            && S_IS_DEFINED (fragp->fr_symbol)
577            && !S_IS_WEAK (fragp->fr_symbol)
578            && sec == S_GET_SEGMENT (fragp->fr_symbol))
579     {
580       offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset;
581       /* Convert to 64-bit blocks minus one.  */
582       disp_to_target = (val - 8) / 8;
583       disp_is_known = 1;
584     }
585 
586   /* The displacement should fit in a signed 32-bit number.  */
587   if (disp_is_known && signed_overflow (disp_to_target, 32))
588     as_bad_where (fragp->fr_file, fragp->fr_line,
589                   _("signed instruction operand out of range, shall fit in 32 bits"));
590 
591   /* Now relax particular jump instructions.  */
592   if (code == BPF_CODE_JA)
593     {
594       /* Unconditional jump.
595          JA d16 -> JAL d32  */
596 
597       gas_assert (RELAX_BRANCH_UNCOND (fragp->fr_subtype));
598 
599       if (disp_is_known)
600         {
601           if (disp_to_target >= -32768 && disp_to_target <= 32767)
602             {
603               /* 16-bit disp is known and in range.  Install a fixup
604                  for the disp16 if the branch value is not constant.
605                  This will be resolved by the assembler and units
606                  converted.  */
607 
608               if (!RELAX_BRANCH_CONST (fragp->fr_subtype))
609                 {
610                   /* Install fixup for the JA.  */
611                   reloc_howto_type *reloc_howto
612                     = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP16);
613                   if (!reloc_howto)
614                     abort();
615 
616                   fixp = fix_new_exp (fragp, buf - (bfd_byte *) fragp->fr_literal,
617                                       bfd_get_reloc_size (reloc_howto),
618                                       &exp,
619                                       reloc_howto->pc_relative,
620                                       BFD_RELOC_BPF_DISP16);
621                   fixp->fx_file = fragp->fr_file;
622                   fixp->fx_line = fragp->fr_line;
623                 }
624             }
625           else
626             {
627               /* 16-bit disp is known and not in range.  Turn the JA
628                  into a JAL with a 32-bit displacement.  */
629               char bytes[8];
630 
631               bytes[0] = ((BPF_CLASS_JMP32|BPF_CODE_JA|BPF_SRC_K) >> 56) & 0xff;
632               bytes[1] = (word >> 48) & 0xff;
633               bytes[2] = 0; /* disp16 high */
634               bytes[3] = 0; /* disp16 lo */
635               encode_int32 ((int32_t) disp_to_target, bytes + 4);
636 
637               write_insn_bytes (buf, bytes);
638             }
639         }
640       else
641         {
642           /* The displacement to the target is not known.  Do not
643              relax.  The linker will maybe do it if it chooses to.  */
644 
645           reloc_howto_type *reloc_howto = NULL;
646 
647           gas_assert (!RELAX_BRANCH_CONST (fragp->fr_subtype));
648 
649           /* Install fixup for the JA.  */
650           reloc_howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP16);
651           if (!reloc_howto)
652             abort ();
653 
654           fixp = fix_new_exp (fragp, buf - (bfd_byte *) fragp->fr_literal,
655                               bfd_get_reloc_size (reloc_howto),
656                               &exp,
657                               reloc_howto->pc_relative,
658                               BFD_RELOC_BPF_DISP16);
659           fixp->fx_file = fragp->fr_file;
660           fixp->fx_line = fragp->fr_line;
661         }
662 
663       buf += 8;
664     }
665   else
666     {
667       /* Conditional jump.
668          JXX d16 -> JXX +1; JA +1; JAL d32 */
669 
670       gas_assert (!RELAX_BRANCH_UNCOND (fragp->fr_subtype));
671 
672       if (disp_is_known)
673         {
674           if (disp_to_target >= -32768 && disp_to_target <= 32767)
675             {
676               /* 16-bit disp is known and in range.  Install a fixup
677                  for the disp16 if the branch value is not constant.
678                  This will be resolved by the assembler and units
679                  converted.  */
680 
681               if (!RELAX_BRANCH_CONST (fragp->fr_subtype))
682                 {
683                   /* Install fixup for the branch.  */
684                   reloc_howto_type *reloc_howto
685                     = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP16);
686                   if (!reloc_howto)
687                     abort();
688 
689                   fixp = fix_new_exp (fragp, buf - (bfd_byte *) fragp->fr_literal,
690                                       bfd_get_reloc_size (reloc_howto),
691                                       &exp,
692                                       reloc_howto->pc_relative,
693                                       BFD_RELOC_BPF_DISP16);
694                   fixp->fx_file = fragp->fr_file;
695                   fixp->fx_line = fragp->fr_line;
696                 }
697 
698               buf += 8;
699             }
700           else
701             {
702               /* 16-bit disp is known and not in range.  Turn the JXX
703                  into a sequence JXX +1; JA +1; JAL d32.  */
704 
705               char bytes[8];
706 
707               /* First, set the 16-bit offset in the current
708                  instruction to 1.  */
709 
710               if (target_big_endian)
711                 bfd_putb16 (1, buf + 2);
712               else
713                 bfd_putl16 (1, buf + 2);
714               buf += 8;
715 
716               /* Then, write the JA + 1  */
717 
718               bytes[0] = 0x05; /* JA */
719               bytes[1] = 0x0;
720               encode_int16 (1, bytes + 2);
721               bytes[4] = 0x0;
722               bytes[5] = 0x0;
723               bytes[6] = 0x0;
724               bytes[7] = 0x0;
725               write_insn_bytes (buf, bytes);
726               buf += 8;
727 
728               /* Finally, write the JAL to the target. */
729 
730               bytes[0] = ((BPF_CLASS_JMP32|BPF_CODE_JA|BPF_SRC_K) >> 56) & 0xff;
731               bytes[1] = 0;
732               bytes[2] = 0;
733               bytes[3] = 0;
734               encode_int32 ((int32_t) disp_to_target, bytes + 4);
735               write_insn_bytes (buf, bytes);
736               buf += 8;
737             }
738         }
739       else
740         {
741           /* The displacement to the target is not known.  Do not
742              relax.  The linker will maybe do it if it chooses to.  */
743 
744           reloc_howto_type *reloc_howto = NULL;
745 
746           gas_assert (!RELAX_BRANCH_CONST (fragp->fr_subtype));
747 
748           /* Install fixup for the conditional jump.  */
749           reloc_howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP16);
750           if (!reloc_howto)
751             abort ();
752 
753           fixp = fix_new_exp (fragp, buf - (bfd_byte *) fragp->fr_literal,
754                               bfd_get_reloc_size (reloc_howto),
755                               &exp,
756                               reloc_howto->pc_relative,
757                               BFD_RELOC_BPF_DISP16);
758           fixp->fx_file = fragp->fr_file;
759           fixp->fx_line = fragp->fr_line;
760           buf += 8;
761         }
762     }
763 
764   gas_assert (buf == (bfd_byte *)fragp->fr_literal
765               + fragp->fr_fix + fragp->fr_var);
766 
767   fragp->fr_fix += fragp->fr_var;
768 }
769 
770 
771 /* Apply a fixS (fixup of an instruction or data that we didn't have
772    enough info to complete immediately) to the data in a frag.  */
773 
774 void
md_apply_fix(fixS * fixP,valueT * valP,segT seg ATTRIBUTE_UNUSED)775 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
776 {
777   char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
778 
779   switch (fixP->fx_r_type)
780     {
781     case BFD_RELOC_BPF_DISP16:
782       /* Convert from bytes to number of 64-bit words to the target,
783          minus one.  */
784       *valP = (((long) (*valP)) - 8) / 8;
785       break;
786     case BFD_RELOC_BPF_DISPCALL32:
787     case BFD_RELOC_BPF_DISP32:
788       /* Convert from bytes to number of 64-bit words to the target,
789          minus one.  */
790       *valP = (((long) (*valP)) - 8) / 8;
791 
792       if (fixP->fx_r_type == BFD_RELOC_BPF_DISPCALL32)
793         {
794           /* eBPF supports two kind of CALL instructions: the so
795              called pseudo calls ("bpf to bpf") and external calls
796              ("bpf to kernel").
797 
798              Both kind of calls use the same instruction (CALL).
799              However, external calls are constructed by passing a
800              constant argument to the instruction, whereas pseudo
801              calls result from expressions involving symbols.  In
802              practice, instructions requiring a fixup are interpreted
803              as pseudo-calls.  If we are executing this code, this is
804              a pseudo call.
805 
806              The kernel expects for pseudo-calls to be annotated by
807              having BPF_PSEUDO_CALL in the SRC field of the
808              instruction.  But beware the infamous nibble-swapping of
809              eBPF and take endianness into account here.
810 
811              Note that the CALL instruction has only one operand, so
812              this code is executed only once per instruction.  */
813           md_number_to_chars (where + 1, target_big_endian ? 0x01 : 0x10, 1);
814         }
815       break;
816     case BFD_RELOC_16_PCREL:
817       /* Convert from bytes to number of 64-bit words to the target,
818          minus one.  */
819       *valP = (((long) (*valP)) - 8) / 8;
820       break;
821     default:
822       break;
823     }
824 
825   if (fixP->fx_addsy == (symbolS *) NULL)
826     fixP->fx_done = 1;
827 
828   if (fixP->fx_done)
829     {
830       /* We're finished with this fixup.  Install it because
831 	 bfd_install_relocation won't be called to do it.  */
832       switch (fixP->fx_r_type)
833 	{
834 	case BFD_RELOC_8:
835 	  md_number_to_chars (where, *valP, 1);
836 	  break;
837 	case BFD_RELOC_16:
838 	  md_number_to_chars (where, *valP, 2);
839 	  break;
840 	case BFD_RELOC_32:
841 	  md_number_to_chars (where, *valP, 4);
842 	  break;
843 	case BFD_RELOC_64:
844 	  md_number_to_chars (where, *valP, 8);
845 	  break;
846         case BFD_RELOC_BPF_DISP16:
847           md_number_to_chars (where + 2, (uint16_t) *valP, 2);
848           break;
849         case BFD_RELOC_BPF_DISP32:
850         case BFD_RELOC_BPF_DISPCALL32:
851           md_number_to_chars (where + 4, (uint32_t) *valP, 4);
852           break;
853         case BFD_RELOC_16_PCREL:
854           md_number_to_chars (where + 2, (uint32_t) *valP, 2);
855           break;
856 	default:
857 	  as_bad_where (fixP->fx_file, fixP->fx_line,
858 			_("internal error: can't install fix for reloc type %d (`%s')"),
859 			fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
860 	  break;
861 	}
862     }
863 
864   /* Tuck `value' away for use by tc_gen_reloc.
865      See the comment describing fx_addnumber in write.h.
866      This field is misnamed (or misused :-).  */
867   fixP->fx_addnumber = *valP;
868 }
869 
870 
871 /* Instruction writing routines.  */
872 
873 /* Encode a BPF instruction in the given buffer BYTES.  Non-constant
874    immediates are encoded as zeroes.  */
875 
876 static void
encode_insn(struct bpf_insn * insn,char * bytes,int relaxed ATTRIBUTE_UNUSED)877 encode_insn (struct bpf_insn *insn, char *bytes,
878              int relaxed ATTRIBUTE_UNUSED)
879 {
880   uint8_t src, dst;
881 
882   /* Zero all the bytes.  */
883   memset (bytes, 0, 16);
884 
885   /* First encode the opcodes.  Note that we have to handle the
886      endianness groups of the BPF instructions: 8 | 4 | 4 | 16 |
887      32. */
888   if (target_big_endian)
889     {
890       /* code */
891       bytes[0] = (insn->opcode >> 56) & 0xff;
892       /* regs */
893       bytes[1] = (insn->opcode >> 48) & 0xff;
894       /* offset16 */
895       bytes[2] = (insn->opcode >> 40) & 0xff;
896       bytes[3] = (insn->opcode >> 32) & 0xff;
897       /* imm32 */
898       bytes[4] = (insn->opcode >> 24) & 0xff;
899       bytes[5] = (insn->opcode >> 16) & 0xff;
900       bytes[6] = (insn->opcode >> 8) & 0xff;
901       bytes[7] = insn->opcode & 0xff;
902     }
903   else
904     {
905       /* code */
906       bytes[0] = (insn->opcode >> 56) & 0xff;
907       /* regs */
908       bytes[1] = (((((insn->opcode >> 48) & 0xff) & 0xf) << 4)
909                   | (((insn->opcode >> 48) & 0xff) & 0xf));
910       /* offset16 */
911       bytes[3] = (insn->opcode >> 40) & 0xff;
912       bytes[2] = (insn->opcode >> 32) & 0xff;
913       /* imm32 */
914       bytes[7] = (insn->opcode >> 24) & 0xff;
915       bytes[6] = (insn->opcode >> 16) & 0xff;
916       bytes[5] = (insn->opcode >> 8) & 0xff;
917       bytes[4] = insn->opcode & 0xff;
918     }
919 
920   /* Now the registers.  */
921   src = insn->has_src ? insn->src : 0;
922   dst = insn->has_dst ? insn->dst : 0;
923 
924   if (target_big_endian)
925     bytes[1] = ((dst & 0xf) << 4) | (src & 0xf);
926   else
927     bytes[1] = ((src & 0xf) << 4) | (dst & 0xf);
928 
929   /* Now the immediates that are known to be constant.  */
930 
931   if (insn->has_imm32 && insn->imm32.X_op == O_constant)
932     {
933       int64_t imm = insn->imm32.X_add_number;
934 
935       if (immediate_overflow (imm, 32))
936         as_bad (_("immediate out of range, shall fit in 32 bits"));
937       else
938         encode_int32 (insn->imm32.X_add_number, bytes + 4);
939     }
940 
941   if (insn->has_disp32 && insn->disp32.X_op == O_constant)
942     {
943       int64_t disp = insn->disp32.X_add_number;
944 
945       if (immediate_overflow (disp, 32))
946         as_bad (_("pc-relative offset out of range, shall fit in 32 bits"));
947       else
948         encode_int32 (insn->disp32.X_add_number, bytes + 4);
949     }
950 
951   if (insn->has_offset16 && insn->offset16.X_op == O_constant)
952     {
953       int64_t offset = insn->offset16.X_add_number;
954 
955       if (immediate_overflow (offset, 16))
956         as_bad (_("pc-relative offset out of range, shall fit in 16 bits"));
957       else
958         encode_int16 (insn->offset16.X_add_number, bytes + 2);
959     }
960 
961   if (insn->has_disp16 && insn->disp16.X_op == O_constant)
962     {
963       int64_t disp = insn->disp16.X_add_number;
964 
965       if (immediate_overflow (disp, 16))
966         as_bad (_("pc-relative offset out of range, shall fit in 16 bits"));
967       else
968         encode_int16 (insn->disp16.X_add_number, bytes + 2);
969     }
970 
971   if (insn->has_imm64 && insn->imm64.X_op == O_constant)
972     {
973       uint64_t imm64 = insn->imm64.X_add_number;
974 
975       if (target_big_endian)
976         {
977           bytes[12] = (imm64 >> 56) & 0xff;
978           bytes[13] = (imm64 >> 48) & 0xff;
979           bytes[14] = (imm64 >> 40) & 0xff;
980           bytes[15] = (imm64 >> 32) & 0xff;
981           bytes[4] = (imm64 >> 24) & 0xff;
982           bytes[5] = (imm64 >> 16) & 0xff;
983           bytes[6] = (imm64 >> 8) & 0xff;
984           bytes[7] = imm64 & 0xff;
985         }
986       else
987         {
988           bytes[15] = (imm64 >> 56) & 0xff;
989           bytes[14] = (imm64 >> 48) & 0xff;
990           bytes[13] = (imm64 >> 40) & 0xff;
991           bytes[12] = (imm64 >> 32) & 0xff;
992           bytes[7] = (imm64 >> 24) & 0xff;
993           bytes[6] = (imm64 >> 16) & 0xff;
994           bytes[5] = (imm64 >> 8) & 0xff;
995           bytes[4] = imm64 & 0xff;
996         }
997     }
998 }
999 
1000 /* Install the fixups in INSN in their proper location in the
1001    specified FRAG at the location pointed by WHERE.  */
1002 
1003 static void
install_insn_fixups(struct bpf_insn * insn,fragS * frag,long where)1004 install_insn_fixups (struct bpf_insn *insn, fragS *frag, long where)
1005 {
1006   if (insn->has_imm64)
1007     {
1008       switch (insn->imm64.X_op)
1009         {
1010         case O_symbol:
1011         case O_subtract:
1012         case O_add:
1013           {
1014             reloc_howto_type *reloc_howto;
1015             int size;
1016 
1017             reloc_howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_64);
1018             if (!reloc_howto)
1019               abort ();
1020 
1021             size = bfd_get_reloc_size (reloc_howto);
1022 
1023             fix_new_exp (frag, where,
1024                          size, &insn->imm64, reloc_howto->pc_relative,
1025                          BFD_RELOC_BPF_64);
1026             break;
1027           }
1028         case O_constant:
1029           /* Already handled in encode_insn.  */
1030           break;
1031         default:
1032           abort ();
1033         }
1034     }
1035 
1036   if (insn->has_imm32)
1037     {
1038       switch (insn->imm32.X_op)
1039         {
1040         case O_symbol:
1041         case O_subtract:
1042         case O_add:
1043         case O_uminus:
1044           {
1045             reloc_howto_type *reloc_howto;
1046             int size;
1047 
1048             reloc_howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
1049             if (!reloc_howto)
1050               abort ();
1051 
1052             size = bfd_get_reloc_size (reloc_howto);
1053 
1054             fix_new_exp (frag, where + 4,
1055                          size, &insn->imm32, reloc_howto->pc_relative,
1056                          BFD_RELOC_32);
1057             break;
1058           }
1059         case O_constant:
1060           /* Already handled in encode_insn.  */
1061           break;
1062         default:
1063           abort ();
1064         }
1065     }
1066 
1067   if (insn->has_disp32)
1068     {
1069       switch (insn->disp32.X_op)
1070         {
1071         case O_symbol:
1072         case O_subtract:
1073         case O_add:
1074           {
1075             reloc_howto_type *reloc_howto;
1076             int size;
1077             unsigned int bfd_reloc
1078               = (insn->id == BPF_INSN_CALL
1079                  ? BFD_RELOC_BPF_DISPCALL32
1080                  : BFD_RELOC_BPF_DISP32);
1081 
1082             reloc_howto = bfd_reloc_type_lookup (stdoutput, bfd_reloc);
1083             if (!reloc_howto)
1084               abort ();
1085 
1086             size = bfd_get_reloc_size (reloc_howto);
1087 
1088             fix_new_exp (frag, where,
1089                          size, &insn->disp32, reloc_howto->pc_relative,
1090                          bfd_reloc);
1091             break;
1092           }
1093         case O_constant:
1094           /* Already handled in encode_insn.  */
1095           break;
1096         default:
1097           abort ();
1098         }
1099     }
1100 
1101   if (insn->has_offset16)
1102     {
1103       switch (insn->offset16.X_op)
1104         {
1105         case O_symbol:
1106         case O_subtract:
1107         case O_add:
1108           {
1109             reloc_howto_type *reloc_howto;
1110             int size;
1111 
1112             /* XXX we really need a new pc-rel offset in bytes
1113                relocation for this.  */
1114             reloc_howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP16);
1115             if (!reloc_howto)
1116               abort ();
1117 
1118             size = bfd_get_reloc_size (reloc_howto);
1119 
1120             fix_new_exp (frag, where,
1121                          size, &insn->offset16, reloc_howto->pc_relative,
1122                          BFD_RELOC_BPF_DISP16);
1123             break;
1124           }
1125         case O_constant:
1126           /* Already handled in encode_insn.  */
1127           break;
1128         default:
1129           abort ();
1130         }
1131     }
1132 
1133   if (insn->has_disp16)
1134     {
1135       switch (insn->disp16.X_op)
1136         {
1137         case O_symbol:
1138         case O_subtract:
1139         case O_add:
1140           {
1141             reloc_howto_type *reloc_howto;
1142             int size;
1143 
1144             reloc_howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP16);
1145             if (!reloc_howto)
1146               abort ();
1147 
1148             size = bfd_get_reloc_size (reloc_howto);
1149 
1150             fix_new_exp (frag, where,
1151                          size, &insn->disp16, reloc_howto->pc_relative,
1152                          BFD_RELOC_BPF_DISP16);
1153             break;
1154           }
1155         case O_constant:
1156           /* Already handled in encode_insn.  */
1157           break;
1158         default:
1159           abort ();
1160         }
1161     }
1162 
1163 }
1164 
1165 /* Add a new insn to the list of instructions.  */
1166 
1167 static void
add_fixed_insn(struct bpf_insn * insn)1168 add_fixed_insn (struct bpf_insn *insn)
1169 {
1170   char *this_frag = frag_more (insn->size);
1171   char bytes[16];
1172   int i;
1173 
1174   /* First encode the known parts of the instruction, including
1175      opcodes and constant immediates, and write them to the frag.  */
1176   encode_insn (insn, bytes, 0 /* relax */);
1177   for (i = 0; i < insn->size; ++i)
1178     md_number_to_chars (this_frag + i, (valueT) bytes[i], 1);
1179 
1180   /* Now install the instruction fixups.  */
1181   install_insn_fixups (insn, frag_now,
1182                        this_frag - frag_now->fr_literal);
1183 }
1184 
1185 /* Add a new relaxable to the list of instructions.  */
1186 
1187 static void
add_relaxed_insn(struct bpf_insn * insn,expressionS * exp)1188 add_relaxed_insn (struct bpf_insn *insn, expressionS *exp)
1189 {
1190   char bytes[16];
1191   int i;
1192   char *this_frag;
1193   unsigned worst_case = relaxed_branch_length (NULL, NULL, 0);
1194   unsigned best_case = insn->size;
1195 
1196   /* We only support relaxing branches, for the moment.  */
1197   relax_substateT subtype
1198     = RELAX_BRANCH_ENCODE (insn->id == BPF_INSN_JAR,
1199                            exp->X_op == O_constant,
1200                            worst_case);
1201 
1202   frag_grow (worst_case);
1203   this_frag = frag_more (0);
1204 
1205   /* First encode the known parts of the instruction, including
1206      opcodes and constant immediates, and write them to the frag.  */
1207   encode_insn (insn, bytes, 1 /* relax */);
1208   for (i = 0; i < insn->size; ++i)
1209     md_number_to_chars (this_frag + i, (valueT) bytes[i], 1);
1210 
1211   /* Note that instruction fixups will be applied once the frag is
1212      relaxed, in md_convert_frag.  */
1213   frag_var (rs_machine_dependent,
1214             worst_case, best_case,
1215             subtype, exp->X_add_symbol, exp->X_add_number /* offset */,
1216             NULL);
1217 }
1218 
1219 
1220 /* Parse an operand expression.  Returns the first character that is
1221    not part of the expression, or NULL in case of parse error.
1222 
1223    See md_operand below to see how exp_parse_failed is used.  */
1224 
1225 static int exp_parse_failed = 0;
1226 static bool parsing_insn_operands = false;
1227 
1228 static char *
parse_expression(char * s,expressionS * exp)1229 parse_expression (char *s, expressionS *exp)
1230 {
1231   char *saved_input_line_pointer = input_line_pointer;
1232   char *saved_s = s;
1233 
1234   /* Wake up bpf_parse_name before the call to expression ().  */
1235   parsing_insn_operands = true;
1236 
1237   exp_parse_failed = 0;
1238   input_line_pointer = s;
1239   expression (exp);
1240   s = input_line_pointer;
1241   input_line_pointer = saved_input_line_pointer;
1242 
1243   switch (exp->X_op == O_absent || exp_parse_failed)
1244     return NULL;
1245 
1246   /* The expression parser may consume trailing whitespaces.  We have
1247      to undo that since the instruction templates may be expecting
1248      these whitespaces.  */
1249   {
1250     char *p;
1251     for (p = s - 1; p >= saved_s && *p == ' '; --p)
1252       --s;
1253   }
1254 
1255   return s;
1256 }
1257 
1258 /* Parse a BPF register name and return the corresponding register
1259    number.  Return NULL in case of parse error, or a pointer to the
1260    first character in S that is not part of the register name.  */
1261 
1262 static char *
parse_bpf_register(char * s,char rw,uint8_t * regno)1263 parse_bpf_register (char *s, char rw, uint8_t *regno)
1264 {
1265   if (asm_dialect == DIALECT_NORMAL)
1266     {
1267       rw = 'r';
1268       if (*s != '%')
1269 	return NULL;
1270       s += 1;
1271 
1272       if (*s == 'f' && *(s + 1) == 'p')
1273 	{
1274 	  *regno = 10;
1275 	  s += 2;
1276 	  return s;
1277 	}
1278     }
1279 
1280   if (*s != rw)
1281     return NULL;
1282   s += 1;
1283 
1284   if (*s == '1')
1285     {
1286       if (*(s + 1) == '0')
1287         {
1288           *regno = 10;
1289           s += 2;
1290         }
1291       else
1292         {
1293           *regno = 1;
1294           s += 1;
1295         }
1296     }
1297   else if (*s >= '0' && *s <= '9')
1298     {
1299       *regno = *s - '0';
1300       s += 1;
1301     }
1302 
1303   /* If we are still parsing a name, it is not a register.  */
1304   if (is_part_of_name (*s))
1305     return NULL;
1306 
1307   return s;
1308 }
1309 
1310 /* Symbols created by this parse, but not yet committed to the real
1311    symbol table.  */
1312 static symbolS *deferred_sym_rootP;
1313 static symbolS *deferred_sym_lastP;
1314 
1315 /* Symbols discarded by a previous parse.  Symbols cannot easily be freed
1316    after creation, so try to recycle.  */
1317 static symbolS *orphan_sym_rootP;
1318 static symbolS *orphan_sym_lastP;
1319 
1320 /* Implement md_parse_name hook.  Handles any symbol found in an expression.
1321    This allows us to tentatively create symbols, before we know for sure
1322    whether the parser is using the correct template for an instruction.
1323    If we end up keeping the instruction, the deferred symbols are committed
1324    to the real symbol table. This approach is modeled after the riscv port.  */
1325 
1326 bool
bpf_parse_name(const char * name,expressionS * exp,enum expr_mode mode)1327 bpf_parse_name (const char *name, expressionS *exp, enum expr_mode mode)
1328 {
1329   symbolS *sym;
1330 
1331   /* If we aren't currently parsing an instruction, don't do anything.
1332      This prevents tampering with operands to directives.  */
1333   if (!parsing_insn_operands)
1334     return false;
1335 
1336   gas_assert (mode == expr_normal);
1337 
1338   /* Pseudo-C syntax uses unprefixed register names like r2 or w3.
1339      Since many instructions take either a register or an
1340      immediate/expression, we should not allow references to symbols
1341      with these names in operands.  */
1342   if (asm_dialect == DIALECT_PSEUDOC)
1343     {
1344       uint8_t regno;
1345 
1346       if (parse_bpf_register ((char *) name, 'r', &regno)
1347           || parse_bpf_register ((char *) name, 'w', &regno))
1348         {
1349           as_bad (_("unexpected register name `%s' in expression"),
1350                   name);
1351           return false;
1352         }
1353     }
1354 
1355   if (symbol_find (name) != NULL)
1356     return false;
1357 
1358   for (sym = deferred_sym_rootP; sym; sym = symbol_next (sym))
1359     if (strcmp (name, S_GET_NAME (sym)) == 0)
1360       break;
1361 
1362   /* Tentatively create a symbol.  */
1363   if (!sym)
1364     {
1365       /* See if we can reuse a symbol discarded by a previous parse.
1366 	 This may be quite common, for example when trying multiple templates
1367 	 for an instruction with the first reference to a valid symbol.  */
1368       for (sym = orphan_sym_rootP; sym; sym = symbol_next (sym))
1369 	if (strcmp (name, S_GET_NAME (sym)) == 0)
1370 	  {
1371 	    symbol_remove (sym, &orphan_sym_rootP, &orphan_sym_lastP);
1372 	    break;
1373 	  }
1374 
1375       if (!sym)
1376 	  sym = symbol_create (name, undefined_section, &zero_address_frag, 0);
1377 
1378       /* Add symbol to the deferred list.  If we commit to the isntruction,
1379 	 then the symbol will be inserted into to the real symbol table at
1380 	 that point (in md_assemble).  */
1381       symbol_append (sym, deferred_sym_lastP, &deferred_sym_rootP,
1382 		     &deferred_sym_lastP);
1383     }
1384 
1385   exp->X_op = O_symbol;
1386   exp->X_add_symbol = sym;
1387   exp->X_add_number = 0;
1388 
1389   return true;
1390 }
1391 
1392 /* Collect a parse error message.  */
1393 
1394 static int partial_match_length = 0;
1395 static char *errmsg = NULL;
1396 
1397 static void
parse_error(int length,const char * fmt,...)1398 parse_error (int length, const char *fmt, ...)
1399 {
1400   if (length > partial_match_length)
1401     {
1402       va_list args;
1403 
1404       free (errmsg);
1405       va_start (args, fmt);
1406       errmsg = xvasprintf (fmt, args);
1407       va_end (args);
1408       partial_match_length = length;
1409     }
1410 
1411   /* Discard deferred symbols from the failed parse.  They may potentially
1412      be reused in the future from the orphan list.  */
1413   while (deferred_sym_rootP)
1414     {
1415       symbolS *sym = deferred_sym_rootP;
1416       symbol_remove (sym, &deferred_sym_rootP, &deferred_sym_lastP);
1417       symbol_append (sym, orphan_sym_lastP, &orphan_sym_rootP,
1418 		     &orphan_sym_lastP);
1419     }
1420 }
1421 
1422 /* Assemble a machine instruction in STR and emit the frags/bytes it
1423    assembles to.  */
1424 
1425 void
md_assemble(char * str ATTRIBUTE_UNUSED)1426 md_assemble (char *str ATTRIBUTE_UNUSED)
1427 {
1428   /* There are two different syntaxes that can be used to write BPF
1429      instructions.  One is very conventional and like any other
1430      assembly language where each instruction is conformed by an
1431      instruction mnemonic followed by its operands.  This is what we
1432      call the "normal" syntax.  The other syntax tries to look like C
1433      statements. We have to support both syntaxes in this assembler.
1434 
1435      One of the many nuisances introduced by this eccentricity is that
1436      in the pseudo-c syntax it is not possible to hash the opcodes
1437      table by instruction mnemonic, because there is none.  So we have
1438      no other choice than to try to parse all instruction opcodes
1439      until one matches.  This is slow.
1440 
1441      Another problem is that emitting detailed diagnostics becomes
1442      tricky, since the lack of mnemonic means it is not clear what
1443      instruction was intended by the user, and we cannot emit
1444      diagnostics for every attempted template.  So if an instruction
1445      is not parsed, we report the diagnostic corresponding to the
1446      partially parsed instruction that was matched further.  */
1447 
1448   unsigned int idx = 0;
1449   struct bpf_insn insn;
1450   const struct bpf_opcode *opcode;
1451 
1452   /* Initialize the global diagnostic variables.  See the parse_error
1453      function above.  */
1454   partial_match_length = 0;
1455   errmsg = NULL;
1456 
1457 #define PARSE_ERROR(...) parse_error (s - str, __VA_ARGS__)
1458 
1459   while ((opcode = bpf_get_opcode (idx++)) != NULL)
1460     {
1461       const char *p;
1462       char *s;
1463       const char *template
1464         = (asm_dialect == DIALECT_PSEUDOC ? opcode->pseudoc : opcode->normal);
1465 
1466       /* Do not try to match opcodes with a higher version than the
1467          selected ISA spec.  */
1468       if (opcode->version > isa_spec)
1469         continue;
1470 
1471       memset (&insn, 0, sizeof (struct bpf_insn));
1472       insn.size = 8;
1473       for (s = str, p = template; *p != '\0';)
1474         {
1475           if (*p == ' ')
1476             {
1477               /* Expect zero or more spaces.  */
1478               while (*s != '\0' && (*s == ' ' || *s == '\t'))
1479                 s += 1;
1480               p += 1;
1481             }
1482           else if (*p == '%')
1483             {
1484               if (*(p + 1) == '%')
1485                 {
1486                   if (*s != '%')
1487                     {
1488                       PARSE_ERROR ("expected '%%'");
1489                       break;
1490                     }
1491                   p += 2;
1492                   s += 1;
1493                 }
1494               else if (*(p + 1) == 'w')
1495                 {
1496                   /* Expect zero or more spaces.  */
1497                   while (*s != '\0' && (*s == ' ' || *s == '\t'))
1498                     s += 1;
1499                   p += 2;
1500                 }
1501               else if (*(p + 1) == 'W')
1502                 {
1503                   /* Expect one or more spaces.  */
1504                   if (*s != ' ' && *s != '\t')
1505                     {
1506                       PARSE_ERROR ("expected white space, got '%s'",
1507                                    s);
1508                       break;
1509                     }
1510                   while (*s != '\0' && (*s == ' ' || *s == '\t'))
1511                     s += 1;
1512                   p += 2;
1513                 }
1514               else if (strncmp (p, "%dr", 3) == 0)
1515                 {
1516                   uint8_t regno;
1517                   char *news = parse_bpf_register (s, 'r', &regno);
1518 
1519                   if (news == NULL || (insn.has_dst && regno != insn.dst))
1520                     {
1521                       if (news != NULL)
1522                         PARSE_ERROR ("expected register r%d, got r%d",
1523                                      insn.dst, regno);
1524                       else
1525                         PARSE_ERROR ("expected register name, got '%s'", s);
1526                       break;
1527                     }
1528                   s = news;
1529                   insn.dst = regno;
1530                   insn.has_dst = 1;
1531                   p += 3;
1532                 }
1533               else if (strncmp (p, "%sr", 3) == 0)
1534                 {
1535                   uint8_t regno;
1536                   char *news = parse_bpf_register (s, 'r', &regno);
1537 
1538                   if (news == NULL || (insn.has_src && regno != insn.src))
1539                     {
1540                       if (news != NULL)
1541                         PARSE_ERROR ("expected register r%d, got r%d",
1542                                      insn.dst, regno);
1543                       else
1544                         PARSE_ERROR ("expected register name, got '%s'", s);
1545                       break;
1546                     }
1547                   s = news;
1548                   insn.src = regno;
1549                   insn.has_src = 1;
1550                   p += 3;
1551                 }
1552               else if (strncmp (p, "%dw", 3) == 0)
1553                 {
1554                   uint8_t regno;
1555                   char *news = parse_bpf_register (s, 'w', &regno);
1556 
1557                   if (news == NULL || (insn.has_dst && regno != insn.dst))
1558                     {
1559                       if (news != NULL)
1560                         PARSE_ERROR ("expected register r%d, got r%d",
1561                                      insn.dst, regno);
1562                       else
1563                         PARSE_ERROR ("expected register name, got '%s'", s);
1564                       break;
1565                     }
1566                   s = news;
1567                   insn.dst = regno;
1568                   insn.has_dst = 1;
1569                   p += 3;
1570                 }
1571               else if (strncmp (p, "%sw", 3) == 0)
1572                 {
1573                   uint8_t regno;
1574                   char *news = parse_bpf_register (s, 'w', &regno);
1575 
1576                   if (news == NULL || (insn.has_src && regno != insn.src))
1577                     {
1578                       if (news != NULL)
1579                         PARSE_ERROR ("expected register r%d, got r%d",
1580                                      insn.dst, regno);
1581                       else
1582                         PARSE_ERROR ("expected register name, got '%s'", s);
1583                       break;
1584                     }
1585                   s = news;
1586                   insn.src = regno;
1587                   insn.has_src = 1;
1588                   p += 3;
1589                 }
1590               else if (strncmp (p, "%i32", 4) == 0
1591                        || strncmp (p, "%I32", 4) == 0)
1592                 {
1593                   if (p[1] == 'I')
1594                     {
1595                       while (*s == ' ' || *s == '\t')
1596                         s += 1;
1597                       if (*s != '+' && *s != '-')
1598                         {
1599                           PARSE_ERROR ("expected `+' or `-', got `%c'", *s);
1600                           break;
1601                         }
1602                     }
1603 
1604                   s = parse_expression (s, &insn.imm32);
1605                   if (s == NULL)
1606                     {
1607                       PARSE_ERROR ("expected signed 32-bit immediate");
1608                       break;
1609                     }
1610                   insn.has_imm32 = 1;
1611                   p += 4;
1612                 }
1613               else if (strncmp (p, "%o16", 4) == 0)
1614                 {
1615                   while (*s == ' ' || *s == '\t')
1616                     s += 1;
1617                   if (*s != '+' && *s != '-')
1618                     {
1619                       PARSE_ERROR ("expected `+' or `-', got `%c'", *s);
1620                       break;
1621                     }
1622 
1623                   s = parse_expression (s, &insn.offset16);
1624                   if (s == NULL)
1625                     {
1626                       PARSE_ERROR ("expected signed 16-bit offset");
1627                       break;
1628                     }
1629                   insn.has_offset16 = 1;
1630                   p += 4;
1631                 }
1632               else if (strncmp (p, "%d16", 4) == 0)
1633                 {
1634                   s = parse_expression (s, &insn.disp16);
1635                   if (s == NULL)
1636                     {
1637                       PARSE_ERROR ("expected signed 16-bit displacement");
1638                       break;
1639                     }
1640                   insn.has_disp16 = 1;
1641                   insn.is_relaxable = (insn.disp16.X_op != O_constant);
1642                   p += 4;
1643                 }
1644               else if (strncmp (p, "%d32", 4) == 0)
1645                 {
1646                   s = parse_expression (s, &insn.disp32);
1647                   if (s == NULL)
1648                     {
1649                       PARSE_ERROR ("expected signed 32-bit displacement");
1650                       break;
1651                     }
1652                   insn.has_disp32 = 1;
1653                   p += 4;
1654                 }
1655               else if (strncmp (p, "%i64", 4) == 0)
1656                 {
1657                   s = parse_expression (s, &insn.imm64);
1658                   if (s == NULL)
1659                     {
1660                       PARSE_ERROR ("expected signed 64-bit immediate");
1661                       break;
1662                     }
1663                   insn.has_imm64 = 1;
1664                   insn.size = 16;
1665                   p += 4;
1666                 }
1667               else
1668                 as_fatal (_("invalid %%-tag in BPF opcode '%s'\n"), template);
1669             }
1670           else
1671             {
1672               /* Match a literal character.  */
1673               if (*s != *p)
1674                 {
1675                   if (*s == '\0')
1676                     PARSE_ERROR ("expected '%c'", *p);
1677                   else if (*s == '%')
1678                     {
1679                       /* This is to workaround a bug in as_bad. */
1680                       char tmp[3];
1681 
1682                       tmp[0] = '%';
1683                       tmp[1] = '%';
1684                       tmp[2] = '\0';
1685 
1686                       PARSE_ERROR ("expected '%c', got '%s'", *p, tmp);
1687                     }
1688                   else
1689                     PARSE_ERROR ("expected '%c', got '%c'", *p, *s);
1690                   break;
1691                 }
1692               p += 1;
1693               s += 1;
1694             }
1695         }
1696 
1697       if (*p == '\0')
1698         {
1699           /* Allow white spaces at the end of the line.  */
1700           while (*s != '\0' && (*s == ' ' || *s == '\t'))
1701             s += 1;
1702           if (*s == '\0')
1703             /* We parsed an instruction successfully.  */
1704             break;
1705           PARSE_ERROR ("extra junk at end of line");
1706         }
1707     }
1708 
1709   /* Mark that we are no longer parsing an instruction, bpf_parse_name does
1710      not interfere with symbols in e.g. assembler directives.  */
1711   parsing_insn_operands = false;
1712 
1713   if (opcode == NULL)
1714     {
1715       as_bad (_("unrecognized instruction `%s'"), str);
1716       if (errmsg != NULL)
1717         {
1718           as_bad ("%s", errmsg);
1719           free (errmsg);
1720         }
1721 
1722       return;
1723     }
1724   insn.id = opcode->id;
1725   insn.opcode = opcode->opcode;
1726 
1727 #undef PARSE_ERROR
1728 
1729   /* Commit any symbols created while parsing the instruction.  */
1730   while (deferred_sym_rootP)
1731     {
1732       symbolS *sym = deferred_sym_rootP;
1733       symbol_remove (sym, &deferred_sym_rootP, &deferred_sym_lastP);
1734       symbol_append (sym, symbol_lastP, &symbol_rootP, &symbol_lastP);
1735       symbol_table_insert (sym);
1736     }
1737 
1738   /* Generate the frags and fixups for the parsed instruction.  */
1739   if (do_relax && isa_spec >= BPF_V4 && insn.is_relaxable)
1740     {
1741       expressionS *relaxable_exp = NULL;
1742 
1743       if (insn.has_disp16)
1744         relaxable_exp = &insn.disp16;
1745       else
1746         abort ();
1747 
1748       add_relaxed_insn (&insn, relaxable_exp);
1749     }
1750   else
1751     add_fixed_insn (&insn);
1752 
1753   /* Emit DWARF2 debugging information.  */
1754   dwarf2_emit_insn (insn.size);
1755 }
1756 
1757 /* Parse an operand that is machine-specific.  */
1758 
1759 void
md_operand(expressionS * expressionP)1760 md_operand (expressionS *expressionP)
1761 {
1762   /* If this hook is invoked it means GAS failed to parse a generic
1763      expression.  We should inhibit the as_bad in expr.c, so we can
1764      fail while parsing instruction alternatives.  To do that, we
1765      change the expression to not have an O_absent.  But then we also
1766      need to set exp_parse_failed to parse_expression above does the
1767      right thing.  */
1768   ++input_line_pointer;
1769   expressionP->X_op = O_constant;
1770   expressionP->X_add_number = 0;
1771   exp_parse_failed = 1;
1772 }
1773 
1774 symbolS *
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)1775 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1776 {
1777   return NULL;
1778 }
1779 
1780 
1781 /* Turn a string in input_line_pointer into a floating point constant
1782    of type TYPE, and store the appropriate bytes in *LITP.  The number
1783    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
1784    returned, or NULL on OK.  */
1785 
1786 const char *
md_atof(int type,char * litP,int * sizeP)1787 md_atof (int type, char *litP, int *sizeP)
1788 {
1789   return ieee_md_atof (type, litP, sizeP, false);
1790 }
1791 
1792 
1793 /* Determine whether the equal sign in the given string corresponds to
1794    a BPF instruction, i.e. when it is not to be considered a symbol
1795    assignment.  */
1796 
1797 bool
bpf_tc_equal_in_insn(int c ATTRIBUTE_UNUSED,char * str ATTRIBUTE_UNUSED)1798 bpf_tc_equal_in_insn (int c ATTRIBUTE_UNUSED, char *str ATTRIBUTE_UNUSED)
1799 {
1800   uint8_t regno;
1801 
1802   /* Only pseudo-c instructions can have equal signs, and of these,
1803      all that could be confused with a symbol assignment all start
1804      with a register name.  */
1805   if (asm_dialect == DIALECT_PSEUDOC)
1806     {
1807       char *w = parse_bpf_register (str, 'w', &regno);
1808       char *r = parse_bpf_register (str, 'r', &regno);
1809 
1810       if ((w != NULL && *w == '\0')
1811           || (r != NULL && *r == '\0'))
1812         return 1;
1813     }
1814 
1815   return 0;
1816 }
1817 
1818 /* Some special processing for a BPF ELF file.  */
1819 
1820 void
bpf_elf_final_processing(void)1821 bpf_elf_final_processing (void)
1822 {
1823   /* Annotate the BPF ISA version in the ELF flag bits.  */
1824   elf_elfheader (stdoutput)->e_flags |= (isa_spec & EF_BPF_CPUVER);
1825 }
1826