Skip to content

Commit

Permalink
Add command-line option to set VM start address
Browse files Browse the repository at this point in the history
  • Loading branch information
titzer committed Dec 29, 2023
1 parent a2af291 commit a928666
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 23 deletions.
52 changes: 34 additions & 18 deletions aeneas/src/main/CLOptions.v3
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ component CLOptions {
def jvmOpt = OptionGroup.new("JVM TARGET", options);
def debugOpt = OptionGroup.new("DEBUGGING", options);
def langOpt = OptionGroup.new("LANGUAGE", options);
def rtOpt = OptionGroup.new("RUNTIME", options);

// Action options
def HELP = actionOpt.newBoolOption("help", false,
Expand Down Expand Up @@ -145,23 +146,7 @@ component CLOptions {
def NR = sharedOpt.newBoolOption("nr", true,
"Normalize ranges using RangeStart's to support off-heap ranges.");
def SET_EXEC = compileOpt.newBoolOption("set-exec", true,
"Automatically execute permission for compiled binaries.");
def HEAP_SIZE = compileOpt.newSizeOption("heap-size", 0,
"Set the heap size of the compiled program.");
def STACK_SIZE = compileOpt.newSizeOption("stack-size", 0,
"Set the stack size of the compiled program, enabling robust stack overflow checking.");
def RT_STTABLES = compileOpt.newBoolOption("rt.sttables", false,
"Generate runtime metadata for generating stack traces.");
def RT_GCTABLES = compileOpt.newBoolOption("rt.gctables", false,
"Generate runtime metadata for stackwalking for garbage collection.");
def RT_GC = compileOpt.newBoolOption("rt.gc", false,
"Enable runtime support for garbage collection.");
def RT_TEST_GC = compileOpt.newBoolOption("rt.test-gc", false,
"Enable GC testing mode where every allocation triggers a collection.");
def RT_FILES = compileOpt.newOption("rt.files", Array<string>.new(0), "=<path*>", parseStringArray,
"Specify a list of .v3 files that are included with every compiled program (with -multiple).");
def IR_ALLOC = compileOpt.newBoolOption("ir-alloc", false,
"Generate the allocation stub as compiler IR instead of an assembly stub.");
"Automatically set execute permission for compiled binaries.");
def USE_GLOBALREGALLOC = compileOpt.newMatcherOption("global-regalloc",
"Enable global register allocator.");
// JVM target options
Expand All @@ -188,6 +173,33 @@ component CLOptions {
"Specify the name of the main export from a generated Wasm module.");
def ENTRY_EXPORT = wasmOpt.newStringOption("entry-export", "entry",
"Specify the name of the entry export from a generated Wasm module.");
// Runtime options
def HEAP_SIZE = rtOpt.newSizeOption("heap-size", 0,
"Set the heap size of the compiled program.");
def STACK_SIZE = rtOpt.newSizeOption("stack-size", 0,
"Set the stack size of the compiled program, enabling robust stack overflow checking.");
def VM_START_ADDR = rtOpt.newAddrOption("vm-start-addr", 0x08000000,
"Set the virtual memory start of all program segments.");
def CODE_START_ADDR = rtOpt.newAddrOption("code-start-addr", 0,
"Set the code segment start address.");
def DATA_START_ADDR = rtOpt.newAddrOption("data-start-addr", 0,
"Set the data segment start address.");
def HEAP_START_ADDR = rtOpt.newAddrOption("heap-start-addr", 0,
"Set the heap start address.");
def STACK_START_ADDR = rtOpt.newAddrOption("stack-start-addr", 0,
"Set the stack segment start address.");
def RT_STTABLES = rtOpt.newBoolOption("rt.sttables", false,
"Generate runtime metadata for generating stack traces.");
def RT_GCTABLES = rtOpt.newBoolOption("rt.gctables", false,
"Generate runtime metadata for stackwalking for garbage collection.");
def RT_GC = rtOpt.newBoolOption("rt.gc", false,
"Enable runtime support for garbage collection.");
def RT_TEST_GC = rtOpt.newBoolOption("rt.test-gc", false,
"Enable GC testing mode where every allocation triggers a collection.");
def RT_FILES = rtOpt.newOption("rt.files", Array<string>.new(0), "=<path*>", parseStringArray,
"Specify a list of .v3 files that are included with every compiled program (with -multiple).");
def IR_ALLOC = rtOpt.newBoolOption("ir-alloc", false,
"Generate the allocation stub as compiler IR instead of an assembly stub.");

def parseMatcher(str: string) -> VstMatcher {
if (str == null) return VstMatcher.All;
Expand Down Expand Up @@ -239,6 +251,7 @@ component CLOptions {
compileOpt.print(buf);
wasmOpt.print(buf);
jvmOpt.print(buf);
rtOpt.print(buf);
} else {
printUsageAndSharedOptions(buf, "Usage: v3c (-run|-test|-version|-target=<target>) [options] <v3 files>");
actionOpt.print(buf);
Expand All @@ -257,7 +270,7 @@ class OptionGroup(name: string, o: BasicOptions) {

def newMatcherOption(name: string, help: string) -> Option<VstMatcher> {
var r: Option<VstMatcher> = Option.new(name, VstMatcher.None, CLOptions.parseMatcher);
return add(o.add(r), "[=<method pattern(s)>]", help);
return add(o.add(r), "[=<method patterns>]", help);
}
def newIntOption(name: string, defval: int, help: string) -> Option<int> {
return add(o.newIntOption(name, defval), "=<int>", help);
Expand All @@ -274,6 +287,9 @@ class OptionGroup(name: string, o: BasicOptions) {
def newSizeOption(name: string, defval: u32, help: string) -> Option<u32> {
return add(o.newSizeOption(name, defval), "=<int[K|M|G]>", help);
}
def newAddrOption(name: string, defval: u64, help: string) -> Option<u64> {
return add(o.newAddrOption(name, defval), "=<address>", help);
}
def newEmptyOption(name: string, help: string) -> Option<bool> {
return add(o.newOption(name, false, parseEmpty), "", help);
}
Expand Down
2 changes: 1 addition & 1 deletion aeneas/src/main/Version.v3
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@

// Updated by VCS scripts. DO NOT EDIT.
component Version {
def version: string = "III-7.1678";
def version: string = "III-7.1679";
var buildData: string;
}
6 changes: 4 additions & 2 deletions aeneas/src/os/Linux.v3
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class LinuxTarget extends Target {
def newBackend: (Compiler, Program, MachProgram, MachDataWriter, Dwarf) -> MachBackend;
def kernelCallReturnType: Type;
def linuxComponent = Kernel_TypeCon.new(Kernel.LINUX, kernelCallReturnType);
def VADDR_START = 0x08000000; // TODO: configure based on flags
def DEFAULT_VADDR_START = 0x08000000;
def elf_machine: int;

new(name: string, space, intNorm, machLoweringConfig, newBackend, elf_machine, kernelCallReturnType) super(name) { }
Expand Down Expand Up @@ -54,8 +54,10 @@ class LinuxTarget extends Target {

var pageAlign = rt.codeRegion.space.pageAlign;

var vaddr_start = int.view(CLOptions.VM_START_ADDR.get());
if (vaddr_start == 0) vaddr_start = DEFAULT_VADDR_START;
var w = MachDataWriter.new(rt.codeRegion.space.pageAlign,
VADDR_START, 300);
vaddr_start, 300);

// allocate a stack segment if a non-zero stack size is specified
var stackSize = pageAlign.alignUp(int.!(CLOptions.STACK_SIZE.get()));
Expand Down
5 changes: 3 additions & 2 deletions aeneas/src/x86-64/X86_64Darwin.v3
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def SPACE = AddressSpace.new("mem", false, 64, 8,
// Darwin target for x86-64 architecture. Generates an Mach-O binary directly.
class X86_64DarwinTarget extends Target {
def test: bool;
def VADDR_START: int = 0x08000000;
def DEFAULT_VADDR_START: int = 0x08000000;

new(name: string, test) super(name) { }

Expand Down Expand Up @@ -64,7 +64,8 @@ class X86_64DarwinTarget extends Target {
header.cpusubtype = MachO.CPU_SUBTYPE_X86_64;
header.filetype = MachO.MH_EXECUTE;

var startAddr = VADDR_START;
var startAddr = int.view(CLOptions.VM_START_ADDR.get());
if (startAddr == 0) startAddr = DEFAULT_VADDR_START;
// protect page zero for trapping null accesses
var pz = newSegmentLoad(header, "__NULL", 0);
pz.vmsize = pageAlign.size;
Expand Down
8 changes: 8 additions & 0 deletions lib/util/Option.v3
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ class BasicOptions extends Options {
def newSizeOption(name: string, val: u32) -> Option<u32> {
return add(Option.new(name, val, parseSize));
}
def newAddrOption(name: string, val: u64) -> Option<u64> {
return add(Option.new(name, val, parseAddr));
}
def newBoolOption(name: string, val: bool) -> Option<bool> {
return add(Option.new(name, val, parseBool));
}
Expand Down Expand Up @@ -118,6 +121,11 @@ class BasicOptions extends Options {
}
return 0;
}
def parseAddr(str: string) -> u64 {
var len = str.length;
var p = Longs.parse0xHex(str, 0);
return if(p.0 > 0, u64.view(p.1));
}
def parseString(str: string) -> string {
return if(str == null, "", str);
}
Expand Down
15 changes: 15 additions & 0 deletions test/pointer/fold00.v3
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//@execute 0=0; 1=100; 2=230000000; 3=!BoundsCheckException
def a = Pointer.NULL;
def ptrs = [
a,
a + 100,
a + 230000000
];
def offsets = [
int.!(ptrs[0] - a),
int.!(ptrs[1] - a),
int.!(ptrs[2] - a)
];
def main(a: int) -> int {
return offsets[a];
}

0 comments on commit a928666

Please sign in to comment.