Skip to content

Commit

Permalink
svm: adjust sbpf version naming
Browse files Browse the repository at this point in the history
  • Loading branch information
Rexicon226 committed Jan 29, 2025
1 parent f25fda3 commit 66efd3c
Show file tree
Hide file tree
Showing 12 changed files with 282 additions and 209 deletions.
Binary file added data/test-elfs/reloc_64_64_sbpfv0.so
Binary file not shown.
Binary file added data/test-elfs/reloc_64_relative_data_sbpfv0.so
Binary file not shown.
Binary file added data/test-elfs/reloc_64_relative_sbpfv0.so
Binary file not shown.
Binary file added data/test-elfs/rodata_section_sbpfv0.so
Binary file not shown.
24 changes: 12 additions & 12 deletions scripts/gen_svm_elfs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,27 @@ C_BASE_FLAGS="-target sbf-solana-solana \
-O2 \
-Werror \
-Wno-override-module"
C_FLAGS="${C_BASE_FLAGS} -mcpu=v1"
C_FLAGS_V2="${C_BASE_FLAGS} -mcpu=sbfv2"
C_FLAGS="${C_BASE_FLAGS} -mcpu=generic"
C_FLAGS_V1="${C_BASE_FLAGS} -mcpu=sbfv2"

CC_V1="${CC} ${C_FLAGS}"
CC_V2="${CC} ${C_FLAGS_V2}"
CC_V0="${CC} ${C_FLAGS}"
CC_V1="${CC} ${C_FLAGS_V1}"

LD_V1="${LD} ${LD_FLAGS}"
LD_V2="${LD_V1} --section-start=.text=0x100000000"
LD_V0="${LD} ${LD_FLAGS}"
LD_V1="${LD_V0} --section-start=.text=0x100000000"

V1_FILES=(reloc_64_64 reloc_64_relative reloc_64_relative_data rodata_section)
V0_FILES=(reloc_64_64 reloc_64_relative reloc_64_relative_data rodata_section)

for ZIG_FILE in data/test-elfs/*.zig; do
BASE_NAME=$(basename "$ZIG_FILE" .zig)

$ZIG build-obj "$ZIG_FILE" -OReleaseSmall -fstrip -fno-emit-bin -femit-llvm-bc="data/test-elfs/${BASE_NAME}.bc"
$CC_V2 "data/test-elfs/${BASE_NAME}.bc" -c -o "data/test-elfs/${BASE_NAME}.o"
$LD_V2 "data/test-elfs/${BASE_NAME}.o" -o "data/test-elfs/${BASE_NAME}.so"
$CC_V1 "data/test-elfs/${BASE_NAME}.bc" -c -o "data/test-elfs/${BASE_NAME}.o"
$LD_V1 "data/test-elfs/${BASE_NAME}.o" -o "data/test-elfs/${BASE_NAME}.so"

if [[ " ${V1_FILES[@]} " =~ " ${BASE_NAME} " ]]; then
$CC_V1 "data/test-elfs/${BASE_NAME}.bc" -c -o "data/test-elfs/${BASE_NAME}_sbpfv1.o"
$LD_V1 "data/test-elfs/${BASE_NAME}_sbpfv1.o" -o "data/test-elfs/${BASE_NAME}_sbpfv1.so"
if [[ " ${V0_FILES[@]} " =~ " ${BASE_NAME} " ]]; then
$CC_V0 "data/test-elfs/${BASE_NAME}.bc" -c -o "data/test-elfs/${BASE_NAME}_sbpfv0.o"
$LD_V0 "data/test-elfs/${BASE_NAME}_sbpfv0.o" -o "data/test-elfs/${BASE_NAME}_sbpfv0.so"
fi
done

Expand Down
24 changes: 16 additions & 8 deletions src/svm/elf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub const Elf = struct {
headers: Headers,
data: Data,
entry_pc: u64,
version: sbpf.SBPFVersion,
version: sbpf.Version,
function_registry: Registry(u64),
ro_section: Executable.Section,
config: Config,
Expand Down Expand Up @@ -356,10 +356,18 @@ pub const Elf = struct {
const offset = headers.header.e_entry -| text_section.sh_addr;
const entry_pc = try std.math.divExact(u64, offset, 8);

const sbpf_version: sbpf.SBPFVersion = if (headers.header.e_flags == sbpf.EF_SBPF_V2)
.v2
else
.v1;
const sbpf_version: sbpf.Version = if (config.minimum_version == .v0)
if (headers.header.e_flags == sbpf.EF_SBPF_v1)
.v1
else
.v0
else switch (headers.header.e_flags) {
0 => .v0,
1 => .v1,
2 => .v2,
3 => .v3,
else => @enumFromInt(headers.header.e_flags),
};

if (@intFromEnum(sbpf_version) < @intFromEnum(config.minimum_version))
return error.VersionUnsupported;
Expand Down Expand Up @@ -539,7 +547,7 @@ pub const Elf = struct {
const in_text_section = self.inRangeOfShdr(
text_section_index,
r_offset,
) or version == .v1;
) or version == .v0;
const imm_offset = if (in_text_section) r_offset +| 4 else r_offset;

const addr_slice = try safeSlice(self.bytes, imm_offset, 4);
Expand All @@ -551,7 +559,7 @@ pub const Elf = struct {
addr +|= memory.PROGRAM_START;
}

if (in_text_section or version == .v1) {
if (in_text_section or version == .v0) {
{
const imm_low_offset = imm_offset;
const imm_slice = try safeSlice(self.bytes, imm_low_offset, 4);
Expand Down Expand Up @@ -615,7 +623,7 @@ pub const Elf = struct {
}
} else {
const address: u64 = switch (version) {
.v1 => addr: {
.v0 => addr: {
const addr_slice = try safeSlice(self.bytes, imm_offset, 4);
const address = std.mem.readInt(u32, addr_slice[0..4], .little);
break :addr memory.PROGRAM_START +| address;
Expand Down
64 changes: 34 additions & 30 deletions src/svm/executable.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const Vm = @import("vm.zig").Vm;
pub const Executable = struct {
bytes: []const u8,
instructions: []align(1) const sbpf.Instruction,
version: sbpf.SBPFVersion,
version: sbpf.Version,
entry_pc: u64,
from_elf: bool,
ro_section: Section,
Expand Down Expand Up @@ -55,25 +55,38 @@ pub const Executable = struct {
}

pub fn fromAsm(allocator: std.mem.Allocator, source: []const u8, config: Config) !Executable {
return Assembler.parse(allocator, source, config);
var function_registry, const instructions = try Assembler.parse(
allocator,
source,
config,
);
return fromTextBytes(
allocator,
std.mem.sliceAsBytes(instructions),
&function_registry,
config,
);
}

pub fn fromTextBytes(
allocator: std.mem.Allocator,
source: []const u8,
version: sbpf.SBPFVersion,
registry: *Registry(u64),
config: Config,
) !Executable {
const version = config.minimum_version;

const entry_pc = if (registry.lookupName("entrypoint")) |entry_pc|
entry_pc.value
else
try registry.registerHashedLegacy(
else pc: {
_ = try registry.registerHashedLegacy(
allocator,
!version.enableStaticSyscalls(),
"entrypoint",
0,
);
break :pc 0;
};

return .{
.instructions = std.mem.bytesAsSlice(sbpf.Instruction, source),
Expand All @@ -84,7 +97,10 @@ pub const Executable = struct {
.entry_pc = entry_pc,
.ro_section = .{ .borrowed = .{ .offset = 0, .start = 0, .end = 0 } },
.from_elf = false,
.text_vaddr = memory.PROGRAM_START,
.text_vaddr = if (version.enableLowerBytecodeVaddr())
memory.BYTECODE_START
else
memory.PROGRAM_START,
};
}

Expand Down Expand Up @@ -140,7 +156,8 @@ pub const Assembler = struct {
allocator: std.mem.Allocator,
source: []const u8,
config: Config,
) !Executable {
) !struct { Registry(u64), []const sbpf.Instruction } {
const version = config.minimum_version;
var assembler: Assembler = .{ .source = source };
const statements = try assembler.tokenize(allocator);
defer {
Expand Down Expand Up @@ -327,7 +344,13 @@ pub const Assembler = struct {
};
}
},
.call_reg => .{
.call_reg => if (version.callRegUsesSrcReg()) .{
.opcode = @enumFromInt(bind.opc),
.dst = .r0,
.src = operands[0].register,
.off = 0,
.imm = 0,
} else .{
.opcode = @enumFromInt(bind.opc),
.dst = .r0,
.src = .r0,
Expand Down Expand Up @@ -359,28 +382,9 @@ pub const Assembler = struct {
}
}

const entry_pc = if (function_registry.lookupName("entrypoint")) |entry|
entry.value
else pc: {
_ = try function_registry.registerHashedLegacy(
allocator,
!config.minimum_version.enableStaticSyscalls(),
"entrypoint",
0,
);
break :pc 0;
};

return .{
.bytes = source,
.ro_section = .{ .borrowed = .{ .offset = 0, .start = 0, .end = source.len } },
.instructions = try instructions.toOwnedSlice(allocator),
.version = config.minimum_version,
.entry_pc = entry_pc,
.from_elf = false,
.text_vaddr = memory.PROGRAM_START,
.function_registry = function_registry,
.config = config,
function_registry,
try instructions.toOwnedSlice(allocator),
};
}

Expand Down Expand Up @@ -546,7 +550,7 @@ pub const BuiltinProgram = struct {
pub const Config = struct {
optimize_rodata: bool = true,
reject_broken_elfs: bool = false,
minimum_version: sbpf.SBPFVersion = .v2,
minimum_version: sbpf.Version = .v3,
stack_frame_size: u64 = 4096,
max_call_depth: u64 = 64,

Expand Down
2 changes: 1 addition & 1 deletion src/svm/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ pub fn main() !void {
}

const config: Config = .{
.minimum_version = if (assemble) .v2 else .v1,
.minimum_version = if (assemble) .v3 else .v0,
};
var executable = if (assemble)
try Executable.fromAsm(allocator, bytes, config)
Expand Down
18 changes: 12 additions & 6 deletions src/svm/memory.zig
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
const std = @import("std");
const sbpf = @import("sbpf.zig");

/// Virtual address of the bytecode region (in SBPFv3)
pub const BYTECODE_START: u64 = 0x000000000;
/// Virtual address of the readonly data region (also contains the bytecode until SBPFv3)
pub const PROGRAM_START: u64 = 0x100000000;
/// Virtual address of the stack region
pub const STACK_START: u64 = 0x200000000;
/// Virtual address of the heap region
pub const HEAP_START: u64 = 0x300000000;
/// Virtual address of the input region
pub const INPUT_START: u64 = 0x400000000;
const VIRTUAL_ADDRESS_BITS = 32;

pub const MemoryMap = union(enum) {
aligned: AlignedMemoryMap,
// TODO: unaligned memory map?

pub fn init(regions: []const Region, version: sbpf.SBPFVersion) !MemoryMap {
pub fn init(regions: []const Region, version: sbpf.Version) !MemoryMap {
return .{ .aligned = try AlignedMemoryMap.init(regions, version) };
}

Expand Down Expand Up @@ -113,9 +119,9 @@ pub const Region = struct {

const AlignedMemoryMap = struct {
regions: []const Region,
version: sbpf.SBPFVersion,
version: sbpf.Version,

fn init(regions: []const Region, version: sbpf.SBPFVersion) !AlignedMemoryMap {
fn init(regions: []const Region, version: sbpf.Version) !AlignedMemoryMap {
for (regions, 1..) |reg, index| {
if (reg.vm_addr_start >> VIRTUAL_ADDRESS_BITS != index) {
return error.InvalidMemoryRegion;
Expand Down Expand Up @@ -162,7 +168,7 @@ test "aligned vmap" {
const m = try MemoryMap.init(&.{
Region.init(.mutable, &program_mem, PROGRAM_START),
Region.init(.constant, &stack_mem, STACK_START),
}, .v1);
}, .v0);

try expectEqual(
program_mem[0..1],
Expand Down Expand Up @@ -198,7 +204,7 @@ test "aligned region" {
const m = try MemoryMap.init(&.{
Region.init(.mutable, &program_mem, PROGRAM_START),
Region.init(.constant, &stack_mem, STACK_START),
}, .v1);
}, .v0);

try expectError(
error.AccessNotMapped,
Expand Down Expand Up @@ -244,6 +250,6 @@ test "invalid memory region" {
MemoryMap.init(&.{
Region.init(.constant, &stack_mem, STACK_START),
Region.init(.mutable, &program_mem, PROGRAM_START),
}, .v1),
}, .v0),
);
}
Loading

0 comments on commit 66efd3c

Please sign in to comment.