Commit graph

1741 commits

Author SHA1 Message Date
Ryan Kurtz
3abf7f765e GP-0: Updating Swift documentation links 2025-08-21 06:42:41 -04:00
Ryan Kurtz
729642cbf6 Merge remote-tracking branch 'origin/GP-5912_emteere_SuperH_GBR' into
patch (Closes #4387)
2025-08-19 05:57:47 -04:00
ghidra1
f7138da6f7 GP-5918 Corrected ELF Relocation regression for MIPS 64-bit introduced
with GP-5826 in Ghidra 11.4.1
2025-08-11 13:00:58 -04:00
emteere
28313c6574 GP-5912 Adding SH2 GBR register to the preserved by call list 2025-08-07 12:44:05 +00:00
ghidorahrex
4abf6d55ad GP-5766: Fixed instruction AVX512 disassembly errors 2025-07-29 08:56:43 -04:00
Nicolas Iooss
24d19f6e8c Add eBPF ISA v4 instructions
In 2023, the eBPF instruction set was modified to add several
instructions related to signed operations (load with sign-extension,
signed division, etc.), a 32-bit jump instruction and some byte-swap
instructions. This became version 4 of eBPF ISA.

Here are some references about this change:

- https://pchaigno.github.io/bpf/2021/10/20/ebpf-instruction-sets.html
  (a blog post about eBPF instruction set extensions)
- https://lore.kernel.org/bpf/4bfe98be-5333-1c7e-2f6d-42486c8ec039@meta.com/
  (documentation sent to Linux Kernel mailing list)
- https://www.rfc-editor.org/rfc/rfc9669.html#name-sign-extension-load-operati
  (IETF's BPF Instruction Set Architecture standard defined the new
  instructions)
- https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/bpf/core.c?h=v6.14#n1859
  (implementation of signed division and remainder in Linux kernel.
  This shows that 32-bit signed DIV and signed MOD are zero-extending
  the result in DST)
- https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/bpf/core.c?h=v6.14#n2135
  (implementation of signed memory load in Linux kernel)
- https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1f9a1ea821ff25353a0e80d971e7958cd55b47a3
  (commit which added signed memory load instructions in Linux kernel)

This can be tested with a recent enough version of clang and LLVM (this
works with clang 19.1.4 on Alpine 3.21).
For example for signed memory load instructions:

    signed int sext_8bit(signed char x) {
        return x;
    }

produces:

    $ clang -O0 -target bpf -mcpu=v4 -c test.c -o test.ebpf
    $ llvm-objdump -rd test.ebpf
    ...
    0000000000000000 <sext_8bit>:
           0:  73 1a ff ff 00 00 00 00  *(u8 *)(r10 - 0x1) = r1
           1:  91 a1 ff ff 00 00 00 00  r1 = *(s8 *)(r10 - 0x1)
           2:  bc 10 00 00 00 00 00 00  w0 = w1
           3:  95 00 00 00 00 00 00 00  exit

(The second instruction is a signed memory load)

Instruction MOVS (Sign extend register MOV) uses offset to encode the
conversion (whether the source register is to be considered as signed
8-bit, 16-bit or 32-bit integer). The mnemonic for these instructions is
quite unclear:

- They are all named MOVS in the proposal
  https://lore.kernel.org/bpf/4bfe98be-5333-1c7e-2f6d-42486c8ec039@meta.com/
- LLVM and Linux disassemblers only display pseudo-code (`r0 = (s8)r1`)
- RFC 9669 (https://datatracker.ietf.org/doc/rfc9669/) uses MOVSX for
  all instructions.
- GCC uses MOVS for all instructions:
  https://github.com/gcc-mirror/gcc/blob/releases/gcc-14.1.0/gcc/config/bpf/bpf.md?plain=1#L326-L365

To make the disassembled code clearer, decode such instructions with a
size suffix: MOVSB, MOVSH, MOVSW.

The decoding of instructions 32-bit JA, BSWAP16, BSWAP32 and BSWAP64 is
straightforward.
2025-07-29 12:45:06 +00:00
Ryan Kurtz
0d8a39a07a Merge remote-tracking branch
'origin/GP-5857_ghidorahrex_PR-7979_niooss-ledger_ebpf-fix-load-zext'
into patch (Closes #7979)
2025-07-29 08:24:03 -04:00
Ryan Kurtz
b4239911c9 Merge remote-tracking branch
'origin/GP-5858_ghidorahrex_PR-7929_niooss-ledger_fix-ebpf-call-operand'
into patch (Closes #7929)
2025-07-29 08:21:27 -04:00
Ryan Kurtz
179263a592 Merge remote-tracking branch
'origin/GP-5593_ghidorahrex_PR-7985_niooss-ledger_ebpf-fix-semantic-byte-swap-instructions'
into patch (Closes #7985)
2025-07-29 08:19:37 -04:00
Ryan Kurtz
28b46c5c93 Merge remote-tracking branch
'origin/GP-5336_ghidorahrex_PR-7065_philpem_6805_hcs08_xidx_fix' into
patch (Closes #7065, Closes #7064)
2025-07-29 08:16:11 -04:00
Dan
39c0a83c0c GP-5877: Fix Patch Instruction action in some Harvard architectures. 2025-07-28 15:48:40 +00:00
Ryan Kurtz
3cfa867ac3 Merge remote-tracking branch 'origin/GP-5843_emteere_MIPS64FunctionStarts' into patch 2025-07-21 13:14:06 -04:00
Ryan Kurtz
edf42d82d9 Merge remote-tracking branch 'origin/GP-5846_ghidra1_PPC64_ELFRelocations' into patch 2025-07-18 15:17:45 -04:00
ghidra1
006bd8d423 GP-5846 Corrected ELF PowerPC 64-bit relocation processing bugs
affecting ELFv2 use and R_PPC64_JMP_SLOT relocation
2025-07-18 12:00:34 -04:00
Ryan Kurtz
e69ce4104b Merge remote-tracking branch 'origin/GP-5804_emteere_FixDefaultSymbolicPropRecordState' into patch 2025-07-18 06:15:13 -04:00
emteere
3468c4b502 GP-5843 Added MIPS64 function start patterns 2025-07-17 22:42:00 +00:00
ghidra1
130b365e7c GP-5827 Corrected ELF MIPS 64-bit relocation processing error 2025-07-15 18:27:41 -04:00
Ryan Kurtz
7d76ab5e9b Merge remote-tracking branch
'origin/GP-4989_ghintern_arm_fix_aapcs--SQUASHED' into patch
(Closes #6958)
2025-07-14 16:05:48 -04:00
ghintern
3e11715778 GP-4989: Fix ARM AAPCS cspec, add soft float calling convention 2025-07-14 18:38:17 +00:00
caheckman
de842dbd32 GP-5816 Fix return recovery for AARCH64 and ARM 2025-07-09 21:19:07 +00:00
Nicolas Iooss
e2de11d5b2
Fix eBPF zero-extend load instructions
When a loading less than 8 bytes to a register, the value is supposed to
be zero-extended. This is what the eBPF execution engine in the Linux
kernel does, in
https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/bpf/core.c?h=v6.14#n2113
This is also what is specified in RFC 9669 which standardised BPF ISA:
https://www.rfc-editor.org/rfc/rfc9669.html#name-regular-load-and-store-oper

Add the missing `zext` calls in the semantic section of instructions
LDXW, LDXH and LDXB. While at it, add them to other load instructions.

For information, the issue can be seen when analyzing this C program:

    unsigned int div_by_1000(unsigned int value) {
        return value / 1000;
    }

Compiling it with clang gives:

    $ clang -O0 -target bpf -c division.c -o division.ebpf
    $ bpf-objdump -rd division.ebpf
    division.ebpf:     file format elf64-bpfle

    Disassembly of section .text:

    0000000000000000 <div_by_1000>:
       0:    63 1a fc ff 00 00 00 00     stxw [%fp+-4],%r1
       8:    61 a0 fc ff 00 00 00 00     ldxw %r0,[%fp+-4]
      10:    37 00 00 00 e8 03 00 00     div %r0,0x3e8
      18:    95 00 00 00 00 00 00 00     exit

Ghidra decompiles this program as:

    ulonglong div_by_1000(uint param_1)
    {
      undefined4 in_stack_00000000;
      return CONCAT44(in_stack_00000000,param_1) / 1000;
    }

This `in_stack_00000000` comes from the way the parameter is loaded from
the stack. The listing shows the following disassembly and p-code
operations:

    ram:00100008 61 a0 fc ff 00       LDXW       R0,[R10 + -0x4=>Stack[-0x4]]
                 00 00 00
                            $U3e00:8 = INT_ADD R10, -4:8
                            R0 = LOAD ram($U3e00:8)

This shows the value is indeed loaded from 8 bytes at `$U3e00:8` instead
of 4.

After adding `zext` calls, Ghidra decodes the same instruction as:

    ram:00100008 61 a0 fc ff 00       LDXW       R0,[R10 + -0x4=>local_4]
                 00 00 00
                            $U4100:8 = INT_ADD R10, -4:8
                            $U4180:4 = LOAD ram($U4100:8)
                            R0 = INT_ZEXT $U4180:4

This only loads 4 bytes from the stack, as expected.
Moreover the decompilation view is now correct:

    ulonglong div_by_1000(uint param_1)
    {
      return (ulonglong)param_1 / 1000;
    }
2025-07-07 16:28:00 +02:00
Nicolas Iooss
c1d96a2140
Fix eBPF CALL operand decoding
The operand of the CALL instruction missed multiplying the immediate
value by 8. Without this, calls are not decoded correctly.

Such a CALL instruction can be emitted when compiling this simple
`single_call.c` program:

    static int one(void) {
        return 1;
    }

    int call_one(void) {
        return one();
    }

with:

    clang -O0 -target bpf -c single_call.c -o single_call.ebpf

Disassembling with LLVM shows:

    $ llvm-objdump -d single_call.ebpf
    single_call.ebpf:	file format elf64-bpf

    Disassembly of section .text:

    0000000000000000 <call_one>:
           0:	85 10 00 00 01 00 00 00	call 1
           1:	95 00 00 00 00 00 00 00	exit

    0000000000000010 <one>:
           2:	b7 00 00 00 01 00 00 00	r0 = 1
           3:	95 00 00 00 00 00 00 00	exit

The first instruction ("call 1") calls the function located at 0x10 (at
index `2:` in the listing). Ghidra considered the call to target
address 9 instead (as `inst_next = 8` and `imm = 1`). Fix this by
multiplying `imm` by 8 when encountering a `disp32` operand (which is
only used by instruction `CALL`).

Adjust ELF Relocation R_BPF_64_32 to take into account for this
multiplication by 8. Actually it is documented to compute (S + A) / 8 - 1
so the division by 8 was missing.
2025-07-07 16:26:31 +02:00
Nicolas Iooss
adb0eac98a
Add support for big endian eBPF programs 2025-07-07 16:13:37 +02:00
Nicolas Iooss
52cb7a36e6
Fix the semantics of eBPF byte swap instructions
eBPF byte swap operations (BE16, BE32, BE64, LE16, LE32, LE64) have
semantics that depend on the endianness of the host processor executing
the eBPF program. For example, on a Little-Endian CPU, BE16 swaps the 2
lowest significant bytes of the given destination register.

The semantic section of LE16 contains:

    { dst=((dst) >> 8) | ((dst) << 8); }

This contains several issues:

- It assumes the instruction always swaps the bytes. This should only
  happen on Big-Endian host CPU.
- If `dst` does not contain a 16-bit value (meaning `dst >> 16 != 0`),
  the computed value is wrong. The value should be properly masked. For
  example the Linux kernel defines in
  https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/swab.h?h=v6.14#L14

    #define ___constant_swab16(x) ((__u16)(             \
            (((__u16)(x) & (__u16)0x00ffU) << 8) |      \
            (((__u16)(x) & (__u16)0xff00U) >> 8)))

As the endianness of the CPU has to be the same as the eBPF program
(defined in the ELF header), introduce a macro `ENDIAN` and use it to
implement the byte swap operations.
2025-07-07 16:13:36 +02:00
emteere
4723729d80 GP-5804 Set SymbolicPropogator to record register begin/end state in
basic constructor. Better document recordBeginEndState flag.
2025-07-03 17:49:53 +00:00
Ryan Kurtz
e08d05a376 Merge remote-tracking branch 'origin/GP-5622_ghidorahrex_aarch64_neon_impl--SQUASHED' into Ghidra_11.4 2025-06-11 11:51:05 -04:00
vporok01
3d54c90cd6 Fix RISC-V minu and max instructions' definitions (Closes #8215) 2025-06-11 11:47:49 -04:00
ghidorahrex
fe4244cbc9 GP-5622: Implemented pcode for several AARCH64 Neon instructions 2025-06-11 07:56:09 -04:00
ghidorahrex
b0750c2783 GP-5725: Corrected operands for several AVX512 instructions 2025-06-10 09:21:39 -04:00
ghidra1
92f2588895 GP-0 Corrected build.gradle for PA-RISC to allow pcode test execution 2025-06-09 18:53:22 -04:00
ghidra1
8c441250f5 GP-5742 Cleanup preferred CommentType enum use. Changed SARIF data component comment JSON serialization from int to String. 2025-06-06 17:58:07 -04:00
Ryan Kurtz
2b7a6c6d3b Merge remote-tracking branch 'origin/GP-5659_ghidorahrex_z80_sub_fix'
into Ghidra_11.4 (Closes #8144)
2025-05-30 13:51:53 -04:00
ghidra1
ce6770132b Merge remote-tracking branch
'origin/GP-5605_ghidra1_ELF_SH4_PartialInplace' into Ghidra_11.4
(Closes #8021)
2025-05-21 16:14:07 -04:00
ghidra1
0b2739a8fe Merge remote-tracking branch
'origin/GP-5704_ghidra1_x86_16_LanguageUpgradeIssues' into Ghidra_11.4
(Closes #8140)
2025-05-19 16:05:34 -04:00
ghidra1
271ec694ad GP-5704 Corrected language upgrade issue affecting x86-16 Protected and
SMM mode variants.
2025-05-19 16:01:16 -04:00
ghidorahrex
d6815ae407 GP-5665: Additional cvt reg32 dest fixes 2025-05-15 16:52:12 +00:00
John Millikin
6ab48b885b x86: Fix missing zero-extension in CVTTSD2SI 2025-05-14 19:19:32 +09:00
ghidorahrex
eb6fbb17ef GP-5659: Fixed z80 sub instruction semantics 2025-05-13 14:24:39 +00:00
ghidra1
a9d3b9e236 Merge remote-tracking branch 'origin/GP-4512_emteere_ConstantAnalysisSpeedup--SQUASHED' 2025-05-08 17:36:25 -04:00
emteere
c396867209 GP-4512 Constant propagation and stack analysis performance changes 2025-05-08 17:35:25 -04:00
ghidra1
e10c42ab44 Merge remote-tracking branch 'origin/patch' 2025-05-08 17:20:05 -04:00
ghidra1
cd6d45c64f GP-0 Corrected NPE for eBPF ELF import. (Closes #8034) 2025-05-08 17:18:19 -04:00
Ryan Kurtz
8320d12461 Merge remote-tracking branch
'origin/GP-4923_ghintern_arm_apcs--SQUASHED' (Closes #7434)
2025-05-08 12:36:16 -04:00
Ryan Kurtz
32abab0a3d Merge remote-tracking branch
'origin/GP-5192_ghintern_aarch64_aapcs_fixes--SQUASHED' (Closes #8016)
2025-05-08 12:34:30 -04:00
Ryan Kurtz
c7f9586d97 Merge remote-tracking branch
'origin/GP-5638_ghidracadabra_PR-6602_Sleigh-InSPECtor_x86_push_fs_gs_size'
(Closes #6602)
2025-05-08 12:28:25 -04:00
Ryan Kurtz
541818c274 Merge remote-tracking branch 'origin/patch' 2025-05-08 12:26:49 -04:00
Ryan Kurtz
d641f9de69 Merge remote-tracking branch
'origin/GP-4731_ghidorahrex_PR-5256_befoulad_armv8-splimit' into patch
(Closes #5256, Closes #5255, Closes #6667)
2025-05-08 12:22:40 -04:00
ghintern
28ca53cb34 GP-4923: cspec, ldefs, opinion file support for ARM apcs abi 2025-05-07 17:41:41 +00:00
ghintern
b0b1db632c GP-5192: Fix aarch64 cspec to match aapcs calling convention 2025-05-07 17:40:54 +00:00
James
a9e193d811 GP-5638 update language verions 2025-05-07 13:51:22 +00:00