Commit 3618824ea3

Jakub Konka <kubkon@jakubkonka.com>
2024-07-29 18:08:10
elf: move entry tracking into LinkerDefined
1 parent 5ceac8e
Changed files (3)
src/link/Elf/gc.zig
@@ -16,9 +16,11 @@ pub fn gcAtoms(elf_file: *Elf) !void {
 }
 
 fn collectRoots(roots: *std.ArrayList(*Atom), files: []const File.Index, elf_file: *Elf) !void {
-    if (elf_file.entry_index) |index| {
-        const global = elf_file.symbol(index);
-        try markSymbol(global, roots, elf_file);
+    if (elf_file.linkerDefinedPtr()) |obj| {
+        if (obj.entry_index) |index| {
+            const global = elf_file.symbol(index);
+            try markSymbol(global, roots, elf_file);
+        }
     }
 
     for (files) |index| {
src/link/Elf/LinkerDefined.zig
@@ -4,6 +4,7 @@ symtab: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{},
 strtab: std.ArrayListUnmanaged(u8) = .{},
 symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
 
+entry_index: ?Symbol.Index = null,
 dynamic_index: ?Symbol.Index = null,
 ehdr_start_index: ?Symbol.Index = null,
 init_array_start_index: ?Symbol.Index = null,
@@ -39,6 +40,12 @@ pub fn init(self: *LinkerDefined, allocator: Allocator) !void {
 pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
     const gpa = elf_file.base.comp.gpa;
 
+    // Look for entry address in objects if not set by the incremental compiler.
+    if (self.entry_index == null) {
+        if (elf_file.entry_name) |name| {
+            self.entry_index = elf_file.globalByName(name);
+        }
+    }
     self.dynamic_index = try self.addGlobal("_DYNAMIC", elf_file);
     self.ehdr_start_index = try self.addGlobal("__ehdr_start", elf_file);
     self.init_array_start_index = try self.addGlobal("__init_array_start", elf_file);
src/link/Elf.zig
@@ -93,7 +93,6 @@ phdr_gnu_stack_index: ?u16 = null,
 /// TODO I think ELF permits multiple TLS segments but for now, assume one per file.
 phdr_tls_index: ?u16 = null,
 
-entry_index: ?Symbol.Index = null,
 page_size: u32,
 default_sym_version: elf.Elf64_Versym,
 
@@ -1277,19 +1276,15 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod
     // Any qualifing unresolved symbol will be upgraded to an absolute, weak
     // symbol for potential resolution at load-time.
     try self.resolveSymbols();
+    if (self.linkerDefinedPtr()) |obj| {
+        try obj.initSymbols(self);
+    }
     self.markEhFrameAtomsDead();
     try self.resolveMergeSections();
 
     try self.convertCommonSymbols();
     self.markImportsExports();
 
-    // Look for entry address in objects if not set by the incremental compiler.
-    if (self.entry_index == null) {
-        if (self.entry_name) |name| {
-            self.entry_index = self.globalByName(name);
-        }
-    }
-
     if (self.base.gc_sections) {
         try gc.gcAtoms(self);
 
@@ -1307,9 +1302,6 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod
     try self.finalizeMergeSections();
     try self.initOutputSections();
     try self.initMergeSections();
-    if (self.linkerDefinedPtr()) |obj| {
-        try obj.initSymbols(self);
-    }
     self.claimUnresolved();
 
     // Scan and create missing synthetic entries such as GOT indirection.
@@ -1385,7 +1377,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod
         else => |e| return e,
     };
 
-    if (self.entry_index == null and self.base.isExe()) {
+    if (self.base.isExe() and self.linkerDefinedPtr().?.entry_index == null) {
         log.debug("flushing. no_entry_point_found = true", .{});
         comp.link_error_flags.no_entry_point_found = true;
     } else {
@@ -2917,10 +2909,10 @@ pub fn writeElfHeader(self: *Elf) !void {
     mem.writeInt(u32, hdr_buf[index..][0..4], 1, endian);
     index += 4;
 
-    const e_entry = if (self.entry_index) |entry_index|
-        @as(u64, @intCast(self.symbol(entry_index).address(.{}, self)))
-    else
-        0;
+    const e_entry: u64 = if (self.linkerDefinedPtr()) |obj| blk: {
+        const entry_index = obj.entry_index orelse break :blk 0;
+        break :blk @intCast(self.symbol(entry_index).address(.{}, self));
+    } else 0;
     const phdr_table_offset = if (self.phdr_table_index) |phndx| self.phdrs.items[phndx].p_offset else 0;
     switch (self.ptr_width) {
         .p32 => {