+2023-07-30 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * readelf.c (get_machine_flags): Recognize and pretty print BPF
+ machine flags.
+
2023-07-24 Johannes Schauer Marin Rodrigues <josch@debian.org>
* doc/binutils.texi (objcopy): Document change in behaviour of
#include "elf/xtensa.h"
#include "elf/z80.h"
#include "elf/loongarch.h"
+#include "elf/bpf.h"
#include "getopt.h"
#include "libiberty.h"
strcat (buf, ", no delay");
break;
+ case EM_BPF:
+ sprintf (buf + strlen (buf), ", CPU Version: %u",
+ e_flags & EF_BPF_CPUVER);
+ break;
+
case EM_SPARCV9:
if (e_flags & EF_SPARC_32PLUS)
strcat (buf, ", v8+");
+2023-07-30 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * config/tc-bpf.h (elf_tc_final_processing): Define.
+ * config/tc-bpf.c (bpf_elf_final_processing): New function.
+
2023-07-30 Jose E. Marchesi <jose.marchesi@oracle.com>
* config/tc-bpf.c (signed_overflow): Copy function from
return 0;
}
+
+/* Some special processing for a BPF ELF file. */
+
+void
+bpf_elf_final_processing (void)
+{
+ /* Annotate the BPF ISA version in the ELF flag bits. */
+ elf_elfheader (stdoutput)->e_flags |= (isa_spec & EF_BPF_CPUVER);
+}
#define TC_EQUAL_IN_INSN(c, s) bpf_tc_equal_in_insn ((c), (s))
extern bool bpf_tc_equal_in_insn (int, char *);
+
+#define elf_tc_final_processing bpf_elf_final_processing
+extern void bpf_elf_final_processing (void);
emit_expr_with_reloc (exp, nbytes, "disp");
sparc_no_align_cons = 0;
}
+
+2023-07-30 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * elf/bpf.h (EF_BPF_CPUVER): Define.
+ * opcode/bpf.h (BPF_XBPF): Change from 0xf to 0xff so it fits in
+ EF_BPF_CPUVER.
+
2023-07-24 Jose E. Marchesi <jose.marchesi@oracle.com>
* opcode/bpf.h (BPF_IMM32_BSWAP16): Define.
RELOC_NUMBER (R_BPF_GNU_64_16, 256)
END_RELOC_NUMBERS (R_BPF_max)
+/* Processor specific flags for the ELF header e_flags field. */
+
+/* Version of the BPF ISA used in the file. */
+#define EF_BPF_CPUVER 0x0000000f
+
#endif /* _ELF_BPF_H */
#define BPF_V2 0x2
#define BPF_V3 0x3
#define BPF_V4 0x4
-#define BPF_XBPF 0xff
+#define BPF_XBPF 0xf
/* Masks for the several instruction fields in a BPF instruction.
These assume big-endian BPF instructions. */
+2023-07-30 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * bpf-dis.c: Initialize asm_bpf_version to -1.
+ (print_insn_bpf): Set BPF ISA version from the cpu version ELF
+ header flags if no explicit version set in the command line.
+ * disassemble.c (disassemble_init_for_target): Remove unused code.
+
2023-07-26 Jose E. Marchesi <jose.marchesi@oracle.com>
* bpf-opc.c (bpf_opcodes): Fix BPF_INSN_NEGR to not use a src
#include "libiberty.h"
#include "opintl.h"
#include "opcode/bpf.h"
+#include "elf-bfd.h"
+#include "elf/bpf.h"
#include <string.h>
#include <inttypes.h>
/* Global configuration for the disassembler. */
static enum bpf_dialect asm_dialect = BPF_DIALECT_NORMAL;
-static int asm_bpf_version = BPF_V4;
+static int asm_bpf_version = -1;
static int asm_obase = 10;
/* Print BPF specific command-line options. */
info->disassembler_options = NULL;
}
+ /* Determine what version of the BPF ISA to use when disassembling.
+ If the user didn't explicitly specify an ISA version, then derive
+ it from the CPU Version flag in the ELF header. A CPU version of
+ 0 in the header means "latest version". */
+ if (asm_bpf_version == -1)
+ {
+ struct bfd *abfd = info->section->owner;
+ Elf_Internal_Ehdr *header = elf_elfheader (abfd);
+ int cpu_version = header->e_flags & EF_BPF_CPUVER;
+
+ switch (cpu_version)
+ {
+ case 0: asm_bpf_version = BPF_V4; break;
+ case 1: asm_bpf_version = BPF_V1; break;
+ case 2: asm_bpf_version = BPF_V2; break;
+ case 3: asm_bpf_version = BPF_V3; break;
+ case 4: asm_bpf_version = BPF_V4; break;
+ case 0xf: asm_bpf_version = BPF_XBPF; break;
+ default:
+ /* xgettext:c-format */
+ opcodes_error_handler (_("unknown BPF CPU version %u\n"),
+ cpu_version);
+ break;
+ }
+ }
+
/* Print eight bytes per line. */
info->bytes_per_chunk = 1;
info->bytes_per_line = 8;
#endif
#ifdef ARCH_bpf
case bfd_arch_bpf:
- /* XXX option for dialect */
info->created_styled_output = true;
-#if 0
- info->endian_code = BFD_ENDIAN_LITTLE;
- if (!info->private_data)
- {
- info->private_data = cgen_bitset_create (ISA_MAX);
- if (info->endian == BFD_ENDIAN_BIG)
- {
- cgen_bitset_set (info->private_data, ISA_EBPFBE);
- if (info->mach == bfd_mach_xbpf)
- cgen_bitset_set (info->private_data, ISA_XBPFBE);
- }
- else
- {
- cgen_bitset_set (info->private_data, ISA_EBPFLE);
- if (info->mach == bfd_mach_xbpf)
- cgen_bitset_set (info->private_data, ISA_XBPFLE);
- }
- }
-#endif
break;
#endif
#ifdef ARCH_pru