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