Skip to content
Draft
Show file tree
Hide file tree
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
15 changes: 8 additions & 7 deletions conformance/src/vm_interp.zig
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,17 @@ fn executeVmTest(
.mask_out_rent_epoch_in_vm_serialization,
slot,
);
var parameter_bytes, var regions, const accounts_metadata = try serialize.serializeParameters(
var serialized = try serialize.serializeParameters(
allocator,
&ic,
!direct_mapping,
mask_out_rent_epoch_in_vm_serialization,
);
defer {
parameter_bytes.deinit(allocator);
regions.deinit(allocator);
serialized.memory.deinit(allocator);
serialized.regions.deinit(allocator);
}
tc.serialized_accounts = accounts_metadata;
tc.serialized_accounts = serialized.account_metas;

const rodata = try allocator.dupe(u8, vm_context.rodata.getSlice());
defer allocator.free(rodata);
Expand Down Expand Up @@ -220,7 +220,7 @@ fn executeVmTest(
),
memory.Region.init(.mutable, heap, memory.HEAP_START),
});
try input_memory_regions.appendSlice(allocator, regions.items);
try input_memory_regions.appendSlice(allocator, serialized.regions.items);

const map = try memory.MemoryMap.init(
allocator,
Expand All @@ -236,18 +236,19 @@ fn executeVmTest(
map,
&syscall_registry,
STACK_SIZE,
0,
&tc,
);
defer vm.deinit();

// r1, r10, pc are initialized by Vm.init, modifying them will most like break execution.
// r1, r2, r10, pc are initialized by Vm.init, modifying them will most like break execution.
// In vm_syscalls we allow override them (especially r1) because that simulates the fact
// that a program partially executed before reaching the syscall.
// Here we want to test what happens when the program starts from the beginning.
// [agave] https://github.com/firedancer-io/solfuzz-agave/blob/0b8a7971055d822df3f602c287c368400a784c15/src/vm_interp.rs#L357-L362
vm.registers.set(.r0, vm_context.r0);
// vm.registers.set(.r1, vm_context.r1);
vm.registers.set(.r2, vm_context.r2);
// vm.registers.set(.r2, vm_context.r2);
vm.registers.set(.r3, vm_context.r3);
vm.registers.set(.r4, vm_context.r4);
vm.registers.set(.r5, vm_context.r5);
Expand Down
11 changes: 6 additions & 5 deletions conformance/src/vm_syscall.zig
Original file line number Diff line number Diff line change
Expand Up @@ -223,17 +223,17 @@ fn executeSyscall(
.mask_out_rent_epoch_in_vm_serialization,
tc.slot,
);
var parameter_bytes, var regions, const accounts_metadata = try serialize.serializeParameters(
var serialized = try serialize.serializeParameters(
allocator,
ic,
!direct_mapping,
mask_out_rent_epoch_in_vm_serialization,
);
defer {
parameter_bytes.deinit(allocator);
regions.deinit(allocator);
serialized.memory.deinit(allocator);
serialized.regions.deinit(allocator);
}
tc.serialized_accounts = accounts_metadata;
tc.serialized_accounts = serialized.account_metas;

if (pb_vm.heap_max > HEAP_MAX) return error.InvalidHeapSize;

Expand All @@ -260,7 +260,7 @@ fn executeSyscall(
),
memory.Region.init(.mutable, heap, memory.HEAP_START),
});
try input_memory_regions.appendSlice(allocator, regions.items);
try input_memory_regions.appendSlice(allocator, serialized.regions.items);

const memory_map = try memory.MemoryMap.init(
allocator,
Expand All @@ -275,6 +275,7 @@ fn executeSyscall(
memory_map,
syscall_registry,
stack.len,
0,
&tc,
);
defer vm.deinit();
Expand Down
Binary file modified data/test-elfs/bss_section_sbpfv0.so
Binary file not shown.
Binary file modified data/test-elfs/data_section_sbpfv0.so
Binary file not shown.
Binary file modified data/test-elfs/direct_mapping.so
Binary file not shown.
9 changes: 3 additions & 6 deletions data/test-elfs/elf.ld
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ SECTIONS
_heap_end = .;
. = ALIGN(8);
} :heap
.dynsym 0xFFFFFFFF00000000 : {
*(.dynsym)
. = ALIGN(8);
} :dynsym
.dynstr : { *(.dynstr) } :other
.strtab : { *(.strtab) } :other
/DISCARD/ : {
*(.comment*)
Expand All @@ -35,14 +30,16 @@ SECTIONS
*(.data*)
*(.rel.dyn*)
*(.dynamic)
*(.dynsym)
*(.dynstr)
}
}

PHDRS
{
text PT_LOAD FLAGS(1);
rodata PT_LOAD FLAGS(4);
stack PT_GNU_STACK FLAGS(6);
stack PT_LOAD FLAGS(6);
heap PT_LOAD FLAGS(6);
dynsym PT_NULL FLAGS(0);
other PT_NULL FLAGS(0);
Expand Down
Binary file modified data/test-elfs/hash_collision_sbpfv0.so
Binary file not shown.
Binary file modified data/test-elfs/poseidon_test.so
Binary file not shown.
Binary file added data/test-elfs/r2_instruction_data_offset.so
Binary file not shown.
10 changes: 10 additions & 0 deletions data/test-elfs/r2_instruction_data_offset.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const set_return_data: *align(1) const fn ([*]const u8, usize) void = @ptrFromInt(0xa226d3eb);

export fn entrypoint(_: [*]u8, instruction_data_addr: [*]const u8) u64 {
const instruction_data_len = @as([*]align(1) const u64, @ptrCast(instruction_data_addr - 8))[0];
const instruction_data = instruction_data_addr[0..instruction_data_len];

set_return_data(instruction_data.ptr, instruction_data.len);

return 0;
}
Binary file modified data/test-elfs/relative_call_sbpfv0.so
Binary file not shown.
Binary file modified data/test-elfs/reloc_64_64.so
Binary file not shown.
Binary file modified data/test-elfs/reloc_64_64_sbpfv0.so
Binary file not shown.
Binary file modified data/test-elfs/reloc_64_relative.so
Binary file not shown.
Binary file modified data/test-elfs/reloc_64_relative_data.so
Binary file not shown.
Binary file modified data/test-elfs/reloc_64_relative_data_sbpfv0.so
Binary file not shown.
Binary file modified data/test-elfs/reloc_64_relative_sbpfv0.so
Binary file not shown.
Binary file modified data/test-elfs/rodata_section.so
Binary file not shown.
Binary file modified data/test-elfs/rodata_section_sbpfv0.so
Binary file not shown.
Binary file modified data/test-elfs/strict_header.so
Binary file not shown.
Binary file modified data/test-elfs/struct_func_pointer.so
Binary file not shown.
Binary file modified data/test-elfs/struct_func_pointer_sbpfv0.so
Binary file not shown.
Binary file modified data/test-elfs/syscall_reloc_64_32_sbpfv0.so
Binary file not shown.
Binary file modified data/test-elfs/syscall_static.so
Binary file not shown.
1 change: 1 addition & 0 deletions src/core/features.zon
Original file line number Diff line number Diff line change
Expand Up @@ -241,4 +241,5 @@
.{ .name = "enable_vote_address_leader_schedule", .pubkey = "5JsG4NWH8Jbrqdd8uL6BNwnyZK3dQSoieRXG5vmofj9y" },
.{ .name = "enshrine_slashing_program", .pubkey = "sProgVaNWkYdP2eTRAy1CPrgb3b9p8yXCASrPEqo6VJ" },
.{ .name = "enable_partitioned_epoch_reward", .pubkey = "9bn2vTJUsUcnpiZWbu2woSKtTGW3ErZC9ERv88SDqQjK" },
.{ .name = "provide_instruction_data_offset_in_vm_r2", .pubkey = "5xXZc66h4UdB6Yq7FzdBxBiRAFMMScMLwHxk2QZDaNZL" },
}
25 changes: 15 additions & 10 deletions src/runtime/program/bpf/execute.zig
Original file line number Diff line number Diff line change
Expand Up @@ -64,24 +64,26 @@ pub fn execute(
.bpf_account_data_direct_mapping,
ic.tc.slot,
);
const provide_instruction_data_offset = ic.tc.feature_set.active(
.provide_instruction_data_offset_in_vm_r2,
ic.tc.slot,
);

// [agave] https://github.com/anza-xyz/agave/blob/32ac530151de63329f9ceb97dd23abfcee28f1d4/programs/bpf_loader/src/lib.rs#L1588
var parameter_bytes, //
var regions, //
const accounts_metadata = try serialize.serializeParameters(
var serialized = try serialize.serializeParameters(
allocator,
ic,
!direct_mapping,
mask_out_rent_epoch_in_vm_serialization,
);
defer {
parameter_bytes.deinit(allocator);
regions.deinit(allocator);
serialized.memory.deinit(allocator);
serialized.regions.deinit(allocator);
}

// [agave] https://github.com/anza-xyz/agave/blob/a11b42a73288ab5985009e21ffd48e79f8ad6c58/programs/bpf_loader/src/lib.rs#L278-L282
const old_accounts = ic.tc.serialized_accounts;
ic.tc.serialized_accounts = accounts_metadata;
ic.tc.serialized_accounts = serialized.account_metas;
defer ic.tc.serialized_accounts = old_accounts;

// [agave] https://github.com/anza-xyz/agave/blob/a2af4430d278fcf694af7a2ea5ff64e8a1f5b05b/programs/bpf_loader/src/lib.rs#L1604-L1617
Expand All @@ -94,8 +96,9 @@ pub fn execute(
allocator,
ic.tc,
&executable,
regions.items,
serialized.regions.items,
&ic.tc.vm_environment.loader,
if (provide_instruction_data_offset) serialized.instruction_data_offset else 0,
) catch |err| {
try ic.tc.log("Failed to create SBPF VM: {s}", .{@errorName(err)});
return InstructionError.ProgramEnvironmentSetupFailure;
Expand Down Expand Up @@ -143,8 +146,8 @@ pub fn execute(
allocator,
ic,
!direct_mapping,
parameter_bytes.items,
accounts_metadata.constSlice(),
serialized.memory.items,
serialized.account_metas.constSlice(),
) catch |err| {
maybe_execute_error = err;
};
Expand All @@ -160,8 +163,9 @@ pub fn initVm(
allocator: std.mem.Allocator,
tc: *TransactionContext,
executable: *const vm.Executable,
regions: []vm.memory.Region,
regions: []const vm.memory.Region,
syscalls: *const Registry(Syscall),
instruction_data_offset: u64,
) !struct {
vm.Vm,
[]u8,
Expand Down Expand Up @@ -217,6 +221,7 @@ pub fn initVm(
memory_map,
syscalls,
stack.len,
instruction_data_offset,
tc,
);

Expand Down
39 changes: 21 additions & 18 deletions src/runtime/program/bpf/serialize.zig
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,10 @@ pub const Serializer = struct {
};

const SerializeReturn = struct {
std.ArrayListUnmanaged(u8),
std.ArrayListUnmanaged(Region),
std.BoundedArray(SerializedAccountMeta, InstructionInfo.MAX_ACCOUNT_METAS),
memory: std.ArrayListUnmanaged(u8),
regions: std.ArrayListUnmanaged(Region),
account_metas: std.BoundedArray(SerializedAccountMeta, InstructionInfo.MAX_ACCOUNT_METAS),
instruction_data_offset: u64,
};

/// [agave] https://github.com/anza-xyz/agave/blob/108fcb4ff0f3cb2e7739ca163e6ead04e377e567/program-runtime/src/serialization.rs#L188
Expand Down Expand Up @@ -345,7 +346,7 @@ fn serializeParametersUnaligned(
}
}
_ = serializer.write(u64, std.mem.nativeToLittle(u64, instruction_data.len));
_ = serializer.writeBytes(instruction_data);
const instruction_data_offset = serializer.writeBytes(instruction_data);
_ = serializer.writeBytes(&program_id.data);

var memory, var regions = try serializer.finish();
Expand All @@ -355,9 +356,10 @@ fn serializeParametersUnaligned(
}

return .{
memory,
regions,
account_metas,
.memory = memory,
.regions = regions,
.account_metas = account_metas,
.instruction_data_offset = instruction_data_offset,
};
}

Expand Down Expand Up @@ -470,7 +472,7 @@ fn serializeParametersAligned(
}

_ = serializer.write(u64, std.mem.nativeToLittle(u64, instruction_data.len));
_ = serializer.writeBytes(instruction_data);
const instruction_data_offset = serializer.writeBytes(instruction_data);
_ = serializer.writeBytes(&program_id.data);

var memory, var regions = try serializer.finish();
Expand All @@ -480,9 +482,10 @@ fn serializeParametersAligned(
}

return .{
memory,
regions,
account_metas,
.memory = memory,
.regions = regions,
.account_metas = account_metas,
.instruction_data_offset = instruction_data_offset,
};
}

Expand Down Expand Up @@ -938,21 +941,21 @@ test "serializeParameters" {
allocator.free(pre_accounts);
}

var memory, var regions, const account_metas = try serializeParameters(
var serialized = try serializeParameters(
allocator,
&ic,
copy_account_data,
false,
);
defer {
memory.deinit(allocator);
regions.deinit(allocator);
serialized.memory.deinit(allocator);
serialized.regions.deinit(allocator);
}

const serialized_regions = try concatRegions(allocator, regions.items);
const serialized_regions = try concatRegions(allocator, serialized.regions.items);
defer allocator.free(serialized_regions);
if (copy_account_data) {
try std.testing.expectEqualSlices(u8, memory.items, serialized_regions);
try std.testing.expectEqualSlices(u8, serialized.memory.items, serialized_regions);
}

// TODO: compare against entrypoint deserialize method once implemented
Expand All @@ -963,8 +966,8 @@ test "serializeParameters" {
allocator,
&ic,
copy_account_data,
memory.items,
account_metas.constSlice(),
serialized.memory.items,
serialized.account_metas.constSlice(),
);
for (pre_accounts, 0..) |pre_account, index_in_transaction| {
const post_account = tc.accounts[index_in_transaction];
Expand Down
Loading