Skip to content

Commit

Permalink
Zld is now Emerald
Browse files Browse the repository at this point in the history
  • Loading branch information
kubkon committed Oct 21, 2024
1 parent 185c6c6 commit 5c874c9
Show file tree
Hide file tree
Showing 23 changed files with 109 additions and 110 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# zld
# emerald

`zld` is a drop-in replacement for your system linker `ld` written in Zig.
`emerald` is a drop-in replacement for your system linker `ld` written in Zig.

## Quick start guide

Expand All @@ -12,7 +12,7 @@ You will need Zig 0.13.0 in your path. You can download it from [here](https://z
$ zig build
```

This will create the `ld.zld` (Elf), `ld64.zld` (MachO), `link-zld` (Coff) and `wasm-zld` (Wasm) binaries in `zig-out/bin/`.
This will create the `ld.emerald` (Elf), `ld64.emerald` (MachO), `emerald-link.exe` (Coff) and `wasm-emerald` (Wasm) binaries in `zig-out/bin/`.
You can then use it like you'd use a standard linker.

```
Expand All @@ -32,10 +32,10 @@ $ clang -c hello.c
$ zig cc -c hello.c
# On macOS
$ ./zig-out/bin/ld64.zld hello.o -o hello
$ ./zig-out/bin/ld64.emerald hello.o -o hello
# On Linux
$ ./zig-out/bin/ld.zld hello.o -o hello
$ ./zig-out/bin/ld.emerald hello.o -o hello
# Run!
$ ./hello
Expand Down
12 changes: 6 additions & 6 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn build(b: *std.Build) void {
});

const exe = b.addExecutable(.{
.name = "zld",
.name = "emerald",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = mode,
Expand Down Expand Up @@ -76,10 +76,10 @@ pub fn build(b: *std.Build) void {
const install = b.addInstallArtifact(exe, .{});
const symlinks = addSymlinks(b, install, &[_][]const u8{
"ld",
"ld.zld",
"ld64.zld",
"link-zld.exe",
"wasm-zld",
"ld.emerald",
"ld64.emerald",
"emerald-link.exe",
"wasm-emerald",
});
symlinks.step.dependOn(&install.step);

Expand All @@ -90,7 +90,7 @@ pub fn build(b: *std.Build) void {
const has_objc_msgsend_stubs = b.option(bool, "has-objc-msgsend-stubs", "Whether the system compiler supports '-fobjc-msgsend-selector-stubs' flag") orelse false;

const unit_tests = b.addTest(.{
.root_source_file = b.path("src/Zld.zig"),
.root_source_file = b.path("src/Ld.zig"),
.target = target,
.optimize = mode,
.use_llvm = use_llvm,
Expand Down
2 changes: 1 addition & 1 deletion build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.{
.name = "zld",
.name = "emerald",
.version = "0.0.3",

.dependencies = .{
Expand Down
6 changes: 3 additions & 3 deletions src/Coff.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
base: Zld,
base: Ld,
options: Options,

internal_object_index: ?File.Index = null,
Expand Down Expand Up @@ -1718,7 +1718,7 @@ const AlternateName = struct {
index: Symbol.Index,
};

pub const base_tag = Zld.Tag.coff;
pub const base_tag = Ld.Tag.coff;

const build_options = @import("build_options");
const builtin = @import("builtin");
Expand All @@ -1741,10 +1741,10 @@ const Coff = @This();
const Dll = @import("Coff/Dll.zig");
const File = @import("Coff/file.zig").File;
const InternalObject = @import("Coff/InternalObject.zig");
const Ld = @import("Ld.zig");
const Object = @import("Coff/Object.zig");
pub const Options = @import("Coff/Options.zig");
const RelocSection = synthetic.RelocSection;
const StringTable = @import("StringTable.zig");
const Symbol = @import("Coff/Symbol.zig");
const ThreadPool = std.Thread.Pool;
const Zld = @import("Zld.zig");
10 changes: 5 additions & 5 deletions src/Coff/Options.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
emit: Zld.Emit,
emit: Ld.Emit,
cpu_arch: ?std.Target.Cpu.Arch = null,
positionals: []const Coff.LinkObject,
lib_paths: []const []const u8,
Expand All @@ -20,7 +20,7 @@ pub fn parse(arena: Allocator, args: []const []const u8, ctx: anytype) !Options
};
var verbose = false;

var it = Zld.Options.ArgsIterator{ .args = args };
var it = Ld.Options.ArgsIterator{ .args = args };
var p = ArgsParser(@TypeOf(it)){ .it = &it };
while (p.hasMore()) {
if (p.flag("help")) {
Expand Down Expand Up @@ -146,7 +146,7 @@ const usage =
\\
\\General Options:
\\-align:number Alignment value in bytes
\\-debug-log:scope Turn on debugging logs for 'scope' (requires zld compiled with -Dlog)
\\-debug-log:scope Turn on debugging logs for 'scope' (requires linker compiled with -Dlog)
\\-defaultlib:name Link a default library
\\-filealign:size Section alignment size in bytes, must be power of two
\\-help Print this help and exit
Expand All @@ -156,7 +156,7 @@ const usage =
\\-v Print full linker invocation to stderr
;

const cmd = "link-zld.exe";
const cmd = "link-emerald.exe";

const builtin = @import("builtin");
const io = std.io;
Expand All @@ -168,4 +168,4 @@ const Allocator = mem.Allocator;
const CrossTarget = std.zig.CrossTarget;
const Coff = @import("../Coff.zig");
const Options = @This();
const Zld = @import("../Zld.zig");
const Ld = @import("../Ld.zig");
6 changes: 3 additions & 3 deletions src/Elf.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
base: Zld,
base: Ld,
options: Options,
shoff: u64 = 0,

Expand Down Expand Up @@ -3001,7 +3001,7 @@ pub const null_sym = elf.Elf64_Sym{
.st_size = 0,
};

pub const base_tag = Zld.Tag.elf;
pub const base_tag = Ld.Tag.elf;

const std = @import("std");
const build_options = @import("build_options");
Expand Down Expand Up @@ -3038,6 +3038,7 @@ const Hash = std.hash.Wyhash;
const HashSection = synthetic.HashSection;
const InputMergeSection = merge_section.InputMergeSection;
const InternalObject = @import("Elf/InternalObject.zig");
const Ld = @import("Ld.zig");
const LdScript = @import("Elf/LdScript.zig");
const MergeSection = merge_section.MergeSection;
const MergeSubsection = merge_section.MergeSubsection;
Expand All @@ -3051,4 +3052,3 @@ const Symbol = @import("Elf/Symbol.zig");
const ThreadPool = std.Thread.Pool;
const Thunk = @import("Elf/Thunk.zig");
const VerneedSection = synthetic.VerneedSection;
const Zld = @import("Zld.zig");
6 changes: 3 additions & 3 deletions src/Elf/Object.zig
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,8 @@ fn filterRelocs(
}
};

const f_start = Zld.binarySearch(elf.Elf64_Rela, relocs, Predicate{ .value = start });
const f_len = Zld.linearSearch(elf.Elf64_Rela, relocs[f_start..], LPredicate{ .value = start + len });
const f_start = Ld.binarySearch(elf.Elf64_Rela, relocs, Predicate{ .value = start });
const f_len = Ld.linearSearch(elf.Elf64_Rela, relocs[f_start..], LPredicate{ .value = start + len });

return .{ .start = f_start, .len = f_len };
}
Expand Down Expand Up @@ -1408,4 +1408,4 @@ const File = @import("file.zig").File;
const InputMergeSection = @import("merge_section.zig").InputMergeSection;
const StringTable = @import("../StringTable.zig");
const Symbol = @import("Symbol.zig");
const Zld = @import("../Zld.zig");
const Ld = @import("../Ld.zig");
18 changes: 9 additions & 9 deletions src/Elf/Options.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
emit: Zld.Emit,
emit: Ld.Emit,
shared: bool = false,
relocatable: bool = false,
positionals: []const Elf.LinkObject,
Expand Down Expand Up @@ -68,8 +68,8 @@ pub fn parse(arena: Allocator, args: []const []const u8, ctx: anytype) !Options
.rpath_list = undefined,
};

var it = Zld.Options.ArgsIterator{ .args = args };
var p = Zld.ArgParser(@TypeOf(ctx)){ .it = &it, .ctx = ctx };
var it = Ld.Options.ArgsIterator{ .args = args };
var p = Ld.ArgParser(@TypeOf(ctx)){ .it = &it, .ctx = ctx };
while (p.hasMore()) {
if (p.flag2("help")) {
ctx.fatal(usage ++ "\n", .{cmd});
Expand Down Expand Up @@ -378,7 +378,7 @@ const usage =
\\--build-id=[none,md5,sha1,sha256,uuid,HEXSTRING]
\\ Generate build ID
\\ --no-build-id
\\--debug-log [value] Turn on debugging logs for [value] (requires zld compiled with -Dlog)
\\--debug-log [value] Turn on debugging logs for [value] (requires linker compiled with -Dlog)
\\--dynamic Alias for --Bdynamic
\\--dynamic-linker=[value], -I [value]
\\ Set the dynamic linker to use
Expand Down Expand Up @@ -438,12 +438,12 @@ const usage =
\\-v, --version Print version
\\-V Print version and target information
\\
\\ld.zld: supported target: elf64-x86-64, elf64-littleaarch64, elf64-littleriscv
\\ld.zld: supported emulations: elf64_x86_64, aarch64linux, aarch64elf, elf64lriscv
\\ld.emerald: supported target: elf64-x86-64, elf64-littleaarch64, elf64-littleriscv
\\ld.emerald: supported emulations: elf64_x86_64, aarch64linux, aarch64elf, elf64lriscv
;

pub const version =
\\ld.zld 0.0.4 (compatible with GNU ld)
\\ld.emerald 0.0.4 (compatible with GNU ld)
;

fn cpuArchToElfEmulation(cpu_arch: std.Target.Cpu.Arch) []const u8 {
Expand Down Expand Up @@ -483,7 +483,7 @@ fn parseSectionStart(opts: *Options, arena: Allocator, name: []const u8, value:
_ = try opts.section_start.put(arena, try arena.dupe(u8, name), start);
}

const cmd = "ld.zld";
const cmd = "ld.emerald";

pub const BuildId = enum {
none,
Expand All @@ -510,4 +510,4 @@ const process = std.process;
const Allocator = mem.Allocator;
const Elf = @import("../Elf.zig");
const Options = @This();
const Zld = @import("../Zld.zig");
const Ld = @import("../Ld.zig");
2 changes: 1 addition & 1 deletion src/Elf/gc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ pub fn dumpPrunedAtoms(elf_file: *Elf) !void {
for (object.atoms_indexes.items) |atom_index| {
const atom = object.getAtom(atom_index) orelse continue;
if (!atom.flags.alive)
try stderr.print("ld.zld: removing unused section '{s}' in file '{}'\n", .{
try stderr.print("ld.emerald: removing unused section '{s}' in file '{}'\n", .{
atom.getName(elf_file),
atom.getObject(elf_file).fmtPath(),
});
Expand Down
26 changes: 13 additions & 13 deletions src/Zld.zig → src/Ld.zig
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ pub const ErrorMsg = struct {
}
};

pub fn openPath(allocator: Allocator, tag: Tag, options: Options, thread_pool: *ThreadPool) !*Zld {
pub fn openPath(allocator: Allocator, tag: Tag, options: Options, thread_pool: *ThreadPool) !*Ld {
return switch (tag) {
.macho => &(try MachO.openPath(allocator, options.macho, thread_pool)).base,
.elf => &(try Elf.openPath(allocator, options.elf, thread_pool)).base,
Expand All @@ -213,7 +213,7 @@ pub fn openPath(allocator: Allocator, tag: Tag, options: Options, thread_pool: *
};
}

pub fn deinit(base: *Zld) void {
pub fn deinit(base: *Ld) void {
base.file.close();
assert(base.warnings.items.len == 0);
base.warnings.deinit(base.allocator);
Expand Down Expand Up @@ -243,7 +243,7 @@ pub fn deinit(base: *Zld) void {
}
}

pub fn flush(base: *Zld) !void {
pub fn flush(base: *Ld) !void {
switch (base.tag) {
.elf => try @as(*Elf, @fieldParentPtr("base", base)).flush(),
.macho => try @as(*MachO, @fieldParentPtr("base", base)).flush(),
Expand All @@ -252,12 +252,12 @@ pub fn flush(base: *Zld) !void {
}
}

pub fn warn(base: *Zld, comptime format: []const u8, args: anytype) void {
pub fn warn(base: *Ld, comptime format: []const u8, args: anytype) void {
const warning = base.addWarningWithNotes(0) catch return;
warning.addMsg(format, args) catch return;
}

pub fn fatal(base: *Zld, comptime format: []const u8, args: anytype) void {
pub fn fatal(base: *Ld, comptime format: []const u8, args: anytype) void {
const err = base.addErrorWithNotes(0) catch return;
err.addMsg(format, args) catch return;
}
Expand Down Expand Up @@ -285,7 +285,7 @@ pub const ErrorWithNotes = struct {
}
};

pub fn addErrorWithNotes(base: *Zld, note_count: usize) !ErrorWithNotes {
pub fn addErrorWithNotes(base: *Ld, note_count: usize) !ErrorWithNotes {
base.errors_mutex.lock();
defer base.errors_mutex.unlock();
const err_index = base.errors.items.len;
Expand All @@ -295,7 +295,7 @@ pub fn addErrorWithNotes(base: *Zld, note_count: usize) !ErrorWithNotes {
return .{ .err_index = err_index, .allocator = base.allocator, .errors = base.errors.items };
}

pub fn addWarningWithNotes(base: *Zld, note_count: usize) !ErrorWithNotes {
pub fn addWarningWithNotes(base: *Ld, note_count: usize) !ErrorWithNotes {
base.warnings_mutex.lock();
defer base.warnings_mutex.unlock();
const err_index = base.warnings.items.len;
Expand All @@ -305,7 +305,7 @@ pub fn addWarningWithNotes(base: *Zld, note_count: usize) !ErrorWithNotes {
return .{ .err_index = err_index, .allocator = base.allocator, .errors = base.warnings.items };
}

pub fn getAllWarningsAlloc(base: *Zld) !ErrorBundle {
pub fn getAllWarningsAlloc(base: *Ld) !ErrorBundle {
var bundle: ErrorBundle.Wip = undefined;
try bundle.init(base.allocator);
defer bundle.deinit();
Expand Down Expand Up @@ -333,7 +333,7 @@ pub fn getAllWarningsAlloc(base: *Zld) !ErrorBundle {
return bundle.toOwnedBundle("");
}

pub fn getAllErrorsAlloc(base: *Zld) !ErrorBundle {
pub fn getAllErrorsAlloc(base: *Ld) !ErrorBundle {
var bundle: ErrorBundle.Wip = undefined;
try bundle.init(base.allocator);
defer bundle.deinit();
Expand Down Expand Up @@ -403,15 +403,15 @@ fn renderWarningMessageToWriter(
}
}

pub fn reportErrors(base: *Zld) void {
pub fn reportErrors(base: *Ld) void {
var errors = base.getAllErrorsAlloc() catch @panic("OOM");
defer errors.deinit(base.allocator);
if (errors.errorMessageCount() > 0) {
errors.renderToStdErr(.{ .ttyconf = std.io.tty.detectConfig(std.io.getStdErr()) });
}
}

pub fn reportWarnings(base: *Zld) void {
pub fn reportWarnings(base: *Ld) void {
var warnings = base.getAllWarningsAlloc() catch @panic("OOM");
defer warnings.deinit(base.allocator);
if (warnings.errorMessageCount() > 0) {
Expand Down Expand Up @@ -451,7 +451,7 @@ pub fn linearSearch(comptime T: type, haystack: []align(1) const T, predicate: a
}

test {
std.testing.refAllDeclsRecursive(Zld);
std.testing.refAllDeclsRecursive(Ld);
}

const std = @import("std");
Expand All @@ -470,5 +470,5 @@ pub const Wasm = @import("Wasm.zig");
const Allocator = mem.Allocator;
const CrossTarget = std.zig.CrossTarget;
const ErrorBundle = std.zig.ErrorBundle;
const Ld = @This();
const ThreadPool = std.Thread.Pool;
const Zld = @This();
10 changes: 5 additions & 5 deletions src/MachO.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
base: Zld,
base: Ld,
options: Options,

dyld_info_cmd: macho.dyld_info_command = .{},
Expand Down Expand Up @@ -1279,8 +1279,8 @@ fn reportUndefs(self: *MachO) !void {
const addFn = switch (self.options.undefined_treatment) {
.dynamic_lookup => unreachable, // handled above
.suppress => unreachable, // handled above
.@"error" => &Zld.addErrorWithNotes,
.warn => &Zld.addWarningWithNotes,
.@"error" => &Ld.addErrorWithNotes,
.warn => &Ld.addWarningWithNotes,
};

const gpa = self.base.allocator;
Expand Down Expand Up @@ -3324,7 +3324,7 @@ pub const String = struct {
len: u32 = 0,
};

pub const base_tag = Zld.Tag.macho;
pub const base_tag = Ld.Tag.macho;

const aarch64 = @import("aarch64.zig");
const assert = std.debug.assert;
Expand Down Expand Up @@ -3364,6 +3364,7 @@ const GotSection = synthetic.GotSection;
const Hash = std.hash.Wyhash;
const Indsymtab = synthetic.Indsymtab;
const InternalObject = @import("MachO/InternalObject.zig");
const Ld = @import("Ld.zig");
const MachO = @This();
const Md5 = std.crypto.hash.Md5;
const Object = @import("MachO/Object.zig");
Expand All @@ -3383,4 +3384,3 @@ const TlvPtrSection = synthetic.TlvPtrSection;
const UnwindInfo = @import("MachO/UnwindInfo.zig");
const WaitGroup = std.Thread.WaitGroup;
const WeakBind = synthetic.WeakBind;
const Zld = @import("Zld.zig");
Loading

0 comments on commit 5c874c9

Please sign in to comment.