1 /* tc-bpf.c -- Assembler for the Linux eBPF.
2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
3 Contributed by Oracle, Inc.
5 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
25 #include "opcode/bpf.h"
26 #include "elf/common.h"
28 #include "dwarf2dbg.h"
29 #include "libiberty.h"
32 /* Data structure representing a parsed BPF instruction. */
37 int size
; /* Instruction size in bytes. */
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;
55 unsigned int is_relaxable
: 1;
56 expressionS
*relaxed_exp
;
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";
65 /* Like s_lcomm_internal in gas/read.c but the alignment string
66 is allowed to be optional. */
69 pe_lcomm_internal (int needs_align
, symbolS
*symbolP
, addressT size
)
76 && *input_line_pointer
== ',')
78 align
= parse_align (needs_align
- 1);
80 if (align
== (addressT
) -1)
95 bss_alloc (symbolP
, size
, align
);
100 pe_lcomm (int needs_align
)
102 s_comm_internal (needs_align
* 2, pe_lcomm_internal
);
105 /* The target specific pseudo-ops which we support. */
106 const pseudo_typeS md_pseudo_table
[] =
110 { "dword", cons
, 8 },
111 { "lcomm", pe_lcomm
, 1 },
117 /* Command-line options processing. */
121 OPTION_LITTLE_ENDIAN
= OPTION_MD_BASE
,
129 struct option md_longopts
[] =
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 },
140 size_t md_longopts_size
= sizeof (md_longopts
);
142 const char * md_shortopts
= "";
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. */
149 static int set_target_endian
= 0;
150 extern int target_big_endian
;
152 /* Whether to relax branch instructions. Default is yes. Can be
153 changed using the -mno-relax command line option. */
155 static int do_relax
= 1;
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. */
161 static int isa_spec
= BPF_V4
;
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. */
167 enum target_asm_dialect
173 static int asm_dialect
= DIALECT_NORMAL
;
176 md_parse_option (int c
, const char * arg
)
180 case OPTION_BIG_ENDIAN
:
181 set_target_endian
= 1;
182 target_big_endian
= 1;
184 case OPTION_LITTLE_ENDIAN
:
185 set_target_endian
= 0;
186 target_big_endian
= 0;
189 if (strcmp (arg
, "normal") == 0)
190 asm_dialect
= DIALECT_NORMAL
;
191 else if (strcmp (arg
, "pseudoc") == 0)
192 asm_dialect
= DIALECT_PSEUDOC
;
194 as_fatal (_("-mdialect=%s is not valid. Expected normal or pseudoc"),
197 case OPTION_ISA_SPEC
:
198 if (strcmp (arg
, "v1") == 0)
200 else if (strcmp (arg
, "v2") == 0)
202 else if (strcmp (arg
, "v3") == 0)
204 else if (strcmp (arg
, "v4") == 0)
206 else if (strcmp (arg
, "xbpf") == 0)
209 as_fatal (_("-misa-spec=%s is not valid. Expected v1, v2, v3, v4 o xbpf"),
213 /* This is an alias for -misa-spec=xbpf. */
216 case OPTION_NO_RELAX
:
227 md_show_usage (FILE * stream
)
229 fprintf (stream
, _("\nBPF options:\n"));
230 fprintf (stream
, _("\
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"));
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
247 /* If not specified in the command line, use the host
249 if (!set_target_endian
)
251 #ifdef WORDS_BIGENDIAN
252 target_big_endian
= 1;
254 target_big_endian
= 0;
258 /* Ensure that lines can begin with '*' in BPF store pseudoc instruction. */
259 lex_type
['*'] |= LEX_BEGIN_NAME
;
261 /* Set the machine type. */
262 bfd_default_set_arch_mach (stdoutput
, bfd_arch_bpf
, bfd_mach_bpf
);
265 /* Round up a section size to the appropriate boundary. */
268 md_section_align (segT segment
, valueT size
)
270 int align
= bfd_section_alignment (segment
);
272 return ((size
+ (1 << align
) - 1) & -(1 << align
));
276 /* Functions concerning relocs. */
278 /* The location from which a PC relative jump should be calculated,
279 given a PC relative reloc. */
282 md_pcrel_from_section (fixS
*fixP
, segT sec
)
284 if (fixP
->fx_addsy
!= (symbolS
*) NULL
285 && (! S_IS_DEFINED (fixP
->fx_addsy
)
286 || (S_GET_SEGMENT (fixP
->fx_addsy
) != sec
)
287 || S_IS_EXTERNAL (fixP
->fx_addsy
)
288 || S_IS_WEAK (fixP
->fx_addsy
)))
290 /* The symbol is undefined (or is defined but not in this section).
291 Let the linker figure it out. */
295 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
298 /* Write a value out to the object file, using the appropriate endianness. */
301 md_number_to_chars (char * buf
, valueT val
, int n
)
303 if (target_big_endian
)
304 number_to_chars_bigendian (buf
, val
, n
);
306 number_to_chars_littleendian (buf
, val
, n
);
310 tc_gen_reloc (asection
*sec ATTRIBUTE_UNUSED
, fixS
*fixP
)
312 bfd_reloc_code_real_type r_type
= fixP
->fx_r_type
;
315 reloc
= XNEW (arelent
);
319 r_type
= (r_type
== BFD_RELOC_8
? BFD_RELOC_8_PCREL
320 : r_type
== BFD_RELOC_16
? BFD_RELOC_16_PCREL
321 : r_type
== BFD_RELOC_24
? BFD_RELOC_24_PCREL
322 : r_type
== BFD_RELOC_32
? BFD_RELOC_32_PCREL
323 : r_type
== BFD_RELOC_64
? BFD_RELOC_64_PCREL
327 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, r_type
);
329 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
331 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
332 _("relocation is not supported"));
336 //XXX gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
338 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
339 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
341 /* Use fx_offset for these cases. */
342 if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
343 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
)
344 reloc
->addend
= fixP
->fx_offset
;
346 reloc
->addend
= fixP
->fx_addnumber
;
348 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
353 /* Relaxations supported by this assembler. */
355 #define RELAX_BRANCH_ENCODE(uncond, constant, length) \
358 | ((uncond) ? 1 : 0) \
359 | ((constant) ? 2 : 0) \
362 #define RELAX_BRANCH_P(i) (((i) & 0xf0000000) == 0xc0000000)
363 #define RELAX_BRANCH_LENGTH(i) (((i) >> 2) & 0xff)
364 #define RELAX_BRANCH_CONST(i) (((i) & 2) != 0)
365 #define RELAX_BRANCH_UNCOND(i) (((i) & 1) != 0)
368 /* Compute the length of a branch seuqence, and adjust the stored
369 length accordingly. If FRAG is NULL, the worst-case length is
373 relaxed_branch_length (fragS
*fragp
, asection
*sec
, int update
)
380 uncond
= RELAX_BRANCH_UNCOND (fragp
->fr_subtype
);
381 length
= RELAX_BRANCH_LENGTH (fragp
->fr_subtype
);
384 /* Length is the same for both JA and JAL. */
388 if (RELAX_BRANCH_CONST (fragp
->fr_subtype
))
390 int64_t val
= fragp
->fr_offset
;
392 if (val
< -32768 || val
> 32767)
397 else if (fragp
->fr_symbol
!= NULL
398 && S_IS_DEFINED (fragp
->fr_symbol
)
399 && !S_IS_WEAK (fragp
->fr_symbol
)
400 && sec
== S_GET_SEGMENT (fragp
->fr_symbol
))
402 offsetT val
= S_GET_VALUE (fragp
->fr_symbol
) + fragp
->fr_offset
;
404 /* Convert to 64-bit words, minus one. */
407 /* See if it fits in the signed 16-bits field. */
408 if (val
< -32768 || val
> 32767)
414 /* Use short version, and let the linker relax instead, if
415 appropriate and if supported. */
420 fragp
->fr_subtype
= RELAX_BRANCH_ENCODE (uncond
,
421 RELAX_BRANCH_CONST (fragp
->fr_subtype
),
427 /* Estimate the size of a variant frag before relaxing. */
430 md_estimate_size_before_relax (fragS
*fragp
, asection
*sec
)
432 return (fragp
->fr_var
= relaxed_branch_length (fragp
, sec
, true));
435 /* Read a BPF instruction word from BUF. */
438 read_insn_word (bfd_byte
*buf
)
440 return bfd_getb64 (buf
);
443 /* Write the given signed 16-bit value in the given BUFFER using the
444 target endianness. */
447 encode_int16 (int16_t value
, char *buffer
)
449 uint16_t val
= value
;
451 if (target_big_endian
)
453 buffer
[0] = (val
>> 8) & 0xff;
454 buffer
[1] = val
& 0xff;
458 buffer
[1] = (val
>> 8) & 0xff;
459 buffer
[0] = val
& 0xff;
463 /* Write the given signed 32-bit value in the given BUFFER using the
464 target endianness. */
467 encode_int32 (int32_t value
, char *buffer
)
469 uint32_t val
= value
;
471 if (target_big_endian
)
473 buffer
[0] = (val
>> 24) & 0xff;
474 buffer
[1] = (val
>> 16) & 0xff;
475 buffer
[2] = (val
>> 8) & 0xff;
476 buffer
[3] = val
& 0xff;
480 buffer
[3] = (val
>> 24) & 0xff;
481 buffer
[2] = (val
>> 16) & 0xff;
482 buffer
[1] = (val
>> 8) & 0xff;
483 buffer
[0] = value
& 0xff;
487 /* Write a BPF instruction to BUF. */
490 write_insn_bytes (bfd_byte
*buf
, char *bytes
)
494 for (i
= 0; i
< 8; ++i
)
495 md_number_to_chars ((char *) buf
+ i
, (valueT
) bytes
[i
], 1);
498 /* *FRAGP has been relaxed to its final size, and now needs to have
499 the bytes inside it modified to conform to the new size.
501 Called after relaxation is finished.
502 fragP->fr_type == rs_machine_dependent.
503 fragP->fr_subtype is the subtype of what the address relaxed to. */
506 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
507 segT sec ATTRIBUTE_UNUSED
,
508 fragS
*fragp ATTRIBUTE_UNUSED
)
510 bfd_byte
*buf
= (bfd_byte
*) fragp
->fr_literal
+ fragp
->fr_fix
;
514 int disp_is_known
= 0;
515 int64_t disp_to_target
= 0;
519 gas_assert (RELAX_BRANCH_P (fragp
->fr_subtype
));
521 /* Expression to be used in any resulting relocation in the relaxed
524 exp
.X_add_symbol
= fragp
->fr_symbol
;
525 exp
.X_add_number
= fragp
->fr_offset
;
527 gas_assert (fragp
->fr_var
== RELAX_BRANCH_LENGTH (fragp
->fr_subtype
));
529 /* Read an instruction word from the instruction to be relaxed, and
531 word
= read_insn_word (buf
);
532 code
= (word
>> 60) & 0xf;
534 /* Determine whether the 16-bit displacement to the target is known
536 if (RELAX_BRANCH_CONST (fragp
->fr_subtype
))
538 /* XXX this loses the 32-bit value if the constant was
540 disp_to_target
= fragp
->fr_offset
;
543 else if (fragp
->fr_symbol
!= NULL
544 && S_IS_DEFINED (fragp
->fr_symbol
)
545 && !S_IS_WEAK (fragp
->fr_symbol
)
546 && sec
== S_GET_SEGMENT (fragp
->fr_symbol
))
548 offsetT val
= S_GET_VALUE (fragp
->fr_symbol
) + fragp
->fr_offset
;
549 /* Convert to 64-bit blocks minus one. */
550 disp_to_target
= (val
- 8) / 8;
554 /* Now relax particular jump instructions. */
555 if (code
== BPF_CODE_JA
)
557 /* Unconditional jump.
560 gas_assert (RELAX_BRANCH_UNCOND (fragp
->fr_subtype
));
564 if (disp_to_target
>= -32768 && disp_to_target
<= 32767)
566 /* 16-bit disp is known and in range. Install a fixup
567 for the disp16 if the branch value is not constant.
568 This will be resolved by the assembler and units
571 if (!RELAX_BRANCH_CONST (fragp
->fr_subtype
))
573 /* Install fixup for the JA. */
574 reloc_howto_type
*reloc_howto
575 = bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_BPF_DISP16
);
579 fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*) fragp
->fr_literal
,
580 bfd_get_reloc_size (reloc_howto
),
582 reloc_howto
->pc_relative
,
583 BFD_RELOC_BPF_DISP16
);
584 fixp
->fx_file
= fragp
->fr_file
;
585 fixp
->fx_line
= fragp
->fr_line
;
590 /* 16-bit disp is known and not in range. Turn the JA
591 into a JAL with a 32-bit displacement. */
594 bytes
[0] = ((BPF_CLASS_JMP32
|BPF_CODE_JA
|BPF_SRC_K
) >> 56) & 0xff;
595 bytes
[1] = (word
>> 48) & 0xff;
596 bytes
[2] = 0; /* disp16 high */
597 bytes
[3] = 0; /* disp16 lo */
598 encode_int32 ((int32_t) disp_to_target
, bytes
+ 4);
600 write_insn_bytes (buf
, bytes
);
605 /* The displacement to the target is not known. Do not
606 relax. The linker will maybe do it if it chooses to. */
608 reloc_howto_type
*reloc_howto
= NULL
;
610 gas_assert (!RELAX_BRANCH_CONST (fragp
->fr_subtype
));
612 /* Install fixup for the JA. */
613 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_BPF_DISP16
);
617 fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*) fragp
->fr_literal
,
618 bfd_get_reloc_size (reloc_howto
),
620 reloc_howto
->pc_relative
,
621 BFD_RELOC_BPF_DISP16
);
622 fixp
->fx_file
= fragp
->fr_file
;
623 fixp
->fx_line
= fragp
->fr_line
;
631 JXX d16 -> JXX +1; JA +1; JAL d32 */
633 gas_assert (!RELAX_BRANCH_UNCOND (fragp
->fr_subtype
));
637 if (disp_to_target
>= -32768 && disp_to_target
<= 32767)
639 /* 16-bit disp is known and in range. Install a fixup
640 for the disp16 if the branch value is not constant.
641 This will be resolved by the assembler and units
644 if (!RELAX_BRANCH_CONST (fragp
->fr_subtype
))
646 /* Install fixup for the branch. */
647 reloc_howto_type
*reloc_howto
648 = bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_BPF_DISP16
);
652 fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*) fragp
->fr_literal
,
653 bfd_get_reloc_size (reloc_howto
),
655 reloc_howto
->pc_relative
,
656 BFD_RELOC_BPF_DISP16
);
657 fixp
->fx_file
= fragp
->fr_file
;
658 fixp
->fx_line
= fragp
->fr_line
;
665 /* 16-bit disp is known and not in range. Turn the JXX
666 into a sequence JXX +1; JA +1; JAL d32. */
670 /* First, set the 16-bit offset in the current
673 if (target_big_endian
)
674 bfd_putb16 (1, buf
+ 2);
676 bfd_putl16 (1, buf
+ 2);
679 /* Then, write the JA + 1 */
681 bytes
[0] = 0x05; /* JA */
683 encode_int16 (1, bytes
+ 2);
688 write_insn_bytes (buf
, bytes
);
691 /* Finally, write the JAL to the target. */
693 bytes
[0] = ((BPF_CLASS_JMP32
|BPF_CODE_JA
|BPF_SRC_K
) >> 56) & 0xff;
697 encode_int32 ((int32_t) disp_to_target
, bytes
+ 4);
698 write_insn_bytes (buf
, bytes
);
704 /* The displacement to the target is not known. Do not
705 relax. The linker will maybe do it if it chooses to. */
707 reloc_howto_type
*reloc_howto
= NULL
;
709 gas_assert (!RELAX_BRANCH_CONST (fragp
->fr_subtype
));
711 /* Install fixup for the conditional jump. */
712 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_BPF_DISP16
);
716 fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*) fragp
->fr_literal
,
717 bfd_get_reloc_size (reloc_howto
),
719 reloc_howto
->pc_relative
,
720 BFD_RELOC_BPF_DISP16
);
721 fixp
->fx_file
= fragp
->fr_file
;
722 fixp
->fx_line
= fragp
->fr_line
;
727 gas_assert (buf
== (bfd_byte
*)fragp
->fr_literal
728 + fragp
->fr_fix
+ fragp
->fr_var
);
730 fragp
->fr_fix
+= fragp
->fr_var
;
734 /* Apply a fixS (fixup of an instruction or data that we didn't have
735 enough info to complete immediately) to the data in a frag. */
738 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
740 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
742 switch (fixP
->fx_r_type
)
744 case BFD_RELOC_BPF_DISP16
:
745 /* Convert from bytes to number of 64-bit words to the target,
747 *valP
= (((long) (*valP
)) - 8) / 8;
749 case BFD_RELOC_BPF_DISPCALL32
:
750 case BFD_RELOC_BPF_DISP32
:
751 /* Convert from bytes to number of 64-bit words to the target,
753 *valP
= (((long) (*valP
)) - 8) / 8;
755 if (fixP
->fx_r_type
== BFD_RELOC_BPF_DISPCALL32
)
757 /* eBPF supports two kind of CALL instructions: the so
758 called pseudo calls ("bpf to bpf") and external calls
761 Both kind of calls use the same instruction (CALL).
762 However, external calls are constructed by passing a
763 constant argument to the instruction, whereas pseudo
764 calls result from expressions involving symbols. In
765 practice, instructions requiring a fixup are interpreted
766 as pseudo-calls. If we are executing this code, this is
769 The kernel expects for pseudo-calls to be annotated by
770 having BPF_PSEUDO_CALL in the SRC field of the
771 instruction. But beware the infamous nibble-swapping of
772 eBPF and take endianness into account here.
774 Note that the CALL instruction has only one operand, so
775 this code is executed only once per instruction. */
776 md_number_to_chars (where
+ 1, target_big_endian
? 0x01 : 0x10, 1);
779 case BFD_RELOC_16_PCREL
:
780 /* Convert from bytes to number of 64-bit words to the target,
782 *valP
= (((long) (*valP
)) - 8) / 8;
788 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
793 /* We're finished with this fixup. Install it because
794 bfd_install_relocation won't be called to do it. */
795 switch (fixP
->fx_r_type
)
798 md_number_to_chars (where
, *valP
, 1);
801 md_number_to_chars (where
, *valP
, 2);
804 md_number_to_chars (where
, *valP
, 4);
807 md_number_to_chars (where
, *valP
, 8);
809 case BFD_RELOC_BPF_DISP16
:
810 md_number_to_chars (where
+ 2, (uint16_t) *valP
, 2);
812 case BFD_RELOC_BPF_DISP32
:
813 case BFD_RELOC_BPF_DISPCALL32
:
814 md_number_to_chars (where
+ 4, (uint32_t) *valP
, 4);
816 case BFD_RELOC_16_PCREL
:
817 md_number_to_chars (where
+ 2, (uint32_t) *valP
, 2);
820 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
821 _("internal error: can't install fix for reloc type %d (`%s')"),
822 fixP
->fx_r_type
, bfd_get_reloc_code_name (fixP
->fx_r_type
));
827 /* Tuck `value' away for use by tc_gen_reloc.
828 See the comment describing fx_addnumber in write.h.
829 This field is misnamed (or misused :-). */
830 fixP
->fx_addnumber
= *valP
;
834 /* Instruction writing routines. */
836 /* Encode a BPF instruction in the given buffer BYTES. Non-constant
837 immediates are encoded as zeroes. */
840 encode_insn (struct bpf_insn
*insn
, char *bytes
)
844 /* Zero all the bytes. */
845 memset (bytes
, 0, 16);
847 /* First encode the opcodes. Note that we have to handle the
848 endianness groups of the BPF instructions: 8 | 4 | 4 | 16 |
850 if (target_big_endian
)
853 bytes
[0] = (insn
->opcode
>> 56) & 0xff;
855 bytes
[1] = (insn
->opcode
>> 48) & 0xff;
857 bytes
[2] = (insn
->opcode
>> 40) & 0xff;
858 bytes
[3] = (insn
->opcode
>> 32) & 0xff;
860 bytes
[4] = (insn
->opcode
>> 24) & 0xff;
861 bytes
[5] = (insn
->opcode
>> 16) & 0xff;
862 bytes
[6] = (insn
->opcode
>> 8) & 0xff;
863 bytes
[7] = insn
->opcode
& 0xff;
868 bytes
[0] = (insn
->opcode
>> 56) & 0xff;
870 bytes
[1] = (((((insn
->opcode
>> 48) & 0xff) & 0xf) << 4)
871 | (((insn
->opcode
>> 48) & 0xff) & 0xf));
873 bytes
[3] = (insn
->opcode
>> 40) & 0xff;
874 bytes
[2] = (insn
->opcode
>> 32) & 0xff;
876 bytes
[7] = (insn
->opcode
>> 24) & 0xff;
877 bytes
[6] = (insn
->opcode
>> 16) & 0xff;
878 bytes
[5] = (insn
->opcode
>> 8) & 0xff;
879 bytes
[4] = insn
->opcode
& 0xff;
882 /* Now the registers. */
883 src
= insn
->has_src
? insn
->src
: 0;
884 dst
= insn
->has_dst
? insn
->dst
: 0;
886 if (target_big_endian
)
887 bytes
[1] = ((dst
& 0xf) << 4) | (src
& 0xf);
889 bytes
[1] = ((src
& 0xf) << 4) | (dst
& 0xf);
891 /* Now the immediates that are known to be constant. */
893 if (insn
->has_imm32
&& insn
->imm32
.X_op
== O_constant
)
894 encode_int32 (insn
->imm32
.X_add_number
, bytes
+ 4);
896 if (insn
->has_disp32
&& insn
->disp32
.X_op
== O_constant
)
897 encode_int32 (insn
->disp32
.X_add_number
, bytes
+ 4);
899 if (insn
->has_offset16
&& insn
->offset16
.X_op
== O_constant
)
900 encode_int16 (insn
->offset16
.X_add_number
, bytes
+ 2);
902 if (insn
->has_disp16
&& insn
->disp16
.X_op
== O_constant
)
903 encode_int16 (insn
->disp16
.X_add_number
, bytes
+ 2);
905 if (insn
->has_imm64
&& insn
->imm64
.X_op
== O_constant
)
907 uint64_t imm64
= insn
->imm64
.X_add_number
;
909 if (target_big_endian
)
911 bytes
[12] = (imm64
>> 56) & 0xff;
912 bytes
[13] = (imm64
>> 48) & 0xff;
913 bytes
[14] = (imm64
>> 40) & 0xff;
914 bytes
[15] = (imm64
>> 32) & 0xff;
915 bytes
[4] = (imm64
>> 24) & 0xff;
916 bytes
[5] = (imm64
>> 16) & 0xff;
917 bytes
[6] = (imm64
>> 8) & 0xff;
918 bytes
[7] = imm64
& 0xff;
922 bytes
[15] = (imm64
>> 56) & 0xff;
923 bytes
[14] = (imm64
>> 48) & 0xff;
924 bytes
[13] = (imm64
>> 40) & 0xff;
925 bytes
[12] = (imm64
>> 32) & 0xff;
926 bytes
[7] = (imm64
>> 24) & 0xff;
927 bytes
[6] = (imm64
>> 16) & 0xff;
928 bytes
[5] = (imm64
>> 8) & 0xff;
929 bytes
[4] = imm64
& 0xff;
934 /* Install the fixups in INSN in their proper location in the
935 specified FRAG at the location pointed by WHERE. */
938 install_insn_fixups (struct bpf_insn
*insn
, fragS
*frag
, long where
)
942 switch (insn
->imm64
.X_op
)
948 reloc_howto_type
*reloc_howto
;
951 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_BPF_64
);
955 size
= bfd_get_reloc_size (reloc_howto
);
957 fix_new_exp (frag
, where
,
958 size
, &insn
->imm64
, reloc_howto
->pc_relative
,
963 /* Already handled in encode_insn. */
972 switch (insn
->imm32
.X_op
)
979 reloc_howto_type
*reloc_howto
;
982 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
986 size
= bfd_get_reloc_size (reloc_howto
);
988 fix_new_exp (frag
, where
+ 4,
989 size
, &insn
->imm32
, reloc_howto
->pc_relative
,
994 /* Already handled in encode_insn. */
1001 if (insn
->has_disp32
)
1003 switch (insn
->disp32
.X_op
)
1009 reloc_howto_type
*reloc_howto
;
1011 unsigned int bfd_reloc
1012 = (insn
->id
== BPF_INSN_CALL
1013 ? BFD_RELOC_BPF_DISPCALL32
1014 : BFD_RELOC_BPF_DISP32
);
1016 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, bfd_reloc
);
1020 size
= bfd_get_reloc_size (reloc_howto
);
1022 fix_new_exp (frag
, where
,
1023 size
, &insn
->disp32
, reloc_howto
->pc_relative
,
1028 /* Already handled in encode_insn. */
1035 if (insn
->has_offset16
)
1037 switch (insn
->offset16
.X_op
)
1043 reloc_howto_type
*reloc_howto
;
1046 /* XXX we really need a new pc-rel offset in bytes
1047 relocation for this. */
1048 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_BPF_DISP16
);
1052 size
= bfd_get_reloc_size (reloc_howto
);
1054 fix_new_exp (frag
, where
,
1055 size
, &insn
->offset16
, reloc_howto
->pc_relative
,
1056 BFD_RELOC_BPF_DISP16
);
1060 /* Already handled in encode_insn. */
1067 if (insn
->has_disp16
)
1069 switch (insn
->disp16
.X_op
)
1075 reloc_howto_type
*reloc_howto
;
1078 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_BPF_DISP16
);
1082 size
= bfd_get_reloc_size (reloc_howto
);
1084 fix_new_exp (frag
, where
,
1085 size
, &insn
->disp16
, reloc_howto
->pc_relative
,
1086 BFD_RELOC_BPF_DISP16
);
1090 /* Already handled in encode_insn. */
1099 /* Add a new insn to the list of instructions. */
1102 add_fixed_insn (struct bpf_insn
*insn
)
1104 char *this_frag
= frag_more (insn
->size
);
1108 /* First encode the known parts of the instruction, including
1109 opcodes and constant immediates, and write them to the frag. */
1110 encode_insn (insn
, bytes
);
1111 for (i
= 0; i
< insn
->size
; ++i
)
1112 md_number_to_chars (this_frag
+ i
, (valueT
) bytes
[i
], 1);
1114 /* Now install the instruction fixups. */
1115 install_insn_fixups (insn
, frag_now
,
1116 this_frag
- frag_now
->fr_literal
);
1119 /* Add a new relaxable to the list of instructions. */
1122 add_relaxed_insn (struct bpf_insn
*insn
, expressionS
*exp
)
1127 unsigned worst_case
= relaxed_branch_length (NULL
, NULL
, 0);
1128 unsigned best_case
= insn
->size
;
1130 /* We only support relaxing branches, for the moment. */
1131 relax_substateT subtype
1132 = RELAX_BRANCH_ENCODE (insn
->id
== BPF_INSN_JAR
,
1133 exp
->X_op
== O_constant
,
1136 frag_grow (worst_case
);
1137 this_frag
= frag_more (0);
1139 /* First encode the known parts of the instruction, including
1140 opcodes and constant immediates, and write them to the frag. */
1141 encode_insn (insn
, bytes
);
1142 for (i
= 0; i
< insn
->size
; ++i
)
1143 md_number_to_chars (this_frag
+ i
, (valueT
) bytes
[i
], 1);
1145 /* Note that instruction fixups will be applied once the frag is
1146 relaxed, in md_convert_frag. */
1147 frag_var (rs_machine_dependent
,
1148 worst_case
, best_case
,
1149 subtype
, exp
->X_add_symbol
, exp
->X_add_number
/* offset */,
1154 /* Parse an operand expression. Returns the first character that is
1155 not part of the expression, or NULL in case of parse error.
1157 See md_operand below to see how exp_parse_failed is used. */
1159 static int exp_parse_failed
= 0;
1162 parse_expression (char *s
, expressionS
*exp
)
1164 char *saved_input_line_pointer
= input_line_pointer
;
1167 exp_parse_failed
= 0;
1168 input_line_pointer
= s
;
1170 s
= input_line_pointer
;
1171 input_line_pointer
= saved_input_line_pointer
;
1173 switch (exp
->X_op
== O_absent
|| exp_parse_failed
)
1176 /* The expression parser may consume trailing whitespaces. We have
1177 to undo that since the instruction templates may be expecting
1178 these whitespaces. */
1181 for (p
= s
- 1; p
>= saved_s
&& *p
== ' '; --p
)
1188 /* Parse a BPF register name and return the corresponding register
1189 number. Return NULL in case of parse error, or a pointer to the
1190 first character in S that is not part of the register name. */
1193 parse_bpf_register (char *s
, char rw
, uint8_t *regno
)
1195 if (asm_dialect
== DIALECT_NORMAL
)
1202 if (*s
== 'f' && *(s
+ 1) == 'p')
1216 if (*(s
+ 1) == '0')
1227 else if (*s
>= '0' && *s
<= '9')
1236 /* Collect a parse error message. */
1238 static int partial_match_length
= 0;
1239 static char *errmsg
= NULL
;
1242 parse_error (int length
, const char *fmt
, ...)
1244 if (length
> partial_match_length
)
1249 va_start (args
, fmt
);
1250 errmsg
= xvasprintf (fmt
, args
);
1252 partial_match_length
= length
;
1256 /* Assemble a machine instruction in STR and emit the frags/bytes it
1260 md_assemble (char *str ATTRIBUTE_UNUSED
)
1262 /* There are two different syntaxes that can be used to write BPF
1263 instructions. One is very conventional and like any other
1264 assembly language where each instruction is conformed by an
1265 instruction mnemonic followed by its operands. This is what we
1266 call the "normal" syntax. The other syntax tries to look like C
1267 statements. We have to support both syntaxes in this assembler.
1269 One of the many nuisances introduced by this eccentricity is that
1270 in the pseudo-c syntax it is not possible to hash the opcodes
1271 table by instruction mnemonic, because there is none. So we have
1272 no other choice than to try to parse all instruction opcodes
1273 until one matches. This is slow.
1275 Another problem is that emitting detailed diagnostics becomes
1276 tricky, since the lack of mnemonic means it is not clear what
1277 instruction was intended by the user, and we cannot emit
1278 diagnostics for every attempted template. So if an instruction
1279 is not parsed, we report the diagnostic corresponding to the
1280 partially parsed instruction that was matched further. */
1282 unsigned int idx
= 0;
1283 struct bpf_insn insn
;
1284 const struct bpf_opcode
*opcode
;
1286 /* Initialize the global diagnostic variables. See the parse_error
1288 partial_match_length
= 0;
1291 #define PARSE_ERROR(...) parse_error (s - str, __VA_ARGS__)
1293 while ((opcode
= bpf_get_opcode (idx
++)) != NULL
)
1297 const char *template
1298 = (asm_dialect
== DIALECT_PSEUDOC
? opcode
->pseudoc
: opcode
->normal
);
1300 /* Do not try to match opcodes with a higher version than the
1301 selected ISA spec. */
1302 if (opcode
->version
> isa_spec
)
1305 memset (&insn
, 0, sizeof (struct bpf_insn
));
1307 for (s
= str
, p
= template; *p
!= '\0';)
1311 /* Expect zero or more spaces. */
1312 while (*s
!= '\0' && (*s
== ' ' || *s
== '\t'))
1318 if (*(p
+ 1) == '%')
1322 PARSE_ERROR ("expected '%%'");
1328 else if (*(p
+ 1) == 'w')
1330 /* Expect zero or more spaces. */
1331 while (*s
!= '\0' && (*s
== ' ' || *s
== '\t'))
1335 else if (*(p
+ 1) == 'W')
1337 /* Expect one or more spaces. */
1338 if (*s
!= ' ' && *s
!= '\t')
1340 PARSE_ERROR ("expected white space, got '%s'",
1344 while (*s
!= '\0' && (*s
== ' ' || *s
== '\t'))
1348 else if (strncmp (p
, "%dr", 3) == 0)
1351 char *news
= parse_bpf_register (s
, 'r', ®no
);
1353 if (news
== NULL
|| (insn
.has_dst
&& regno
!= insn
.dst
))
1356 PARSE_ERROR ("expected register r%d, got r%d",
1359 PARSE_ERROR ("expected register name, got '%s'", s
);
1367 else if (strncmp (p
, "%sr", 3) == 0)
1370 char *news
= parse_bpf_register (s
, 'r', ®no
);
1372 if (news
== NULL
|| (insn
.has_src
&& regno
!= insn
.src
))
1375 PARSE_ERROR ("expected register r%d, got r%d",
1378 PARSE_ERROR ("expected register name, got '%s'", s
);
1386 else if (strncmp (p
, "%dw", 3) == 0)
1389 char *news
= parse_bpf_register (s
, 'w', ®no
);
1391 if (news
== NULL
|| (insn
.has_dst
&& regno
!= insn
.dst
))
1394 PARSE_ERROR ("expected register r%d, got r%d",
1397 PARSE_ERROR ("expected register name, got '%s'", s
);
1405 else if (strncmp (p
, "%sw", 3) == 0)
1408 char *news
= parse_bpf_register (s
, 'w', ®no
);
1410 if (news
== NULL
|| (insn
.has_src
&& regno
!= insn
.src
))
1413 PARSE_ERROR ("expected register r%d, got r%d",
1416 PARSE_ERROR ("expected register name, got '%s'", s
);
1424 else if (strncmp (p
, "%i32", 4) == 0
1425 || strncmp (p
, "%I32", 4) == 0)
1429 while (*s
== ' ' || *s
== '\t')
1431 if (*s
!= '+' && *s
!= '-')
1433 PARSE_ERROR ("expected `+' or `-', got `%c'", *s
);
1438 s
= parse_expression (s
, &insn
.imm32
);
1441 PARSE_ERROR ("expected signed 32-bit immediate");
1447 else if (strncmp (p
, "%o16", 4) == 0)
1449 while (*s
== ' ' || *s
== '\t')
1451 if (*s
!= '+' && *s
!= '-')
1453 PARSE_ERROR ("expected `+' or `-', got `%c'", *s
);
1457 s
= parse_expression (s
, &insn
.offset16
);
1460 PARSE_ERROR ("expected signed 16-bit offset");
1463 insn
.has_offset16
= 1;
1466 else if (strncmp (p
, "%d16", 4) == 0)
1468 s
= parse_expression (s
, &insn
.disp16
);
1471 PARSE_ERROR ("expected signed 16-bit displacement");
1474 insn
.has_disp16
= 1;
1475 insn
.is_relaxable
= 1;
1478 else if (strncmp (p
, "%d32", 4) == 0)
1480 s
= parse_expression (s
, &insn
.disp32
);
1483 PARSE_ERROR ("expected signed 32-bit displacement");
1486 insn
.has_disp32
= 1;
1489 else if (strncmp (p
, "%i64", 4) == 0)
1491 s
= parse_expression (s
, &insn
.imm64
);
1494 PARSE_ERROR ("expected signed 64-bit immediate");
1502 as_fatal (_("invalid %%-tag in BPF opcode '%s'\n"), template);
1506 /* Match a literal character. */
1510 PARSE_ERROR ("expected '%c'", *p
);
1513 /* This is to workaround a bug in as_bad. */
1520 PARSE_ERROR ("expected '%c', got '%s'", *p
, tmp
);
1523 PARSE_ERROR ("expected '%c', got '%c'", *p
, *s
);
1533 /* Allow white spaces at the end of the line. */
1534 while (*s
!= '\0' && (*s
== ' ' || *s
== '\t'))
1537 /* We parsed an instruction successfully. */
1539 PARSE_ERROR ("extra junk at end of line");
1545 as_bad (_("unrecognized instruction `%s'"), str
);
1548 as_bad ("%s", errmsg
);
1554 insn
.id
= opcode
->id
;
1555 insn
.opcode
= opcode
->opcode
;
1559 /* Generate the frags and fixups for the parsed instruction. */
1560 if (do_relax
&& insn
.is_relaxable
)
1562 expressionS
*relaxable_exp
= NULL
;
1564 if (insn
.has_disp16
)
1565 relaxable_exp
= &insn
.disp16
;
1569 add_relaxed_insn (&insn
, relaxable_exp
);
1572 add_fixed_insn (&insn
);
1574 /* Emit DWARF2 debugging information. */
1575 dwarf2_emit_insn (insn
.size
);
1578 /* Parse an operand that is machine-specific. */
1581 md_operand (expressionS
*expressionP
)
1583 /* If this hook is invoked it means GAS failed to parse a generic
1584 expression. We should inhibit the as_bad in expr.c, so we can fail
1585 while parsing instruction alternatives. To do that, we change the
1586 expression to not have an O_absent. But then we also need to set
1587 exp_parse_failed to parse_expression above does the right thing. */
1588 ++input_line_pointer
;
1589 expressionP
->X_op
= O_constant
;
1590 expressionP
->X_add_number
= 0;
1591 exp_parse_failed
= 1;
1595 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1601 /* Turn a string in input_line_pointer into a floating point constant
1602 of type TYPE, and store the appropriate bytes in *LITP. The number
1603 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1604 returned, or NULL on OK. */
1607 md_atof (int type
, char *litP
, int *sizeP
)
1609 return ieee_md_atof (type
, litP
, sizeP
, false);
1613 /* Determine whether the equal sign in the given string corresponds to
1614 a BPF instruction, i.e. when it is not to be considered a symbol
1618 bpf_tc_equal_in_insn (int c ATTRIBUTE_UNUSED
, char *str ATTRIBUTE_UNUSED
)
1622 /* Only pseudo-c instructions can have equal signs, and of these,
1623 all that could be confused with a symbol assignment all start
1624 with a register name. */
1625 if (asm_dialect
== DIALECT_PSEUDOC
)
1627 char *w
= parse_bpf_register (str
, 'w', ®no
);
1628 char *r
= parse_bpf_register (str
, 'r', ®no
);
1630 if ((w
!= NULL
&& *w
== '\0')
1631 || (r
!= NULL
&& *r
== '\0'))