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