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