Skip to content

Commit c5293df

Browse files
authored
Add support for extended call instructions (#63)
* Add support for extended call instructions Signed-off-by: Alan Jowett <[email protected]> * Apply formatting Signed-off-by: Alan Jowett <[email protected]> Signed-off-by: Alan Jowett <[email protected]>
1 parent 99a3e7d commit c5293df

File tree

2 files changed

+74
-3
lines changed

2 files changed

+74
-3
lines changed

src/bpf_assembler.cc

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,21 @@ typedef class _bpf_assembler
281281
inst.opcode = EBPF_OP_EXIT;
282282
} else if (mnemonic == "call") {
283283
inst.opcode = EBPF_OP_CALL;
284-
inst.imm = _decode_imm32(operands[0]);
284+
auto mode = operands[0];
285+
auto target = operands[1];
286+
// Mode determines if this is a helper function, a local call, or a call to a runtime function.
287+
if (mode == "helper") {
288+
inst.imm = _decode_imm32(target);
289+
inst.src = 0;
290+
} else if (mode == "local") {
291+
inst.imm == _decode_jump_target(target);
292+
inst.src = 1;
293+
} else if (mode == "runtime") {
294+
inst.imm = _decode_imm32(target);
295+
inst.src = 2;
296+
} else {
297+
throw std::runtime_error("Invalid call mode");
298+
}
285299
} else {
286300
mnemonic.ends_with("32") ? inst.opcode = EBPF_CLS_JMP32 : inst.opcode |= EBPF_CLS_JMP;
287301
auto iter =
@@ -408,7 +422,7 @@ typedef class _bpf_assembler
408422
{"and", {&_bpf_assembler::_encode_alu, 2}}, {"and32", {&_bpf_assembler::_encode_alu, 2}},
409423
{"arsh", {&_bpf_assembler::_encode_alu, 2}}, {"arsh32", {&_bpf_assembler::_encode_alu, 2}},
410424
{"be16", {&_bpf_assembler::_encode_alu, 1}}, {"be32", {&_bpf_assembler::_encode_alu, 1}},
411-
{"be64", {&_bpf_assembler::_encode_alu, 1}}, {"call", {&_bpf_assembler::_encode_jmp, 1}},
425+
{"be64", {&_bpf_assembler::_encode_alu, 1}}, {"call", {&_bpf_assembler::_encode_jmp, 2}},
412426
{"div", {&_bpf_assembler::_encode_alu, 2}}, {"div32", {&_bpf_assembler::_encode_alu, 2}},
413427
{"exit", {&_bpf_assembler::_encode_jmp, 0}}, {"ja", {&_bpf_assembler::_encode_jmp, 1}},
414428
{"jeq", {&_bpf_assembler::_encode_jmp, 3}}, {"jeq32", {&_bpf_assembler::_encode_jmp, 3}},
@@ -506,6 +520,14 @@ typedef class _bpf_assembler
506520

507521
bpf_encode_t encode = nullptr;
508522
size_t operand_count = 0;
523+
524+
// If this is a call instruction and it doesn't specify a mode, add the default mode (helper).
525+
if (mnemonic == "call") {
526+
if (operands.size() == 1) {
527+
operands.insert(operands.begin(), "helper");
528+
}
529+
}
530+
509531
if (mnemonic == "lock") {
510532
// Find the handler for this atomic operation.
511533
if (operands.size() == 0) {
@@ -557,7 +579,11 @@ typedef class _bpf_assembler
557579
if (iter == _labels.end()) {
558580
throw std::runtime_error(std::string("Invalid label: ") + _jump_instructions[i].value());
559581
}
560-
output[i].offset = static_cast<uint16_t>(iter->second - i - 1);
582+
if (output[i].opcode == EBPF_OP_CALL) {
583+
output[i].imm = static_cast<uint16_t>(iter->second - i - 1);
584+
} else {
585+
output[i].offset = static_cast<uint16_t>(iter->second - i - 1);
586+
}
561587
}
562588
return output;
563589
}

tests/call_local.data

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Copyright (c) Microsoft Corporation
2+
# SPDX-License-Identifier: MIT
3+
-- asm
4+
# r1-r5 are passed to the callee
5+
mov r0, 0
6+
mov r1, 1
7+
mov r2, 2
8+
mov r3, 3
9+
mov r4, 4
10+
mov r5, 5
11+
# r6-r9 are preserved
12+
mov r6, 6
13+
mov r7, 7
14+
mov r8, 8
15+
mov r9, 9
16+
call local func1
17+
# r0 contains the return value
18+
# r0 should contain 1 + 2 + 3 + 4 + 5
19+
jne r0, 15, failed
20+
# r6 through r9 should be preserved
21+
jne r6, 6, failed
22+
jne r7, 7, failed
23+
jne r8, 8, failed
24+
jne r9, 9, failed
25+
# Success
26+
mov r0, 1
27+
exit
28+
failed:
29+
mov r0, -1
30+
exit
31+
# Function sets r0 = r1 + r2 + r3 + r4 + r5
32+
func1:
33+
mov r0, 0
34+
add r0, r1
35+
add r0, r2
36+
add r0, r3
37+
add r0, r4
38+
add r0, r5
39+
mov r6, 0
40+
mov r7, 0
41+
mov r8, 0
42+
mov r9, 0
43+
exit
44+
-- result
45+
0x1

0 commit comments

Comments
 (0)