diff --git a/Directory.Build.targets b/Directory.Build.targets
index eb2b0e5..f96ac71 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -5,6 +5,7 @@
+
diff --git a/doc/configuration/properties.md b/doc/configuration/properties.md
index 5618d37..1951005 100644
--- a/doc/configuration/properties.md
+++ b/doc/configuration/properties.md
@@ -156,6 +156,12 @@ historical reasons.
* `RelocationHardening` (`true`, `false`): Enable/disable marking relocations as
read-only. This has security benefits, especially in combination with
`EagerBinding`. Defaults to `true`.
+* `ImageBase`: The location in memory that the binary should be loaded at. Only
+ takes effect at run time if `DynamicImageBase` is `false`. Unset by default.
+* `DynamicImageBase` (`true`, `false`): Enable/disable
+ [ASLR](https://en.wikipedia.org/wiki/Address_space_layout_randomization), i.e.
+ randomization of the image base at run time. Only affects Windows binaries.
+ Defaults to `true`.
* `Sanitizers`: A semicolon-separated list of
[sanitizers](https://github.com/google/sanitizers) to instrument code with.
Currently, only `thread` is supported. Unset by default.
diff --git a/src/sdk/ZigCompile.cs b/src/sdk/ZigCompile.cs
index d9f4cee..e61c2b6 100644
--- a/src/sdk/ZigCompile.cs
+++ b/src/sdk/ZigCompile.cs
@@ -54,12 +54,21 @@ public string Configuration
[Required]
public bool DocumentationAnalysis { get; set; }
+ [Required]
+ public bool DynamicImageBase { get; set; }
+
[Required]
public bool EagerBinding { get; set; }
[Required]
public bool FastMath { get; set; }
+ public int ImageBase
+ {
+ get => _imageBase ?? 0;
+ set => _imageBase = value;
+ }
+
[Required]
public ITaskItem[] IncludeDirectories { get; set; } = null!;
@@ -158,10 +167,14 @@ public string SymbolVisibility
[Required]
public int WarningLevel { get; set; }
+ private static readonly CultureInfo _culture = CultureInfo.InvariantCulture;
+
private ZigCompilerMode _compilerMode;
private ZigConfiguration _configuration;
+ private int? _imageBase;
+
private ZigOutputType _outputType;
private ZigReleaseMode _releaseMode;
@@ -556,13 +569,20 @@ void TryAppendWarningSwitch(string name)
if (!RelocationHardening)
builder.AppendSwitch(isZig ? "-z norelro" : "-Wl,-z,norelro");
+ if (_imageBase is { } ib)
+ builder.AppendSwitchIfNotNull(
+ isZig ? "--image-base 0x" : "-Wl,--image-base,0x", ib.ToString("x", _culture));
+
+ if (!DynamicImageBase)
+ builder.AppendSwitch(isZig ? "--no-dynamicbase" : "-Wl,--no-dynamicbase");
+
builder.AppendSwitch(isZig ? "-z origin" : "-Wl,-z,origin");
builder.AppendSwitchIfNotNull(isZig ? "-rpath " : "-Wl,-rpath,", "$ORIGIN");
// TODO: https://github.com/vezel-dev/zig-sdk/issues/8
- builder.AppendFileNamesIfNotNull(Sources, " ");
- builder.AppendFileNamesIfNotNull(LibraryReferences, " ");
+ builder.AppendFileNamesIfNotNull(Sources, delimiter: " ");
+ builder.AppendFileNamesIfNotNull(LibraryReferences, delimiter: " ");
foreach (var directory in LinkerDirectories)
builder.AppendSwitchIfNotNull("-L ", directory);
diff --git a/src/sdk/build/Vezel.Zig.Sdk.Build.targets b/src/sdk/build/Vezel.Zig.Sdk.Build.targets
index a1e1095..df3dea7 100644
--- a/src/sdk/build/Vezel.Zig.Sdk.Build.targets
+++ b/src/sdk/build/Vezel.Zig.Sdk.Build.targets
@@ -55,9 +55,11 @@
Deterministic="$(Deterministic)"
DisableWarnings="$(DisableWarnings)"
DocumentationAnalysis="$(DocumentationAnalysis)"
+ DynamicImageBase="$(DynamicImageBase)"
EagerBinding="$(EagerBinding)"
EnvironmentVariables="ZIG_GLOBAL_CACHE_DIR=$(CachePath)/global; ZIG_LOCAL_CACHE_DIR=$(CachePath)/local"
FastMath="$(FastMath)"
+ ImageBase="$(ImageBase)"
IncludeDirectories="@(IncludeDirectory)"
LanguageStandard="$(LanguageStandard)"
LibraryIncludeDirectories="@(LibraryIncludeDirectory)"
diff --git a/src/sdk/build/Vezel.Zig.Sdk.Defaults.targets b/src/sdk/build/Vezel.Zig.Sdk.Defaults.targets
index 1cdc090..586646e 100644
--- a/src/sdk/build/Vezel.Zig.Sdk.Defaults.targets
+++ b/src/sdk/build/Vezel.Zig.Sdk.Defaults.targets
@@ -52,6 +52,7 @@
+ true
true
false
diff --git a/src/sdk/build/Vezel.Zig.Sdk.Test.targets b/src/sdk/build/Vezel.Zig.Sdk.Test.targets
index c0d94cb..1eebf1f 100644
--- a/src/sdk/build/Vezel.Zig.Sdk.Test.targets
+++ b/src/sdk/build/Vezel.Zig.Sdk.Test.targets
@@ -28,9 +28,11 @@
Deterministic="$(Deterministic)"
DisableWarnings="$(DisableWarnings)"
DocumentationAnalysis="$(DocumentationAnalysis)"
+ DynamicImageBase="$(DynamicImageBase)"
EagerBinding="$(EagerBinding)"
EnvironmentVariables="ZIG_GLOBAL_CACHE_DIR=$(CachePath)/global; ZIG_LOCAL_CACHE_DIR=$(CachePath)/local"
FastMath="$(FastMath)"
+ ImageBase="$(ImageBase)"
IncludeDirectories="@(IncludeDirectory)"
LanguageStandard="$(LanguageStandard)"
LibraryIncludeDirectories="@(LibraryIncludeDirectory)"