aboutsummaryrefslogtreecommitdiff
path: root/src/link/Elf.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-12-26 21:39:39 -0700
committerAndrew Kelley <andrew@ziglang.org>2024-01-01 17:51:21 -0700
commit57562c8d507667b6fefcb7fbc7a305fbd610b5dd (patch)
treef0e494bdace7302f7cce8ad8c9c7d3227bd81d64 /src/link/Elf.zig
parentc9fe43679f8d8f0db6250cc881b59cc68daaf128 (diff)
downloadzig-57562c8d507667b6fefcb7fbc7a305fbd610b5dd.tar.gz
zig-57562c8d507667b6fefcb7fbc7a305fbd610b5dd.zip
compiler: push entry symbol name resolution into the linker
This is necessary because on COFF, the entry symbol name is not known until the linker has looked at the set of global symbol names to determine which of the four possible main entry points is present.
Diffstat (limited to 'src/link/Elf.zig')
-rw-r--r--src/link/Elf.zig29
1 files changed, 21 insertions, 8 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index ea8454490c..65fc0ff5a3 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -25,6 +25,7 @@ linker_script: ?[]const u8,
version_script: ?[]const u8,
print_icf_sections: bool,
print_map: bool,
+entry_name: ?[]const u8,
ptr_width: PtrWidth,
@@ -290,6 +291,13 @@ pub fn createEmpty(
.page_size = page_size,
.default_sym_version = default_sym_version,
+ .entry_name = switch (options.entry) {
+ .disabled => null,
+ .default => if (output_mode != .Exe) null else defaultEntrySymbolName(target.cpu.arch),
+ .enabled => defaultEntrySymbolName(target.cpu.arch),
+ .named => |name| name,
+ },
+
.image_base = b: {
if (is_dyn_lib) break :b 0;
if (output_mode == .Exe and comp.config.pie) break :b 0;
@@ -1305,7 +1313,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
// Look for entry address in objects if not set by the incremental compiler.
if (self.entry_index == null) {
- if (comp.config.entry) |name| {
+ if (self.entry_name) |name| {
self.entry_index = self.globalByName(name);
}
}
@@ -1679,9 +1687,8 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
}
}
- if (comp.config.entry) |entry| {
- try argv.append("--entry");
- try argv.append(entry);
+ if (self.entry_name) |name| {
+ try argv.appendSlice(&.{ "--entry", name });
}
for (self.base.rpath_list) |rpath| {
@@ -2427,7 +2434,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
// We can skip hashing libc and libc++ components that we are in charge of building from Zig
// installation sources because they are always a product of the compiler version + target information.
- man.hash.addOptionalBytes(comp.config.entry);
+ man.hash.addOptionalBytes(self.entry_name);
man.hash.add(self.image_base);
man.hash.add(self.base.gc_sections);
man.hash.addOptional(self.sort_section);
@@ -2563,9 +2570,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
.ReleaseFast, .ReleaseSafe => try argv.append("-O3"),
}
- if (comp.config.entry) |entry| {
- try argv.append("--entry");
- try argv.append(entry);
+ if (self.entry_name) |name| {
+ try argv.appendSlice(&.{ "--entry", name });
}
for (self.base.force_undefined_symbols.keys()) |sym| {
@@ -6512,6 +6518,13 @@ const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection);
pub const R_X86_64_ZIG_GOT32 = elf.R_X86_64_NUM + 1;
pub const R_X86_64_ZIG_GOTPCREL = elf.R_X86_64_NUM + 2;
+fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {
+ return switch (cpu_arch) {
+ .mips, .mipsel, .mips64, .mips64el => "__start",
+ else => "_start",
+ };
+}
+
const std = @import("std");
const build_options = @import("build_options");
const builtin = @import("builtin");