Skip to content

Add eBPF instruction CALLX for indirect calls #7972

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion Ghidra/Processors/eBPF/data/languages/eBPF.sinc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ define register offset=0 size=8 [ R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 P

# Instruction encoding: Insop:8, dst_reg:4, src_reg:4, off:16, imm:32 - from lsb to msb
define token instr(64)
llvm_imm_callx_zero=(36, 63)
imm=(32, 63) signed
llvm_reg_callx=(32, 35) # special encoding for callx instruction emitted by LLVM
off=(16, 31) signed
src=(12, 15)
dst=(8, 11)
Expand All @@ -31,7 +33,7 @@ define token immtoken(64)
;

#To operate with registers
attach variables [ src dst ] [ R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 _ _ _ _ _ ];
attach variables [ src dst llvm_reg_callx ] [ R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 _ _ _ _ _ ];

#Arithmetic instructions
#BPF_ALU64
Expand Down Expand Up @@ -356,4 +358,20 @@ disp32: reloc is imm [ reloc = inst_next + imm; ] { export *:4 reloc; }
call disp32;
}

# GCC encoding and LLVM 19.1+ encoding
:CALLX dst is op_alu_jmp_opcode=0x8 & op_alu_jmp_source=1 & op_insn_class=0x5 & src=0 & imm=0 & dst {
call [dst];
}

# LLVM encoding used until LLVM 19.1
# Introduced in https://github.com/llvm/llvm-project/commit/9a67245d881f4cf89fd8f897ae2cd0bccec49496
# Modified in https://github.com/llvm/llvm-project/commit/c43ad6c0fddac0bbed5e881801dd2bc2f9eeba2d
:CALLX llvm_reg_callx is op_alu_jmp_opcode=0x8 & op_alu_jmp_source=1 & op_insn_class=0x5 & dst=0 & src=0 & llvm_imm_callx_zero=0 & llvm_reg_callx {
call [llvm_reg_callx];
}
# Both CALLX encodings are matched when both dst and imm are zero
:CALLX R0 is op_alu_jmp_opcode=0x8 & op_alu_jmp_source=1 & op_insn_class=0x5 & dst=0 & src=0 & imm=0 & R0 {
call [R0];
}

:EXIT is op_alu_jmp_opcode=0x9 & op_alu_jmp_source=0 & op_insn_class=0x5 { return [*:8 R10]; }