tc-bpf.c revision 1.1.1.4 1 1.1 christos /* tc-bpf.c -- Assembler for the Linux eBPF.
2 1.1.1.4 christos Copyright (C) 2019-2025 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', ®no)
1365 1.1.1.3 christos || parse_bpf_register ((char *) name, 'w', ®no))
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', ®no);
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', ®no);
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', ®no);
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', ®no);
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', ®no);
1841 1.1.1.3 christos char *r = parse_bpf_register (str, 'r', ®no);
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