| author | |
| committer | |
| log | b2e847a41a817a78b5aa3a8f1e0afa5a33ad9194 |
| tree | f248f9cdbc1c5f320d07aa19318e81f9a5fef446 |
| parent | 10d03acdb5ff81c112280854629c9f9032e14330 |
9 files changed, 493 insertions(+), 502 deletions(-)
CMakeLists.txt+1-1| ... | @@ -594,7 +594,7 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -594,7 +594,7 @@ set(ZIG_STAGE2_SOURCES |
| 594 | "${CMAKE_SOURCE_DIR}/src/link/Elf/Object.zig" | 594 | "${CMAKE_SOURCE_DIR}/src/link/Elf/Object.zig" |
| 595 | "${CMAKE_SOURCE_DIR}/src/link/Elf/SharedObject.zig" | 595 | "${CMAKE_SOURCE_DIR}/src/link/Elf/SharedObject.zig" |
| 596 | "${CMAKE_SOURCE_DIR}/src/link/Elf/Symbol.zig" | 596 | "${CMAKE_SOURCE_DIR}/src/link/Elf/Symbol.zig" |
| 597 | "${CMAKE_SOURCE_DIR}/src/link/Elf/ZigModule.zig" | 597 | "${CMAKE_SOURCE_DIR}/src/link/Elf/ZigObject.zig" |
| 598 | "${CMAKE_SOURCE_DIR}/src/link/Elf/eh_frame.zig" | 598 | "${CMAKE_SOURCE_DIR}/src/link/Elf/eh_frame.zig" |
| 599 | "${CMAKE_SOURCE_DIR}/src/link/Elf/file.zig" | 599 | "${CMAKE_SOURCE_DIR}/src/link/Elf/file.zig" |
| 600 | "${CMAKE_SOURCE_DIR}/src/link/Elf/gc.zig" | 600 | "${CMAKE_SOURCE_DIR}/src/link/Elf/gc.zig" |
src/arch/x86_64/Emit.zig+1-1| ... | @@ -86,7 +86,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -86,7 +86,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 86 | }), | 86 | }), |
| 87 | .linker_reloc => |data| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| { | 87 | .linker_reloc => |data| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| { |
| 88 | const atom = elf_file.symbol(data.atom_index).atom(elf_file).?; | 88 | const atom = elf_file.symbol(data.atom_index).atom(elf_file).?; |
| 89 | const sym = elf_file.symbol(elf_file.zigModulePtr().symbol(data.sym_index)); | 89 | const sym = elf_file.symbol(elf_file.zigObjectPtr().?.symbol(data.sym_index)); |
| 90 | if (emit.lower.bin_file.options.pic) { | 90 | if (emit.lower.bin_file.options.pic) { |
| 91 | const r_type: u32 = if (sym.flags.has_zig_got) | 91 | const r_type: u32 = if (sym.flags.has_zig_got) |
| 92 | link.File.Elf.R_X86_64_ZIG_GOTPCREL | 92 | link.File.Elf.R_X86_64_ZIG_GOTPCREL |
src/codegen.zig+1-1| ... | @@ -904,7 +904,7 @@ fn genDeclRef( | ... | @@ -904,7 +904,7 @@ fn genDeclRef( |
| 904 | else | 904 | else |
| 905 | null; | 905 | null; |
| 906 | const sym_index = try elf_file.getGlobalSymbol(name, lib_name); | 906 | const sym_index = try elf_file.getGlobalSymbol(name, lib_name); |
| 907 | elf_file.symbol(elf_file.zigModulePtr().symbol(sym_index)).flags.needs_got = true; | 907 | elf_file.symbol(elf_file.zigObjectPtr().?.symbol(sym_index)).flags.needs_got = true; |
| 908 | return GenResult.mcv(.{ .load_symbol = sym_index }); | 908 | return GenResult.mcv(.{ .load_symbol = sym_index }); |
| 909 | } | 909 | } |
| 910 | const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index); | 910 | const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index); |
src/link/Elf.zig+87-95| ... | @@ -11,7 +11,7 @@ llvm_object: ?*LlvmObject = null, | ... | @@ -11,7 +11,7 @@ llvm_object: ?*LlvmObject = null, |
| 11 | /// Index of each input file also encodes the priority or precedence of one input file | 11 | /// Index of each input file also encodes the priority or precedence of one input file |
| 12 | /// over another. | 12 | /// over another. |
| 13 | files: std.MultiArrayList(File.Entry) = .{}, | 13 | files: std.MultiArrayList(File.Entry) = .{}, |
| 14 | zig_module_index: ?File.Index = null, | 14 | zig_object_index: ?File.Index = null, |
| 15 | linker_defined_index: ?File.Index = null, | 15 | linker_defined_index: ?File.Index = null, |
| 16 | objects: std.ArrayListUnmanaged(File.Index) = .{}, | 16 | objects: std.ArrayListUnmanaged(File.Index) = .{}, |
| 17 | shared_objects: std.ArrayListUnmanaged(File.Index) = .{}, | 17 | shared_objects: std.ArrayListUnmanaged(File.Index) = .{}, |
| ... | @@ -327,24 +327,24 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option | ... | @@ -327,24 +327,24 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | const index = @as(File.Index, @intCast(try self.files.addOne(allocator))); | 329 | const index = @as(File.Index, @intCast(try self.files.addOne(allocator))); |
| 330 | self.files.set(index, .{ .zig_module = .{ | 330 | self.files.set(index, .{ .zig_object = .{ |
| 331 | .index = index, | 331 | .index = index, |
| 332 | .path = options.module.?.main_mod.root_src_path, | 332 | .path = options.module.?.main_mod.root_src_path, |
| 333 | } }); | 333 | } }); |
| 334 | self.zig_module_index = index; | 334 | self.zig_object_index = index; |
| 335 | const zig_module = self.file(index).?.zig_module; | 335 | const zig_object = self.zigObjectPtr().?; |
| 336 | 336 | ||
| 337 | try zig_module.atoms.append(allocator, 0); // null input section | 337 | try zig_object.atoms.append(allocator, 0); // null input section |
| 338 | 338 | ||
| 339 | const name_off = try self.strtab.insert(allocator, std.fs.path.stem(options.module.?.main_mod.root_src_path)); | 339 | const name_off = try self.strtab.insert(allocator, std.fs.path.stem(options.module.?.main_mod.root_src_path)); |
| 340 | const symbol_index = try self.addSymbol(); | 340 | const symbol_index = try self.addSymbol(); |
| 341 | try zig_module.local_symbols.append(allocator, symbol_index); | 341 | try zig_object.local_symbols.append(allocator, symbol_index); |
| 342 | const symbol_ptr = self.symbol(symbol_index); | 342 | const symbol_ptr = self.symbol(symbol_index); |
| 343 | symbol_ptr.file_index = zig_module.index; | 343 | symbol_ptr.file_index = zig_object.index; |
| 344 | symbol_ptr.name_offset = name_off; | 344 | symbol_ptr.name_offset = name_off; |
| 345 | 345 | ||
| 346 | const esym_index = try zig_module.addLocalEsym(allocator); | 346 | const esym_index = try zig_object.addLocalEsym(allocator); |
| 347 | const esym = &zig_module.local_esyms.items(.elf_sym)[esym_index]; | 347 | const esym = &zig_object.local_esyms.items(.elf_sym)[esym_index]; |
| 348 | esym.st_name = name_off; | 348 | esym.st_name = name_off; |
| 349 | esym.st_info |= elf.STT_FILE; | 349 | esym.st_info |= elf.STT_FILE; |
| 350 | esym.st_shndx = elf.SHN_ABS; | 350 | esym.st_shndx = elf.SHN_ABS; |
| ... | @@ -401,7 +401,7 @@ pub fn deinit(self: *Elf) void { | ... | @@ -401,7 +401,7 @@ pub fn deinit(self: *Elf) void { |
| 401 | 401 | ||
| 402 | for (self.files.items(.tags), self.files.items(.data)) |tag, *data| switch (tag) { | 402 | for (self.files.items(.tags), self.files.items(.data)) |tag, *data| switch (tag) { |
| 403 | .null => {}, | 403 | .null => {}, |
| 404 | .zig_module => data.zig_module.deinit(gpa), | 404 | .zig_object => data.zig_object.deinit(gpa), |
| 405 | .linker_defined => data.linker_defined.deinit(gpa), | 405 | .linker_defined => data.linker_defined.deinit(gpa), |
| 406 | .object => data.object.deinit(gpa), | 406 | .object => data.object.deinit(gpa), |
| 407 | .shared_object => data.shared_object.deinit(gpa), | 407 | .shared_object => data.shared_object.deinit(gpa), |
| ... | @@ -726,7 +726,7 @@ fn allocateNonAllocSection(self: *Elf, opts: AllocateNonAllocSectionOpts) error{ | ... | @@ -726,7 +726,7 @@ fn allocateNonAllocSection(self: *Elf, opts: AllocateNonAllocSectionOpts) error{ |
| 726 | return index; | 726 | return index; |
| 727 | } | 727 | } |
| 728 | 728 | ||
| 729 | /// TODO move to ZigModule | 729 | /// TODO move to ZigObject |
| 730 | pub fn initMetadata(self: *Elf) !void { | 730 | pub fn initMetadata(self: *Elf) !void { |
| 731 | const gpa = self.base.allocator; | 731 | const gpa = self.base.allocator; |
| 732 | const ptr_size = self.ptrWidthBytes(); | 732 | const ptr_size = self.ptrWidthBytes(); |
| ... | @@ -1041,7 +1041,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1041,7 +1041,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1041 | } else null; | 1041 | } else null; |
| 1042 | const gc_sections = self.base.options.gc_sections orelse false; | 1042 | const gc_sections = self.base.options.gc_sections orelse false; |
| 1043 | 1043 | ||
| 1044 | if (self.base.options.output_mode == .Obj and self.zig_module_index == null) { | 1044 | if (self.base.options.output_mode == .Obj and self.zig_object_index == null) { |
| 1045 | // TODO this will become -r route I guess. For now, just copy the object file. | 1045 | // TODO this will become -r route I guess. For now, just copy the object file. |
| 1046 | assert(self.base.file == null); // TODO uncomment once we implement -r | 1046 | assert(self.base.file == null); // TODO uncomment once we implement -r |
| 1047 | const the_object_path = blk: { | 1047 | const the_object_path = blk: { |
| ... | @@ -1543,7 +1543,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1543,7 +1543,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1543 | } | 1543 | } |
| 1544 | 1544 | ||
| 1545 | // Now, we are ready to resolve the symbols across all input files. | 1545 | // Now, we are ready to resolve the symbols across all input files. |
| 1546 | // We will first resolve the files in the ZigModule, next in the parsed | 1546 | // We will first resolve the files in the ZigObject, next in the parsed |
| 1547 | // input Object files. | 1547 | // input Object files. |
| 1548 | // Any qualifing unresolved symbol will be upgraded to an absolute, weak | 1548 | // Any qualifing unresolved symbol will be upgraded to an absolute, weak |
| 1549 | // symbol for potential resolution at load-time. | 1549 | // symbol for potential resolution at load-time. |
| ... | @@ -1576,7 +1576,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1576,7 +1576,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1576 | // Scan and create missing synthetic entries such as GOT indirection. | 1576 | // Scan and create missing synthetic entries such as GOT indirection. |
| 1577 | try self.scanRelocs(); | 1577 | try self.scanRelocs(); |
| 1578 | 1578 | ||
| 1579 | // TODO I need to re-think how to handle ZigModule's debug sections AND debug sections | 1579 | // TODO I need to re-think how to handle ZigObject's debug sections AND debug sections |
| 1580 | // extracted from input object files correctly. | 1580 | // extracted from input object files correctly. |
| 1581 | if (self.dwarf) |*dw| { | 1581 | if (self.dwarf) |*dw| { |
| 1582 | if (self.debug_abbrev_section_dirty) { | 1582 | if (self.debug_abbrev_section_dirty) { |
| ... | @@ -1645,15 +1645,14 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1645,15 +1645,14 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1645 | 1645 | ||
| 1646 | // Beyond this point, everything has been allocated a virtual address and we can resolve | 1646 | // Beyond this point, everything has been allocated a virtual address and we can resolve |
| 1647 | // the relocations, and commit objects to file. | 1647 | // the relocations, and commit objects to file. |
| 1648 | if (self.zig_module_index) |index| { | 1648 | if (self.zigObjectPtr()) |zig_object| { |
| 1649 | const zig_module = self.file(index).?.zig_module; | 1649 | for (zig_object.atoms.items) |atom_index| { |
| 1650 | for (zig_module.atoms.items) |atom_index| { | ||
| 1651 | const atom_ptr = self.atom(atom_index) orelse continue; | 1650 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 1652 | if (!atom_ptr.flags.alive) continue; | 1651 | if (!atom_ptr.flags.alive) continue; |
| 1653 | const out_shndx = atom_ptr.outputShndx() orelse continue; | 1652 | const out_shndx = atom_ptr.outputShndx() orelse continue; |
| 1654 | const shdr = &self.shdrs.items[out_shndx]; | 1653 | const shdr = &self.shdrs.items[out_shndx]; |
| 1655 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | 1654 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 1656 | const code = try zig_module.codeAlloc(self, atom_index); | 1655 | const code = try zig_object.codeAlloc(self, atom_index); |
| 1657 | defer gpa.free(code); | 1656 | defer gpa.free(code); |
| 1658 | const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr; | 1657 | const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr; |
| 1659 | atom_ptr.resolveRelocsAlloc(self, code) catch |err| switch (err) { | 1658 | atom_ptr.resolveRelocsAlloc(self, code) catch |err| switch (err) { |
| ... | @@ -1926,8 +1925,8 @@ fn accessLibPath( | ... | @@ -1926,8 +1925,8 @@ fn accessLibPath( |
| 1926 | /// 5. Remove references to dead objects/shared objects | 1925 | /// 5. Remove references to dead objects/shared objects |
| 1927 | /// 6. Re-run symbol resolution on pruned objects and shared objects sets. | 1926 | /// 6. Re-run symbol resolution on pruned objects and shared objects sets. |
| 1928 | fn resolveSymbols(self: *Elf) void { | 1927 | fn resolveSymbols(self: *Elf) void { |
| 1929 | // Resolve symbols in the ZigModule. For now, we assume that it's always live. | 1928 | // Resolve symbols in the ZigObject. For now, we assume that it's always live. |
| 1930 | if (self.zig_module_index) |index| self.file(index).?.resolveSymbols(self); | 1929 | if (self.zigObjectPtr()) |zig_object| zig_object.resolveSymbols(self); |
| 1931 | // Resolve symbols on the set of all objects and shared objects (even if some are unneeded). | 1930 | // Resolve symbols on the set of all objects and shared objects (even if some are unneeded). |
| 1932 | for (self.objects.items) |index| self.file(index).?.resolveSymbols(self); | 1931 | for (self.objects.items) |index| self.file(index).?.resolveSymbols(self); |
| 1933 | for (self.shared_objects.items) |index| self.file(index).?.resolveSymbols(self); | 1932 | for (self.shared_objects.items) |index| self.file(index).?.resolveSymbols(self); |
| ... | @@ -1936,7 +1935,7 @@ fn resolveSymbols(self: *Elf) void { | ... | @@ -1936,7 +1935,7 @@ fn resolveSymbols(self: *Elf) void { |
| 1936 | self.markLive(); | 1935 | self.markLive(); |
| 1937 | 1936 | ||
| 1938 | // Reset state of all globals after marking live objects. | 1937 | // Reset state of all globals after marking live objects. |
| 1939 | if (self.zig_module_index) |index| self.file(index).?.resetGlobals(self); | 1938 | if (self.zigObjectPtr()) |zig_object| zig_object.resetGlobals(self); |
| 1940 | for (self.objects.items) |index| self.file(index).?.resetGlobals(self); | 1939 | for (self.objects.items) |index| self.file(index).?.resetGlobals(self); |
| 1941 | for (self.shared_objects.items) |index| self.file(index).?.resetGlobals(self); | 1940 | for (self.shared_objects.items) |index| self.file(index).?.resetGlobals(self); |
| 1942 | 1941 | ||
| ... | @@ -1988,7 +1987,7 @@ fn resolveSymbols(self: *Elf) void { | ... | @@ -1988,7 +1987,7 @@ fn resolveSymbols(self: *Elf) void { |
| 1988 | } | 1987 | } |
| 1989 | 1988 | ||
| 1990 | // Re-resolve the symbols. | 1989 | // Re-resolve the symbols. |
| 1991 | if (self.zig_module_index) |index| self.file(index).?.resolveSymbols(self); | 1990 | if (self.zigObjectPtr()) |zig_object| zig_object.resolveSymbols(self); |
| 1992 | for (self.objects.items) |index| self.file(index).?.resolveSymbols(self); | 1991 | for (self.objects.items) |index| self.file(index).?.resolveSymbols(self); |
| 1993 | for (self.shared_objects.items) |index| self.file(index).?.resolveSymbols(self); | 1992 | for (self.shared_objects.items) |index| self.file(index).?.resolveSymbols(self); |
| 1994 | } | 1993 | } |
| ... | @@ -1998,7 +1997,7 @@ fn resolveSymbols(self: *Elf) void { | ... | @@ -1998,7 +1997,7 @@ fn resolveSymbols(self: *Elf) void { |
| 1998 | /// This routine will prune unneeded objects extracted from archives and | 1997 | /// This routine will prune unneeded objects extracted from archives and |
| 1999 | /// unneeded shared objects. | 1998 | /// unneeded shared objects. |
| 2000 | fn markLive(self: *Elf) void { | 1999 | fn markLive(self: *Elf) void { |
| 2001 | if (self.zig_module_index) |index| self.file(index).?.markLive(self); | 2000 | if (self.zigObjectPtr()) |zig_object| zig_object.markLive(self); |
| 2002 | for (self.objects.items) |index| { | 2001 | for (self.objects.items) |index| { |
| 2003 | const file_ptr = self.file(index).?; | 2002 | const file_ptr = self.file(index).?; |
| 2004 | if (file_ptr.isAlive()) file_ptr.markLive(self); | 2003 | if (file_ptr.isAlive()) file_ptr.markLive(self); |
| ... | @@ -2057,7 +2056,7 @@ fn markImportsExports(self: *Elf) void { | ... | @@ -2057,7 +2056,7 @@ fn markImportsExports(self: *Elf) void { |
| 2057 | } | 2056 | } |
| 2058 | } | 2057 | } |
| 2059 | 2058 | ||
| 2060 | if (self.zig_module_index) |index| { | 2059 | if (self.zig_object_index) |index| { |
| 2061 | mark(self, index); | 2060 | mark(self, index); |
| 2062 | } | 2061 | } |
| 2063 | 2062 | ||
| ... | @@ -2067,9 +2066,8 @@ fn markImportsExports(self: *Elf) void { | ... | @@ -2067,9 +2066,8 @@ fn markImportsExports(self: *Elf) void { |
| 2067 | } | 2066 | } |
| 2068 | 2067 | ||
| 2069 | fn claimUnresolved(self: *Elf) void { | 2068 | fn claimUnresolved(self: *Elf) void { |
| 2070 | if (self.zig_module_index) |index| { | 2069 | if (self.zigObjectPtr()) |zig_object| { |
| 2071 | const zig_module = self.file(index).?.zig_module; | 2070 | zig_object.claimUnresolved(self); |
| 2072 | zig_module.claimUnresolved(self); | ||
| 2073 | } | 2071 | } |
| 2074 | for (self.objects.items) |index| { | 2072 | for (self.objects.items) |index| { |
| 2075 | const object = self.file(index).?.object; | 2073 | const object = self.file(index).?.object; |
| ... | @@ -2093,9 +2091,8 @@ fn scanRelocs(self: *Elf) !void { | ... | @@ -2093,9 +2091,8 @@ fn scanRelocs(self: *Elf) !void { |
| 2093 | undefs.deinit(); | 2091 | undefs.deinit(); |
| 2094 | } | 2092 | } |
| 2095 | 2093 | ||
| 2096 | if (self.zig_module_index) |index| { | 2094 | if (self.zigObjectPtr()) |zig_object| { |
| 2097 | const zig_module = self.file(index).?.zig_module; | 2095 | try zig_object.scanRelocs(self, &undefs); |
| 2098 | try zig_module.scanRelocs(self, &undefs); | ||
| 2099 | } | 2096 | } |
| 2100 | for (self.objects.items) |index| { | 2097 | for (self.objects.items) |index| { |
| 2101 | const object = self.file(index).?.object; | 2098 | const object = self.file(index).?.object; |
| ... | @@ -3114,9 +3111,9 @@ pub fn getOrCreateMetadataForLazySymbol(self: *Elf, lazy_sym: link.File.LazySymb | ... | @@ -3114,9 +3111,9 @@ pub fn getOrCreateMetadataForLazySymbol(self: *Elf, lazy_sym: link.File.LazySymb |
| 3114 | .state = &gop.value_ptr.rodata_state, | 3111 | .state = &gop.value_ptr.rodata_state, |
| 3115 | }, | 3112 | }, |
| 3116 | }; | 3113 | }; |
| 3117 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; | 3114 | const zig_object = self.zigObjectPtr().?; |
| 3118 | switch (metadata.state.*) { | 3115 | switch (metadata.state.*) { |
| 3119 | .unused => metadata.symbol_index.* = try zig_module.addAtom(self), | 3116 | .unused => metadata.symbol_index.* = try zig_object.addAtom(self), |
| 3120 | .pending_flush => return metadata.symbol_index.*, | 3117 | .pending_flush => return metadata.symbol_index.*, |
| 3121 | .flushed => {}, | 3118 | .flushed => {}, |
| 3122 | } | 3119 | } |
| ... | @@ -3130,8 +3127,8 @@ pub fn getOrCreateMetadataForLazySymbol(self: *Elf, lazy_sym: link.File.LazySymb | ... | @@ -3130,8 +3127,8 @@ pub fn getOrCreateMetadataForLazySymbol(self: *Elf, lazy_sym: link.File.LazySymb |
| 3130 | pub fn getOrCreateMetadataForDecl(self: *Elf, decl_index: Module.Decl.Index) !Symbol.Index { | 3127 | pub fn getOrCreateMetadataForDecl(self: *Elf, decl_index: Module.Decl.Index) !Symbol.Index { |
| 3131 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); | 3128 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); |
| 3132 | if (!gop.found_existing) { | 3129 | if (!gop.found_existing) { |
| 3133 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; | 3130 | const zig_object = self.zigObjectPtr().?; |
| 3134 | gop.value_ptr.* = .{ .symbol_index = try zig_module.addAtom(self) }; | 3131 | gop.value_ptr.* = .{ .symbol_index = try zig_object.addAtom(self) }; |
| 3135 | } | 3132 | } |
| 3136 | return gop.value_ptr.symbol_index; | 3133 | return gop.value_ptr.symbol_index; |
| 3137 | } | 3134 | } |
| ... | @@ -3173,7 +3170,7 @@ fn updateDeclCode( | ... | @@ -3173,7 +3170,7 @@ fn updateDeclCode( |
| 3173 | ) !void { | 3170 | ) !void { |
| 3174 | const gpa = self.base.allocator; | 3171 | const gpa = self.base.allocator; |
| 3175 | const mod = self.base.options.module.?; | 3172 | const mod = self.base.options.module.?; |
| 3176 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; | 3173 | const zig_object = self.zigObjectPtr().?; |
| 3177 | const decl = mod.declPtr(decl_index); | 3174 | const decl = mod.declPtr(decl_index); |
| 3178 | 3175 | ||
| 3179 | const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)); | 3176 | const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)); |
| ... | @@ -3182,7 +3179,7 @@ fn updateDeclCode( | ... | @@ -3182,7 +3179,7 @@ fn updateDeclCode( |
| 3182 | const required_alignment = decl.getAlignment(mod); | 3179 | const required_alignment = decl.getAlignment(mod); |
| 3183 | 3180 | ||
| 3184 | const sym = self.symbol(sym_index); | 3181 | const sym = self.symbol(sym_index); |
| 3185 | const esym = &zig_module.local_esyms.items(.elf_sym)[sym.esym_index]; | 3182 | const esym = &zig_object.local_esyms.items(.elf_sym)[sym.esym_index]; |
| 3186 | const atom_ptr = sym.atom(self).?; | 3183 | const atom_ptr = sym.atom(self).?; |
| 3187 | 3184 | ||
| 3188 | const shdr_index = self.getDeclShdrIndex(decl_index, code); | 3185 | const shdr_index = self.getDeclShdrIndex(decl_index, code); |
| ... | @@ -3340,7 +3337,7 @@ pub fn updateDecl( | ... | @@ -3340,7 +3337,7 @@ pub fn updateDecl( |
| 3340 | const name = mod.intern_pool.stringToSlice(decl.name); | 3337 | const name = mod.intern_pool.stringToSlice(decl.name); |
| 3341 | const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name); | 3338 | const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name); |
| 3342 | const esym_index = try self.getGlobalSymbol(name, lib_name); | 3339 | const esym_index = try self.getGlobalSymbol(name, lib_name); |
| 3343 | self.symbol(self.zigModulePtr().symbol(esym_index)).flags.needs_got = true; | 3340 | self.symbol(self.zigObjectPtr().?.symbol(esym_index)).flags.needs_got = true; |
| 3344 | return; | 3341 | return; |
| 3345 | } | 3342 | } |
| 3346 | 3343 | ||
| ... | @@ -3401,7 +3398,7 @@ pub fn updateDecl( | ... | @@ -3401,7 +3398,7 @@ pub fn updateDecl( |
| 3401 | fn updateLazySymbol(self: *Elf, sym: link.File.LazySymbol, symbol_index: Symbol.Index) !void { | 3398 | fn updateLazySymbol(self: *Elf, sym: link.File.LazySymbol, symbol_index: Symbol.Index) !void { |
| 3402 | const gpa = self.base.allocator; | 3399 | const gpa = self.base.allocator; |
| 3403 | const mod = self.base.options.module.?; | 3400 | const mod = self.base.options.module.?; |
| 3404 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; | 3401 | const zig_object = self.zigObjectPtr().?; |
| 3405 | 3402 | ||
| 3406 | var required_alignment: InternPool.Alignment = .none; | 3403 | var required_alignment: InternPool.Alignment = .none; |
| 3407 | var code_buffer = std.ArrayList(u8).init(gpa); | 3404 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | @@ -3449,7 +3446,7 @@ fn updateLazySymbol(self: *Elf, sym: link.File.LazySymbol, symbol_index: Symbol. | ... | @@ -3449,7 +3446,7 @@ fn updateLazySymbol(self: *Elf, sym: link.File.LazySymbol, symbol_index: Symbol. |
| 3449 | const phdr_index = self.phdr_to_shdr_table.get(output_section_index).?; | 3446 | const phdr_index = self.phdr_to_shdr_table.get(output_section_index).?; |
| 3450 | local_sym.name_offset = name_str_index; | 3447 | local_sym.name_offset = name_str_index; |
| 3451 | local_sym.output_section_index = output_section_index; | 3448 | local_sym.output_section_index = output_section_index; |
| 3452 | const local_esym = &zig_module.local_esyms.items(.elf_sym)[local_sym.esym_index]; | 3449 | const local_esym = &zig_object.local_esyms.items(.elf_sym)[local_sym.esym_index]; |
| 3453 | local_esym.st_name = name_str_index; | 3450 | local_esym.st_name = name_str_index; |
| 3454 | local_esym.st_info |= elf.STT_OBJECT; | 3451 | local_esym.st_info |= elf.STT_OBJECT; |
| 3455 | local_esym.st_size = code.len; | 3452 | local_esym.st_size = code.len; |
| ... | @@ -3519,8 +3516,8 @@ fn lowerConst( | ... | @@ -3519,8 +3516,8 @@ fn lowerConst( |
| 3519 | var code_buffer = std.ArrayList(u8).init(gpa); | 3516 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 3520 | defer code_buffer.deinit(); | 3517 | defer code_buffer.deinit(); |
| 3521 | 3518 | ||
| 3522 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; | 3519 | const zig_object = self.zigObjectPtr().?; |
| 3523 | const sym_index = try zig_module.addAtom(self); | 3520 | const sym_index = try zig_object.addAtom(self); |
| 3524 | 3521 | ||
| 3525 | const res = try codegen.generateSymbol(&self.base, src_loc, tv, &code_buffer, .{ | 3522 | const res = try codegen.generateSymbol(&self.base, src_loc, tv, &code_buffer, .{ |
| 3526 | .none = {}, | 3523 | .none = {}, |
| ... | @@ -3537,7 +3534,7 @@ fn lowerConst( | ... | @@ -3537,7 +3534,7 @@ fn lowerConst( |
| 3537 | const name_str_index = try self.strtab.insert(gpa, name); | 3534 | const name_str_index = try self.strtab.insert(gpa, name); |
| 3538 | local_sym.name_offset = name_str_index; | 3535 | local_sym.name_offset = name_str_index; |
| 3539 | local_sym.output_section_index = output_section_index; | 3536 | local_sym.output_section_index = output_section_index; |
| 3540 | const local_esym = &zig_module.local_esyms.items(.elf_sym)[local_sym.esym_index]; | 3537 | const local_esym = &zig_object.local_esyms.items(.elf_sym)[local_sym.esym_index]; |
| 3541 | local_esym.st_name = name_str_index; | 3538 | local_esym.st_name = name_str_index; |
| 3542 | local_esym.st_info |= elf.STT_OBJECT; | 3539 | local_esym.st_info |= elf.STT_OBJECT; |
| 3543 | local_esym.st_size = code.len; | 3540 | local_esym.st_size = code.len; |
| ... | @@ -3579,7 +3576,7 @@ pub fn updateExports( | ... | @@ -3579,7 +3576,7 @@ pub fn updateExports( |
| 3579 | defer tracy.end(); | 3576 | defer tracy.end(); |
| 3580 | 3577 | ||
| 3581 | const gpa = self.base.allocator; | 3578 | const gpa = self.base.allocator; |
| 3582 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; | 3579 | const zig_object = self.zigObjectPtr().?; |
| 3583 | const metadata = switch (exported) { | 3580 | const metadata = switch (exported) { |
| 3584 | .decl_index => |decl_index| blk: { | 3581 | .decl_index => |decl_index| blk: { |
| 3585 | _ = try self.getOrCreateMetadataForDecl(decl_index); | 3582 | _ = try self.getOrCreateMetadataForDecl(decl_index); |
| ... | @@ -3603,8 +3600,8 @@ pub fn updateExports( | ... | @@ -3603,8 +3600,8 @@ pub fn updateExports( |
| 3603 | }; | 3600 | }; |
| 3604 | const sym_index = metadata.symbol_index; | 3601 | const sym_index = metadata.symbol_index; |
| 3605 | const esym_index = self.symbol(sym_index).esym_index; | 3602 | const esym_index = self.symbol(sym_index).esym_index; |
| 3606 | const esym = zig_module.local_esyms.items(.elf_sym)[esym_index]; | 3603 | const esym = zig_object.local_esyms.items(.elf_sym)[esym_index]; |
| 3607 | const esym_shndx = zig_module.local_esyms.items(.shndx)[esym_index]; | 3604 | const esym_shndx = zig_object.local_esyms.items(.shndx)[esym_index]; |
| 3608 | 3605 | ||
| 3609 | for (exports) |exp| { | 3606 | for (exports) |exp| { |
| 3610 | if (exp.opts.section.unwrap()) |section_name| { | 3607 | if (exp.opts.section.unwrap()) |section_name| { |
| ... | @@ -3638,24 +3635,24 @@ pub fn updateExports( | ... | @@ -3638,24 +3635,24 @@ pub fn updateExports( |
| 3638 | const exp_name = mod.intern_pool.stringToSlice(exp.opts.name); | 3635 | const exp_name = mod.intern_pool.stringToSlice(exp.opts.name); |
| 3639 | const name_off = try self.strtab.insert(gpa, exp_name); | 3636 | const name_off = try self.strtab.insert(gpa, exp_name); |
| 3640 | const global_esym_index = if (metadata.@"export"(self, exp_name)) |exp_index| exp_index.* else blk: { | 3637 | const global_esym_index = if (metadata.@"export"(self, exp_name)) |exp_index| exp_index.* else blk: { |
| 3641 | const global_esym_index = try zig_module.addGlobalEsym(gpa); | 3638 | const global_esym_index = try zig_object.addGlobalEsym(gpa); |
| 3642 | const lookup_gop = try zig_module.globals_lookup.getOrPut(gpa, name_off); | 3639 | const lookup_gop = try zig_object.globals_lookup.getOrPut(gpa, name_off); |
| 3643 | const global_esym = zig_module.elfSym(global_esym_index); | 3640 | const global_esym = zig_object.elfSym(global_esym_index); |
| 3644 | global_esym.st_name = name_off; | 3641 | global_esym.st_name = name_off; |
| 3645 | lookup_gop.value_ptr.* = global_esym_index; | 3642 | lookup_gop.value_ptr.* = global_esym_index; |
| 3646 | try metadata.exports.append(gpa, global_esym_index); | 3643 | try metadata.exports.append(gpa, global_esym_index); |
| 3647 | const gop = try self.getOrPutGlobal(name_off); | 3644 | const gop = try self.getOrPutGlobal(name_off); |
| 3648 | try zig_module.global_symbols.append(gpa, gop.index); | 3645 | try zig_object.global_symbols.append(gpa, gop.index); |
| 3649 | break :blk global_esym_index; | 3646 | break :blk global_esym_index; |
| 3650 | }; | 3647 | }; |
| 3651 | 3648 | ||
| 3652 | const actual_esym_index = global_esym_index & ZigModule.symbol_mask; | 3649 | const actual_esym_index = global_esym_index & ZigObject.symbol_mask; |
| 3653 | const global_esym = &zig_module.global_esyms.items(.elf_sym)[actual_esym_index]; | 3650 | const global_esym = &zig_object.global_esyms.items(.elf_sym)[actual_esym_index]; |
| 3654 | global_esym.st_value = self.symbol(sym_index).value; | 3651 | global_esym.st_value = self.symbol(sym_index).value; |
| 3655 | global_esym.st_shndx = esym.st_shndx; | 3652 | global_esym.st_shndx = esym.st_shndx; |
| 3656 | global_esym.st_info = (stb_bits << 4) | stt_bits; | 3653 | global_esym.st_info = (stb_bits << 4) | stt_bits; |
| 3657 | global_esym.st_name = name_off; | 3654 | global_esym.st_name = name_off; |
| 3658 | zig_module.global_esyms.items(.shndx)[actual_esym_index] = esym_shndx; | 3655 | zig_object.global_esyms.items(.shndx)[actual_esym_index] = esym_shndx; |
| 3659 | } | 3656 | } |
| 3660 | } | 3657 | } |
| 3661 | 3658 | ||
| ... | @@ -3683,20 +3680,20 @@ pub fn deleteDeclExport( | ... | @@ -3683,20 +3680,20 @@ pub fn deleteDeclExport( |
| 3683 | if (self.llvm_object) |_| return; | 3680 | if (self.llvm_object) |_| return; |
| 3684 | const metadata = self.decls.getPtr(decl_index) orelse return; | 3681 | const metadata = self.decls.getPtr(decl_index) orelse return; |
| 3685 | const mod = self.base.options.module.?; | 3682 | const mod = self.base.options.module.?; |
| 3686 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; | 3683 | const zig_object = self.zigObjectPtr().?; |
| 3687 | const exp_name = mod.intern_pool.stringToSlice(name); | 3684 | const exp_name = mod.intern_pool.stringToSlice(name); |
| 3688 | const esym_index = metadata.@"export"(self, exp_name) orelse return; | 3685 | const esym_index = metadata.@"export"(self, exp_name) orelse return; |
| 3689 | log.debug("deleting export '{s}'", .{exp_name}); | 3686 | log.debug("deleting export '{s}'", .{exp_name}); |
| 3690 | const esym = &zig_module.global_esyms.items(.elf_sym)[esym_index.*]; | 3687 | const esym = &zig_object.global_esyms.items(.elf_sym)[esym_index.*]; |
| 3691 | _ = zig_module.globals_lookup.remove(esym.st_name); | 3688 | _ = zig_object.globals_lookup.remove(esym.st_name); |
| 3692 | const sym_index = self.resolver.get(esym.st_name).?; | 3689 | const sym_index = self.resolver.get(esym.st_name).?; |
| 3693 | const sym = self.symbol(sym_index); | 3690 | const sym = self.symbol(sym_index); |
| 3694 | if (sym.file_index == zig_module.index) { | 3691 | if (sym.file_index == zig_object.index) { |
| 3695 | _ = self.resolver.swapRemove(esym.st_name); | 3692 | _ = self.resolver.swapRemove(esym.st_name); |
| 3696 | sym.* = .{}; | 3693 | sym.* = .{}; |
| 3697 | } | 3694 | } |
| 3698 | esym.* = null_sym; | 3695 | esym.* = null_sym; |
| 3699 | zig_module.global_esyms.items(.shndx)[esym_index.*] = elf.SHN_UNDEF; | 3696 | zig_object.global_esyms.items(.shndx)[esym_index.*] = elf.SHN_UNDEF; |
| 3700 | } | 3697 | } |
| 3701 | 3698 | ||
| 3702 | fn addLinkerDefinedSymbols(self: *Elf) !void { | 3699 | fn addLinkerDefinedSymbols(self: *Elf) !void { |
| ... | @@ -3917,8 +3914,8 @@ fn initSections(self: *Elf) !void { | ... | @@ -3917,8 +3914,8 @@ fn initSections(self: *Elf) !void { |
| 3917 | const needs_rela_dyn = blk: { | 3914 | const needs_rela_dyn = blk: { |
| 3918 | if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or | 3915 | if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or |
| 3919 | self.zig_got.flags.needs_rela or self.copy_rel.symbols.items.len > 0) break :blk true; | 3916 | self.zig_got.flags.needs_rela or self.copy_rel.symbols.items.len > 0) break :blk true; |
| 3920 | if (self.zig_module_index) |index| { | 3917 | if (self.zigObjectPtr()) |zig_object| { |
| 3921 | if (self.file(index).?.zig_module.num_dynrelocs > 0) break :blk true; | 3918 | if (zig_object.num_dynrelocs > 0) break :blk true; |
| 3922 | } | 3919 | } |
| 3923 | for (self.objects.items) |index| { | 3920 | for (self.objects.items) |index| { |
| 3924 | if (self.file(index).?.object.num_dynrelocs > 0) break :blk true; | 3921 | if (self.file(index).?.object.num_dynrelocs > 0) break :blk true; |
| ... | @@ -4512,16 +4509,15 @@ fn sortShdrs(self: *Elf) !void { | ... | @@ -4512,16 +4509,15 @@ fn sortShdrs(self: *Elf) !void { |
| 4512 | } | 4509 | } |
| 4513 | } | 4510 | } |
| 4514 | 4511 | ||
| 4515 | if (self.zig_module_index) |index| { | 4512 | if (self.zigObjectPtr()) |zig_object| { |
| 4516 | const zig_module = self.file(index).?.zig_module; | 4513 | for (zig_object.atoms.items) |atom_index| { |
| 4517 | for (zig_module.atoms.items) |atom_index| { | ||
| 4518 | const atom_ptr = self.atom(atom_index) orelse continue; | 4514 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 4519 | if (!atom_ptr.flags.alive) continue; | 4515 | if (!atom_ptr.flags.alive) continue; |
| 4520 | const out_shndx = atom_ptr.outputShndx() orelse continue; | 4516 | const out_shndx = atom_ptr.outputShndx() orelse continue; |
| 4521 | atom_ptr.output_section_index = backlinks[out_shndx]; | 4517 | atom_ptr.output_section_index = backlinks[out_shndx]; |
| 4522 | } | 4518 | } |
| 4523 | 4519 | ||
| 4524 | for (zig_module.locals()) |local_index| { | 4520 | for (zig_object.locals()) |local_index| { |
| 4525 | const local = self.symbol(local_index); | 4521 | const local = self.symbol(local_index); |
| 4526 | const atom_ptr = local.atom(self) orelse continue; | 4522 | const atom_ptr = local.atom(self) orelse continue; |
| 4527 | if (!atom_ptr.flags.alive) continue; | 4523 | if (!atom_ptr.flags.alive) continue; |
| ... | @@ -4529,11 +4525,11 @@ fn sortShdrs(self: *Elf) !void { | ... | @@ -4529,11 +4525,11 @@ fn sortShdrs(self: *Elf) !void { |
| 4529 | local.output_section_index = backlinks[out_shndx]; | 4525 | local.output_section_index = backlinks[out_shndx]; |
| 4530 | } | 4526 | } |
| 4531 | 4527 | ||
| 4532 | for (zig_module.globals()) |global_index| { | 4528 | for (zig_object.globals()) |global_index| { |
| 4533 | const global = self.symbol(global_index); | 4529 | const global = self.symbol(global_index); |
| 4534 | const atom_ptr = global.atom(self) orelse continue; | 4530 | const atom_ptr = global.atom(self) orelse continue; |
| 4535 | if (!atom_ptr.flags.alive) continue; | 4531 | if (!atom_ptr.flags.alive) continue; |
| 4536 | if (global.file(self).?.index() != index) continue; | 4532 | if (global.file(self).?.index() != zig_object.index) continue; |
| 4537 | const out_shndx = global.outputShndx() orelse continue; | 4533 | const out_shndx = global.outputShndx() orelse continue; |
| 4538 | global.output_section_index = backlinks[out_shndx]; | 4534 | global.output_section_index = backlinks[out_shndx]; |
| 4539 | } | 4535 | } |
| ... | @@ -4599,8 +4595,8 @@ fn updateSectionSizes(self: *Elf) !void { | ... | @@ -4599,8 +4595,8 @@ fn updateSectionSizes(self: *Elf) !void { |
| 4599 | 4595 | ||
| 4600 | if (self.rela_dyn_section_index) |shndx| { | 4596 | if (self.rela_dyn_section_index) |shndx| { |
| 4601 | var num = self.got.numRela(self) + self.copy_rel.numRela() + self.zig_got.numRela(); | 4597 | var num = self.got.numRela(self) + self.copy_rel.numRela() + self.zig_got.numRela(); |
| 4602 | if (self.zig_module_index) |index| { | 4598 | if (self.zigObjectPtr()) |zig_object| { |
| 4603 | num += self.file(index).?.zig_module.num_dynrelocs; | 4599 | num += zig_object.num_dynrelocs; |
| 4604 | } | 4600 | } |
| 4605 | for (self.objects.items) |index| { | 4601 | for (self.objects.items) |index| { |
| 4606 | num += self.file(index).?.object.num_dynrelocs; | 4602 | num += self.file(index).?.object.num_dynrelocs; |
| ... | @@ -5079,11 +5075,10 @@ fn writeAtoms(self: *Elf) !void { | ... | @@ -5079,11 +5075,10 @@ fn writeAtoms(self: *Elf) !void { |
| 5079 | fn updateSymtabSize(self: *Elf) !void { | 5075 | fn updateSymtabSize(self: *Elf) !void { |
| 5080 | var sizes = SymtabSize{}; | 5076 | var sizes = SymtabSize{}; |
| 5081 | 5077 | ||
| 5082 | if (self.zig_module_index) |index| { | 5078 | if (self.zigObjectPtr()) |zig_object| { |
| 5083 | const zig_module = self.file(index).?.zig_module; | 5079 | zig_object.updateSymtabSize(self); |
| 5084 | zig_module.updateSymtabSize(self); | 5080 | sizes.nlocals += zig_object.output_symtab_size.nlocals; |
| 5085 | sizes.nlocals += zig_module.output_symtab_size.nlocals; | 5081 | sizes.nglobals += zig_object.output_symtab_size.nglobals; |
| 5086 | sizes.nglobals += zig_module.output_symtab_size.nglobals; | ||
| 5087 | } | 5082 | } |
| 5088 | 5083 | ||
| 5089 | for (self.objects.items) |index| { | 5084 | for (self.objects.items) |index| { |
| ... | @@ -5299,11 +5294,10 @@ fn writeSymtab(self: *Elf) !void { | ... | @@ -5299,11 +5294,10 @@ fn writeSymtab(self: *Elf) !void { |
| 5299 | .symtab = symtab, | 5294 | .symtab = symtab, |
| 5300 | }; | 5295 | }; |
| 5301 | 5296 | ||
| 5302 | if (self.zig_module_index) |index| { | 5297 | if (self.zigObjectPtr()) |zig_object| { |
| 5303 | const zig_module = self.file(index).?.zig_module; | 5298 | zig_object.writeSymtab(self, ctx); |
| 5304 | zig_module.writeSymtab(self, ctx); | 5299 | ctx.ilocal += zig_object.output_symtab_size.nlocals; |
| 5305 | ctx.ilocal += zig_module.output_symtab_size.nlocals; | 5300 | ctx.iglobal += zig_object.output_symtab_size.nglobals; |
| 5306 | ctx.iglobal += zig_module.output_symtab_size.nglobals; | ||
| 5307 | } | 5301 | } |
| 5308 | 5302 | ||
| 5309 | for (self.objects.items) |index| { | 5303 | for (self.objects.items) |index| { |
| ... | @@ -5863,7 +5857,7 @@ pub fn file(self: *Elf, index: File.Index) ?File { | ... | @@ -5863,7 +5857,7 @@ pub fn file(self: *Elf, index: File.Index) ?File { |
| 5863 | return switch (tag) { | 5857 | return switch (tag) { |
| 5864 | .null => null, | 5858 | .null => null, |
| 5865 | .linker_defined => .{ .linker_defined = &self.files.items(.data)[index].linker_defined }, | 5859 | .linker_defined => .{ .linker_defined = &self.files.items(.data)[index].linker_defined }, |
| 5866 | .zig_module => .{ .zig_module = &self.files.items(.data)[index].zig_module }, | 5860 | .zig_object => .{ .zig_object = &self.files.items(.data)[index].zig_object }, |
| 5867 | .object => .{ .object = &self.files.items(.data)[index].object }, | 5861 | .object => .{ .object = &self.files.items(.data)[index].object }, |
| 5868 | .shared_object => .{ .shared_object = &self.files.items(.data)[index].shared_object }, | 5862 | .shared_object => .{ .shared_object = &self.files.items(.data)[index].shared_object }, |
| 5869 | }; | 5863 | }; |
| ... | @@ -5964,23 +5958,22 @@ pub fn getGlobalSymbol(self: *Elf, name: []const u8, lib_name: ?[]const u8) !u32 | ... | @@ -5964,23 +5958,22 @@ pub fn getGlobalSymbol(self: *Elf, name: []const u8, lib_name: ?[]const u8) !u32 |
| 5964 | _ = lib_name; | 5958 | _ = lib_name; |
| 5965 | const gpa = self.base.allocator; | 5959 | const gpa = self.base.allocator; |
| 5966 | const off = try self.strtab.insert(gpa, name); | 5960 | const off = try self.strtab.insert(gpa, name); |
| 5967 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; | 5961 | const zig_object = self.zigObjectPtr().?; |
| 5968 | const lookup_gop = try zig_module.globals_lookup.getOrPut(gpa, off); | 5962 | const lookup_gop = try zig_object.globals_lookup.getOrPut(gpa, off); |
| 5969 | if (!lookup_gop.found_existing) { | 5963 | if (!lookup_gop.found_existing) { |
| 5970 | const esym_index = try zig_module.addGlobalEsym(gpa); | 5964 | const esym_index = try zig_object.addGlobalEsym(gpa); |
| 5971 | const esym = zig_module.elfSym(esym_index); | 5965 | const esym = zig_object.elfSym(esym_index); |
| 5972 | esym.st_name = off; | 5966 | esym.st_name = off; |
| 5973 | lookup_gop.value_ptr.* = esym_index; | 5967 | lookup_gop.value_ptr.* = esym_index; |
| 5974 | const gop = try self.getOrPutGlobal(off); | 5968 | const gop = try self.getOrPutGlobal(off); |
| 5975 | try zig_module.global_symbols.append(gpa, gop.index); | 5969 | try zig_object.global_symbols.append(gpa, gop.index); |
| 5976 | } | 5970 | } |
| 5977 | return lookup_gop.value_ptr.*; | 5971 | return lookup_gop.value_ptr.*; |
| 5978 | } | 5972 | } |
| 5979 | 5973 | ||
| 5980 | pub fn zigModulePtr(self: *Elf) *ZigModule { | 5974 | pub fn zigObjectPtr(self: *Elf) ?*ZigObject { |
| 5981 | assert(self.zig_module_index != null); | 5975 | const index = self.zig_object_index orelse return null; |
| 5982 | const file_ptr = self.file(self.zig_module_index.?).?; | 5976 | return self.file(index).?.zig_object; |
| 5983 | return file_ptr.zig_module; | ||
| 5984 | } | 5977 | } |
| 5985 | 5978 | ||
| 5986 | const GetOrCreateComdatGroupOwnerResult = struct { | 5979 | const GetOrCreateComdatGroupOwnerResult = struct { |
| ... | @@ -6245,12 +6238,11 @@ fn fmtDumpState( | ... | @@ -6245,12 +6238,11 @@ fn fmtDumpState( |
| 6245 | _ = unused_fmt_string; | 6238 | _ = unused_fmt_string; |
| 6246 | _ = options; | 6239 | _ = options; |
| 6247 | 6240 | ||
| 6248 | if (self.zig_module_index) |index| { | 6241 | if (self.zigObjectPtr()) |zig_object| { |
| 6249 | const zig_module = self.file(index).?.zig_module; | 6242 | try writer.print("zig_object({d}) : {s}\n", .{ zig_object.index, zig_object.path }); |
| 6250 | try writer.print("zig_module({d}) : {s}\n", .{ index, zig_module.path }); | ||
| 6251 | try writer.print("{}{}\n", .{ | 6243 | try writer.print("{}{}\n", .{ |
| 6252 | zig_module.fmtAtoms(self), | 6244 | zig_object.fmtAtoms(self), |
| 6253 | zig_module.fmtSymtab(self), | 6245 | zig_object.fmtSymtab(self), |
| 6254 | }); | 6246 | }); |
| 6255 | } | 6247 | } |
| 6256 | 6248 | ||
| ... | @@ -6379,9 +6371,9 @@ const DeclMetadata = struct { | ... | @@ -6379,9 +6371,9 @@ const DeclMetadata = struct { |
| 6379 | exports: std.ArrayListUnmanaged(Symbol.Index) = .{}, | 6371 | exports: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 6380 | 6372 | ||
| 6381 | fn @"export"(m: DeclMetadata, elf_file: *Elf, name: []const u8) ?*u32 { | 6373 | fn @"export"(m: DeclMetadata, elf_file: *Elf, name: []const u8) ?*u32 { |
| 6382 | const zig_module = elf_file.file(elf_file.zig_module_index.?).?.zig_module; | 6374 | const zig_object = elf_file.zigObjectPtr().?; |
| 6383 | for (m.exports.items) |*exp| { | 6375 | for (m.exports.items) |*exp| { |
| 6384 | const exp_name = elf_file.strtab.getAssumeExists(zig_module.elfSym(exp.*).st_name); | 6376 | const exp_name = elf_file.strtab.getAssumeExists(zig_object.elfSym(exp.*).st_name); |
| 6385 | if (mem.eql(u8, name, exp_name)) return exp; | 6377 | if (mem.eql(u8, name, exp_name)) return exp; |
| 6386 | } | 6378 | } |
| 6387 | return null; | 6379 | return null; |
| ... | @@ -6491,4 +6483,4 @@ const TypedValue = @import("../TypedValue.zig"); | ... | @@ -6491,4 +6483,4 @@ const TypedValue = @import("../TypedValue.zig"); |
| 6491 | const Value = @import("../value.zig").Value; | 6483 | const Value = @import("../value.zig").Value; |
| 6492 | const VerneedSection = synthetic_sections.VerneedSection; | 6484 | const VerneedSection = synthetic_sections.VerneedSection; |
| 6493 | const ZigGotSection = synthetic_sections.ZigGotSection; | 6485 | const ZigGotSection = synthetic_sections.ZigGotSection; |
| 6494 | const ZigModule = @import("Elf/ZigModule.zig"); | 6486 | const ZigObject = @import("Elf/ZigObject.zig"); |
src/link/Elf/Atom.zig+14-14| ... | @@ -52,7 +52,7 @@ pub fn file(self: Atom, elf_file: *Elf) ?File { | ... | @@ -52,7 +52,7 @@ pub fn file(self: Atom, elf_file: *Elf) ?File { |
| 52 | pub fn inputShdr(self: Atom, elf_file: *Elf) Object.ElfShdr { | 52 | pub fn inputShdr(self: Atom, elf_file: *Elf) Object.ElfShdr { |
| 53 | return switch (self.file(elf_file).?) { | 53 | return switch (self.file(elf_file).?) { |
| 54 | .object => |x| x.shdrs.items[self.input_section_index], | 54 | .object => |x| x.shdrs.items[self.input_section_index], |
| 55 | .zig_module => |x| x.inputShdr(self.atom_index, elf_file), | 55 | .zig_object => |x| x.inputShdr(self.atom_index, elf_file), |
| 56 | else => unreachable, | 56 | else => unreachable, |
| 57 | }; | 57 | }; |
| 58 | } | 58 | } |
| ... | @@ -270,14 +270,14 @@ pub fn free(self: *Atom, elf_file: *Elf) void { | ... | @@ -270,14 +270,14 @@ pub fn free(self: *Atom, elf_file: *Elf) void { |
| 270 | // TODO create relocs free list | 270 | // TODO create relocs free list |
| 271 | self.freeRelocs(elf_file); | 271 | self.freeRelocs(elf_file); |
| 272 | // TODO figure out how to free input section mappind in ZigModule | 272 | // TODO figure out how to free input section mappind in ZigModule |
| 273 | // const zig_module = self.file(elf_file).?.zig_module; | 273 | // const zig_object = elf_file.zigObjectPtr().? |
| 274 | // assert(zig_module.atoms.swapRemove(self.atom_index)); | 274 | // assert(zig_object.atoms.swapRemove(self.atom_index)); |
| 275 | self.* = .{}; | 275 | self.* = .{}; |
| 276 | } | 276 | } |
| 277 | 277 | ||
| 278 | pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela { | 278 | pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela { |
| 279 | return switch (self.file(elf_file).?) { | 279 | return switch (self.file(elf_file).?) { |
| 280 | .zig_module => |x| x.relocs.items[self.relocs_section_index].items, | 280 | .zig_object => |x| x.relocs.items[self.relocs_section_index].items, |
| 281 | .object => |x| x.getRelocs(self.relocs_section_index), | 281 | .object => |x| x.getRelocs(self.relocs_section_index), |
| 282 | else => unreachable, | 282 | else => unreachable, |
| 283 | }; | 283 | }; |
| ... | @@ -298,17 +298,17 @@ pub fn markFdesDead(self: Atom, elf_file: *Elf) void { | ... | @@ -298,17 +298,17 @@ pub fn markFdesDead(self: Atom, elf_file: *Elf) void { |
| 298 | pub fn addReloc(self: Atom, elf_file: *Elf, reloc: elf.Elf64_Rela) !void { | 298 | pub fn addReloc(self: Atom, elf_file: *Elf, reloc: elf.Elf64_Rela) !void { |
| 299 | const gpa = elf_file.base.allocator; | 299 | const gpa = elf_file.base.allocator; |
| 300 | const file_ptr = self.file(elf_file).?; | 300 | const file_ptr = self.file(elf_file).?; |
| 301 | assert(file_ptr == .zig_module); | 301 | assert(file_ptr == .zig_object); |
| 302 | const zig_module = file_ptr.zig_module; | 302 | const zig_object = file_ptr.zig_object; |
| 303 | const rels = &zig_module.relocs.items[self.relocs_section_index]; | 303 | const rels = &zig_object.relocs.items[self.relocs_section_index]; |
| 304 | try rels.append(gpa, reloc); | 304 | try rels.append(gpa, reloc); |
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | pub fn freeRelocs(self: Atom, elf_file: *Elf) void { | 307 | pub fn freeRelocs(self: Atom, elf_file: *Elf) void { |
| 308 | const file_ptr = self.file(elf_file).?; | 308 | const file_ptr = self.file(elf_file).?; |
| 309 | assert(file_ptr == .zig_module); | 309 | assert(file_ptr == .zig_object); |
| 310 | const zig_module = file_ptr.zig_module; | 310 | const zig_object = file_ptr.zig_object; |
| 311 | zig_module.relocs.items[self.relocs_section_index].clearRetainingCapacity(); | 311 | zig_object.relocs.items[self.relocs_section_index].clearRetainingCapacity(); |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool { | 314 | pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool { |
| ... | @@ -332,7 +332,7 @@ pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype | ... | @@ -332,7 +332,7 @@ pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype |
| 332 | const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow; | 332 | const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow; |
| 333 | 333 | ||
| 334 | const symbol_index = switch (file_ptr) { | 334 | const symbol_index = switch (file_ptr) { |
| 335 | .zig_module => |x| x.symbol(rel.r_sym()), | 335 | .zig_object => |x| x.symbol(rel.r_sym()), |
| 336 | .object => |x| x.symbols.items[rel.r_sym()], | 336 | .object => |x| x.symbols.items[rel.r_sym()], |
| 337 | else => unreachable, | 337 | else => unreachable, |
| 338 | }; | 338 | }; |
| ... | @@ -690,7 +690,7 @@ fn reportUndefined( | ... | @@ -690,7 +690,7 @@ fn reportUndefined( |
| 690 | undefs: anytype, | 690 | undefs: anytype, |
| 691 | ) !void { | 691 | ) !void { |
| 692 | const rel_esym = switch (self.file(elf_file).?) { | 692 | const rel_esym = switch (self.file(elf_file).?) { |
| 693 | .zig_module => |x| x.elfSym(rel.r_sym()).*, | 693 | .zig_object => |x| x.elfSym(rel.r_sym()).*, |
| 694 | .object => |x| x.symtab[rel.r_sym()], | 694 | .object => |x| x.symtab[rel.r_sym()], |
| 695 | else => unreachable, | 695 | else => unreachable, |
| 696 | }; | 696 | }; |
| ... | @@ -724,7 +724,7 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) !void { | ... | @@ -724,7 +724,7 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) !void { |
| 724 | if (r_type == elf.R_X86_64_NONE) continue; | 724 | if (r_type == elf.R_X86_64_NONE) continue; |
| 725 | 725 | ||
| 726 | const target = switch (file_ptr) { | 726 | const target = switch (file_ptr) { |
| 727 | .zig_module => |x| elf_file.symbol(x.symbol(rel.r_sym())), | 727 | .zig_object => |x| elf_file.symbol(x.symbol(rel.r_sym())), |
| 728 | .object => |x| elf_file.symbol(x.symbols.items[rel.r_sym()]), | 728 | .object => |x| elf_file.symbol(x.symbols.items[rel.r_sym()]), |
| 729 | else => unreachable, | 729 | else => unreachable, |
| 730 | }; | 730 | }; |
| ... | @@ -1004,7 +1004,7 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any | ... | @@ -1004,7 +1004,7 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any |
| 1004 | const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow; | 1004 | const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow; |
| 1005 | 1005 | ||
| 1006 | const target_index = switch (file_ptr) { | 1006 | const target_index = switch (file_ptr) { |
| 1007 | .zig_module => |x| x.symbol(rel.r_sym()), | 1007 | .zig_object => |x| x.symbol(rel.r_sym()), |
| 1008 | .object => |x| x.symbols.items[rel.r_sym()], | 1008 | .object => |x| x.symbols.items[rel.r_sym()], |
| 1009 | else => unreachable, | 1009 | else => unreachable, |
| 1010 | }; | 1010 | }; |
src/link/Elf/Symbol.zig+1-2| ... | @@ -72,7 +72,7 @@ pub fn file(symbol: Symbol, elf_file: *Elf) ?File { | ... | @@ -72,7 +72,7 @@ pub fn file(symbol: Symbol, elf_file: *Elf) ?File { |
| 72 | pub fn elfSym(symbol: Symbol, elf_file: *Elf) elf.Elf64_Sym { | 72 | pub fn elfSym(symbol: Symbol, elf_file: *Elf) elf.Elf64_Sym { |
| 73 | const file_ptr = symbol.file(elf_file).?; | 73 | const file_ptr = symbol.file(elf_file).?; |
| 74 | switch (file_ptr) { | 74 | switch (file_ptr) { |
| 75 | .zig_module => |x| return x.elfSym(symbol.esym_index).*, | 75 | .zig_object => |x| return x.elfSym(symbol.esym_index).*, |
| 76 | .linker_defined => |x| return x.symtab.items[symbol.esym_index], | 76 | .linker_defined => |x| return x.symtab.items[symbol.esym_index], |
| 77 | inline else => |x| return x.symtab[symbol.esym_index], | 77 | inline else => |x| return x.symtab[symbol.esym_index], |
| 78 | } | 78 | } |
| ... | @@ -406,4 +406,3 @@ const PltSection = synthetic_sections.PltSection; | ... | @@ -406,4 +406,3 @@ const PltSection = synthetic_sections.PltSection; |
| 406 | const SharedObject = @import("SharedObject.zig"); | 406 | const SharedObject = @import("SharedObject.zig"); |
| 407 | const Symbol = @This(); | 407 | const Symbol = @This(); |
| 408 | const ZigGotSection = synthetic_sections.ZigGotSection; | 408 | const ZigGotSection = synthetic_sections.ZigGotSection; |
| 409 | const ZigModule = @import("ZigModule.zig"); |
src/link/Elf/ZigModule.zig deleted-381| ... | @@ -1,381 +0,0 @@ | ||
| 1 | //! ZigModule encapsulates the state of the incrementally compiled Zig module. | ||
| 2 | //! It stores the associated input local and global symbols, allocated atoms, | ||
| 3 | //! and any relocations that may have been emitted. | ||
| 4 | //! Think about this as fake in-memory Object file for the Zig module. | ||
| 5 | |||
| 6 | /// Path is owned by Module and lives as long as *Module. | ||
| 7 | path: []const u8, | ||
| 8 | index: File.Index, | ||
| 9 | |||
| 10 | local_esyms: std.MultiArrayList(ElfSym) = .{}, | ||
| 11 | global_esyms: std.MultiArrayList(ElfSym) = .{}, | ||
| 12 | local_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, | ||
| 13 | global_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, | ||
| 14 | globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{}, | ||
| 15 | |||
| 16 | atoms: std.ArrayListUnmanaged(Atom.Index) = .{}, | ||
| 17 | relocs: std.ArrayListUnmanaged(std.ArrayListUnmanaged(elf.Elf64_Rela)) = .{}, | ||
| 18 | |||
| 19 | num_dynrelocs: u32 = 0, | ||
| 20 | |||
| 21 | output_symtab_size: Elf.SymtabSize = .{}, | ||
| 22 | |||
| 23 | pub const global_symbol_bit: u32 = 0x80000000; | ||
| 24 | pub const symbol_mask: u32 = 0x7fffffff; | ||
| 25 | pub const SHN_ATOM: u16 = 0x100; | ||
| 26 | |||
| 27 | pub fn deinit(self: *ZigModule, allocator: Allocator) void { | ||
| 28 | self.local_esyms.deinit(allocator); | ||
| 29 | self.global_esyms.deinit(allocator); | ||
| 30 | self.local_symbols.deinit(allocator); | ||
| 31 | self.global_symbols.deinit(allocator); | ||
| 32 | self.globals_lookup.deinit(allocator); | ||
| 33 | self.atoms.deinit(allocator); | ||
| 34 | for (self.relocs.items) |*list| { | ||
| 35 | list.deinit(allocator); | ||
| 36 | } | ||
| 37 | self.relocs.deinit(allocator); | ||
| 38 | } | ||
| 39 | |||
| 40 | pub fn addLocalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index { | ||
| 41 | try self.local_esyms.ensureUnusedCapacity(allocator, 1); | ||
| 42 | const index = @as(Symbol.Index, @intCast(self.local_esyms.addOneAssumeCapacity())); | ||
| 43 | var esym = ElfSym{ .elf_sym = Elf.null_sym }; | ||
| 44 | esym.elf_sym.st_info = elf.STB_LOCAL << 4; | ||
| 45 | self.local_esyms.set(index, esym); | ||
| 46 | return index; | ||
| 47 | } | ||
| 48 | |||
| 49 | pub fn addGlobalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index { | ||
| 50 | try self.global_esyms.ensureUnusedCapacity(allocator, 1); | ||
| 51 | const index = @as(Symbol.Index, @intCast(self.global_esyms.addOneAssumeCapacity())); | ||
| 52 | var esym = ElfSym{ .elf_sym = Elf.null_sym }; | ||
| 53 | esym.elf_sym.st_info = elf.STB_GLOBAL << 4; | ||
| 54 | self.global_esyms.set(index, esym); | ||
| 55 | return index | global_symbol_bit; | ||
| 56 | } | ||
| 57 | |||
| 58 | pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index { | ||
| 59 | const gpa = elf_file.base.allocator; | ||
| 60 | |||
| 61 | const atom_index = try elf_file.addAtom(); | ||
| 62 | const symbol_index = try elf_file.addSymbol(); | ||
| 63 | const esym_index = try self.addLocalEsym(gpa); | ||
| 64 | |||
| 65 | const shndx = @as(u32, @intCast(self.atoms.items.len)); | ||
| 66 | try self.atoms.append(gpa, atom_index); | ||
| 67 | try self.local_symbols.append(gpa, symbol_index); | ||
| 68 | |||
| 69 | const atom_ptr = elf_file.atom(atom_index).?; | ||
| 70 | atom_ptr.file_index = self.index; | ||
| 71 | |||
| 72 | const symbol_ptr = elf_file.symbol(symbol_index); | ||
| 73 | symbol_ptr.file_index = self.index; | ||
| 74 | symbol_ptr.atom_index = atom_index; | ||
| 75 | |||
| 76 | self.local_esyms.items(.shndx)[esym_index] = shndx; | ||
| 77 | self.local_esyms.items(.elf_sym)[esym_index].st_shndx = SHN_ATOM; | ||
| 78 | symbol_ptr.esym_index = esym_index; | ||
| 79 | |||
| 80 | const relocs_index = @as(u32, @intCast(self.relocs.items.len)); | ||
| 81 | const relocs = try self.relocs.addOne(gpa); | ||
| 82 | relocs.* = .{}; | ||
| 83 | atom_ptr.relocs_section_index = relocs_index; | ||
| 84 | |||
| 85 | return symbol_index; | ||
| 86 | } | ||
| 87 | |||
| 88 | /// TODO actually create fake input shdrs and return that instead. | ||
| 89 | pub fn inputShdr(self: ZigModule, atom_index: Atom.Index, elf_file: *Elf) Object.ElfShdr { | ||
| 90 | _ = self; | ||
| 91 | const shdr = shdr: { | ||
| 92 | const atom = elf_file.atom(atom_index) orelse break :shdr Elf.null_shdr; | ||
| 93 | const shndx = atom.outputShndx() orelse break :shdr Elf.null_shdr; | ||
| 94 | var shdr = elf_file.shdrs.items[shndx]; | ||
| 95 | shdr.sh_addr = 0; | ||
| 96 | shdr.sh_offset = 0; | ||
| 97 | shdr.sh_size = atom.size; | ||
| 98 | shdr.sh_addralign = atom.alignment.toByteUnits(1); | ||
| 99 | break :shdr shdr; | ||
| 100 | }; | ||
| 101 | return Object.ElfShdr.fromElf64Shdr(shdr) catch unreachable; | ||
| 102 | } | ||
| 103 | |||
| 104 | pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void { | ||
| 105 | for (self.globals(), 0..) |index, i| { | ||
| 106 | const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit; | ||
| 107 | const esym = self.global_esyms.items(.elf_sym)[i]; | ||
| 108 | const shndx = self.global_esyms.items(.shndx)[i]; | ||
| 109 | |||
| 110 | if (esym.st_shndx == elf.SHN_UNDEF) continue; | ||
| 111 | |||
| 112 | if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) { | ||
| 113 | assert(esym.st_shndx == SHN_ATOM); | ||
| 114 | const atom_index = self.atoms.items[shndx]; | ||
| 115 | const atom = elf_file.atom(atom_index) orelse continue; | ||
| 116 | if (!atom.flags.alive) continue; | ||
| 117 | } | ||
| 118 | |||
| 119 | const global = elf_file.symbol(index); | ||
| 120 | if (self.asFile().symbolRank(esym, false) < global.symbolRank(elf_file)) { | ||
| 121 | const atom_index = switch (esym.st_shndx) { | ||
| 122 | elf.SHN_ABS, elf.SHN_COMMON => 0, | ||
| 123 | SHN_ATOM => self.atoms.items[shndx], | ||
| 124 | else => unreachable, | ||
| 125 | }; | ||
| 126 | const output_section_index = if (elf_file.atom(atom_index)) |atom| | ||
| 127 | atom.outputShndx().? | ||
| 128 | else | ||
| 129 | elf.SHN_UNDEF; | ||
| 130 | global.value = esym.st_value; | ||
| 131 | global.atom_index = atom_index; | ||
| 132 | global.esym_index = esym_index; | ||
| 133 | global.file_index = self.index; | ||
| 134 | global.output_section_index = output_section_index; | ||
| 135 | global.version_index = elf_file.default_sym_version; | ||
| 136 | if (esym.st_bind() == elf.STB_WEAK) global.flags.weak = true; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 | pub fn claimUnresolved(self: *ZigModule, elf_file: *Elf) void { | ||
| 142 | for (self.globals(), 0..) |index, i| { | ||
| 143 | const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit; | ||
| 144 | const esym = self.global_esyms.items(.elf_sym)[i]; | ||
| 145 | |||
| 146 | if (esym.st_shndx != elf.SHN_UNDEF) continue; | ||
| 147 | |||
| 148 | const global = elf_file.symbol(index); | ||
| 149 | if (global.file(elf_file)) |_| { | ||
| 150 | if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF) continue; | ||
| 151 | } | ||
| 152 | |||
| 153 | const is_import = blk: { | ||
| 154 | if (!elf_file.isDynLib()) break :blk false; | ||
| 155 | const vis = @as(elf.STV, @enumFromInt(esym.st_other)); | ||
| 156 | if (vis == .HIDDEN) break :blk false; | ||
| 157 | break :blk true; | ||
| 158 | }; | ||
| 159 | |||
| 160 | global.value = 0; | ||
| 161 | global.atom_index = 0; | ||
| 162 | global.esym_index = esym_index; | ||
| 163 | global.file_index = self.index; | ||
| 164 | global.version_index = if (is_import) elf.VER_NDX_LOCAL else elf_file.default_sym_version; | ||
| 165 | global.flags.import = is_import; | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 169 | pub fn scanRelocs(self: *ZigModule, elf_file: *Elf, undefs: anytype) !void { | ||
| 170 | for (self.atoms.items) |atom_index| { | ||
| 171 | const atom = elf_file.atom(atom_index) orelse continue; | ||
| 172 | if (!atom.flags.alive) continue; | ||
| 173 | const shdr = atom.inputShdr(elf_file); | ||
| 174 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | ||
| 175 | if (atom.scanRelocsRequiresCode(elf_file)) { | ||
| 176 | // TODO ideally we don't have to fetch the code here. | ||
| 177 | // Perhaps it would make sense to save the code until flushModule where we | ||
| 178 | // would free all of generated code? | ||
| 179 | const code = try self.codeAlloc(elf_file, atom_index); | ||
| 180 | defer elf_file.base.allocator.free(code); | ||
| 181 | try atom.scanRelocs(elf_file, code, undefs); | ||
| 182 | } else try atom.scanRelocs(elf_file, null, undefs); | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | pub fn resetGlobals(self: *ZigModule, elf_file: *Elf) void { | ||
| 187 | for (self.globals()) |index| { | ||
| 188 | const global = elf_file.symbol(index); | ||
| 189 | const off = global.name_offset; | ||
| 190 | global.* = .{}; | ||
| 191 | global.name_offset = off; | ||
| 192 | } | ||
| 193 | } | ||
| 194 | |||
| 195 | pub fn markLive(self: *ZigModule, elf_file: *Elf) void { | ||
| 196 | for (self.globals(), 0..) |index, i| { | ||
| 197 | const esym = self.global_esyms.items(.elf_sym)[i]; | ||
| 198 | if (esym.st_bind() == elf.STB_WEAK) continue; | ||
| 199 | |||
| 200 | const global = elf_file.symbol(index); | ||
| 201 | const file = global.file(elf_file) orelse continue; | ||
| 202 | const should_keep = esym.st_shndx == elf.SHN_UNDEF or | ||
| 203 | (esym.st_shndx == elf.SHN_COMMON and global.elfSym(elf_file).st_shndx != elf.SHN_COMMON); | ||
| 204 | if (should_keep and !file.isAlive()) { | ||
| 205 | file.setAlive(); | ||
| 206 | file.markLive(elf_file); | ||
| 207 | } | ||
| 208 | } | ||
| 209 | } | ||
| 210 | |||
| 211 | pub fn updateSymtabSize(self: *ZigModule, elf_file: *Elf) void { | ||
| 212 | for (self.locals()) |local_index| { | ||
| 213 | const local = elf_file.symbol(local_index); | ||
| 214 | const esym = local.elfSym(elf_file); | ||
| 215 | switch (esym.st_type()) { | ||
| 216 | elf.STT_SECTION, elf.STT_NOTYPE => { | ||
| 217 | local.flags.output_symtab = false; | ||
| 218 | continue; | ||
| 219 | }, | ||
| 220 | else => {}, | ||
| 221 | } | ||
| 222 | local.flags.output_symtab = true; | ||
| 223 | self.output_symtab_size.nlocals += 1; | ||
| 224 | } | ||
| 225 | |||
| 226 | for (self.globals()) |global_index| { | ||
| 227 | const global = elf_file.symbol(global_index); | ||
| 228 | if (global.file(elf_file)) |file| if (file.index() != self.index) { | ||
| 229 | global.flags.output_symtab = false; | ||
| 230 | continue; | ||
| 231 | }; | ||
| 232 | global.flags.output_symtab = true; | ||
| 233 | if (global.isLocal()) { | ||
| 234 | self.output_symtab_size.nlocals += 1; | ||
| 235 | } else { | ||
| 236 | self.output_symtab_size.nglobals += 1; | ||
| 237 | } | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | pub fn writeSymtab(self: *ZigModule, elf_file: *Elf, ctx: anytype) void { | ||
| 242 | var ilocal = ctx.ilocal; | ||
| 243 | for (self.locals()) |local_index| { | ||
| 244 | const local = elf_file.symbol(local_index); | ||
| 245 | if (!local.flags.output_symtab) continue; | ||
| 246 | local.setOutputSym(elf_file, &ctx.symtab[ilocal]); | ||
| 247 | ilocal += 1; | ||
| 248 | } | ||
| 249 | |||
| 250 | var iglobal = ctx.iglobal; | ||
| 251 | for (self.globals()) |global_index| { | ||
| 252 | const global = elf_file.symbol(global_index); | ||
| 253 | if (global.file(elf_file)) |file| if (file.index() != self.index) continue; | ||
| 254 | if (!global.flags.output_symtab) continue; | ||
| 255 | if (global.isLocal()) { | ||
| 256 | global.setOutputSym(elf_file, &ctx.symtab[ilocal]); | ||
| 257 | ilocal += 1; | ||
| 258 | } else { | ||
| 259 | global.setOutputSym(elf_file, &ctx.symtab[iglobal]); | ||
| 260 | iglobal += 1; | ||
| 261 | } | ||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 265 | pub fn symbol(self: *ZigModule, index: Symbol.Index) Symbol.Index { | ||
| 266 | const is_global = index & global_symbol_bit != 0; | ||
| 267 | const actual_index = index & symbol_mask; | ||
| 268 | if (is_global) return self.global_symbols.items[actual_index]; | ||
| 269 | return self.local_symbols.items[actual_index]; | ||
| 270 | } | ||
| 271 | |||
| 272 | pub fn elfSym(self: *ZigModule, index: Symbol.Index) *elf.Elf64_Sym { | ||
| 273 | const is_global = index & global_symbol_bit != 0; | ||
| 274 | const actual_index = index & symbol_mask; | ||
| 275 | if (is_global) return &self.global_esyms.items(.elf_sym)[actual_index]; | ||
| 276 | return &self.local_esyms.items(.elf_sym)[actual_index]; | ||
| 277 | } | ||
| 278 | |||
| 279 | pub fn locals(self: *ZigModule) []const Symbol.Index { | ||
| 280 | return self.local_symbols.items; | ||
| 281 | } | ||
| 282 | |||
| 283 | pub fn globals(self: *ZigModule) []const Symbol.Index { | ||
| 284 | return self.global_symbols.items; | ||
| 285 | } | ||
| 286 | |||
| 287 | pub fn asFile(self: *ZigModule) File { | ||
| 288 | return .{ .zig_module = self }; | ||
| 289 | } | ||
| 290 | |||
| 291 | /// Returns atom's code. | ||
| 292 | /// Caller owns the memory. | ||
| 293 | pub fn codeAlloc(self: ZigModule, elf_file: *Elf, atom_index: Atom.Index) ![]u8 { | ||
| 294 | const gpa = elf_file.base.allocator; | ||
| 295 | const atom = elf_file.atom(atom_index).?; | ||
| 296 | assert(atom.file_index == self.index); | ||
| 297 | const shdr = &elf_file.shdrs.items[atom.outputShndx().?]; | ||
| 298 | const file_offset = shdr.sh_offset + atom.value - shdr.sh_addr; | ||
| 299 | const size = std.math.cast(usize, atom.size) orelse return error.Overflow; | ||
| 300 | const code = try gpa.alloc(u8, size); | ||
| 301 | errdefer gpa.free(code); | ||
| 302 | const amt = try elf_file.base.file.?.preadAll(code, file_offset); | ||
| 303 | if (amt != code.len) { | ||
| 304 | log.err("fetching code for {s} failed", .{atom.name(elf_file)}); | ||
| 305 | return error.InputOutput; | ||
| 306 | } | ||
| 307 | return code; | ||
| 308 | } | ||
| 309 | |||
| 310 | pub fn fmtSymtab(self: *ZigModule, elf_file: *Elf) std.fmt.Formatter(formatSymtab) { | ||
| 311 | return .{ .data = .{ | ||
| 312 | .self = self, | ||
| 313 | .elf_file = elf_file, | ||
| 314 | } }; | ||
| 315 | } | ||
| 316 | |||
| 317 | const FormatContext = struct { | ||
| 318 | self: *ZigModule, | ||
| 319 | elf_file: *Elf, | ||
| 320 | }; | ||
| 321 | |||
| 322 | fn formatSymtab( | ||
| 323 | ctx: FormatContext, | ||
| 324 | comptime unused_fmt_string: []const u8, | ||
| 325 | options: std.fmt.FormatOptions, | ||
| 326 | writer: anytype, | ||
| 327 | ) !void { | ||
| 328 | _ = unused_fmt_string; | ||
| 329 | _ = options; | ||
| 330 | try writer.writeAll(" locals\n"); | ||
| 331 | for (ctx.self.locals()) |index| { | ||
| 332 | const local = ctx.elf_file.symbol(index); | ||
| 333 | try writer.print(" {}\n", .{local.fmt(ctx.elf_file)}); | ||
| 334 | } | ||
| 335 | try writer.writeAll(" globals\n"); | ||
| 336 | for (ctx.self.globals()) |index| { | ||
| 337 | const global = ctx.elf_file.symbol(index); | ||
| 338 | try writer.print(" {}\n", .{global.fmt(ctx.elf_file)}); | ||
| 339 | } | ||
| 340 | } | ||
| 341 | |||
| 342 | pub fn fmtAtoms(self: *ZigModule, elf_file: *Elf) std.fmt.Formatter(formatAtoms) { | ||
| 343 | return .{ .data = .{ | ||
| 344 | .self = self, | ||
| 345 | .elf_file = elf_file, | ||
| 346 | } }; | ||
| 347 | } | ||
| 348 | |||
| 349 | fn formatAtoms( | ||
| 350 | ctx: FormatContext, | ||
| 351 | comptime unused_fmt_string: []const u8, | ||
| 352 | options: std.fmt.FormatOptions, | ||
| 353 | writer: anytype, | ||
| 354 | ) !void { | ||
| 355 | _ = unused_fmt_string; | ||
| 356 | _ = options; | ||
| 357 | try writer.writeAll(" atoms\n"); | ||
| 358 | for (ctx.self.atoms.items) |atom_index| { | ||
| 359 | const atom = ctx.elf_file.atom(atom_index) orelse continue; | ||
| 360 | try writer.print(" {}\n", .{atom.fmt(ctx.elf_file)}); | ||
| 361 | } | ||
| 362 | } | ||
| 363 | |||
| 364 | const ElfSym = struct { | ||
| 365 | elf_sym: elf.Elf64_Sym, | ||
| 366 | shndx: u32 = elf.SHN_UNDEF, | ||
| 367 | }; | ||
| 368 | |||
| 369 | const assert = std.debug.assert; | ||
| 370 | const std = @import("std"); | ||
| 371 | const elf = std.elf; | ||
| 372 | const log = std.log.scoped(.link); | ||
| 373 | |||
| 374 | const Allocator = std.mem.Allocator; | ||
| 375 | const Atom = @import("Atom.zig"); | ||
| 376 | const Elf = @import("../Elf.zig"); | ||
| 377 | const File = @import("file.zig").File; | ||
| 378 | const Module = @import("../../Module.zig"); | ||
| 379 | const Object = @import("Object.zig"); | ||
| 380 | const Symbol = @import("Symbol.zig"); | ||
| 381 | const ZigModule = @This(); | ||
src/link/Elf/ZigObject.zig created+381| ... | @@ -0,0 +1,381 @@ | ||
| 1 | //! ZigModule encapsulates the state of the incrementally compiled Zig module. | ||
| 2 | //! It stores the associated input local and global symbols, allocated atoms, | ||
| 3 | //! and any relocations that may have been emitted. | ||
| 4 | //! Think about this as fake in-memory Object file for the Zig module. | ||
| 5 | |||
| 6 | /// Path is owned by Module and lives as long as *Module. | ||
| 7 | path: []const u8, | ||
| 8 | index: File.Index, | ||
| 9 | |||
| 10 | local_esyms: std.MultiArrayList(ElfSym) = .{}, | ||
| 11 | global_esyms: std.MultiArrayList(ElfSym) = .{}, | ||
| 12 | local_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, | ||
| 13 | global_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, | ||
| 14 | globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{}, | ||
| 15 | |||
| 16 | atoms: std.ArrayListUnmanaged(Atom.Index) = .{}, | ||
| 17 | relocs: std.ArrayListUnmanaged(std.ArrayListUnmanaged(elf.Elf64_Rela)) = .{}, | ||
| 18 | |||
| 19 | num_dynrelocs: u32 = 0, | ||
| 20 | |||
| 21 | output_symtab_size: Elf.SymtabSize = .{}, | ||
| 22 | |||
| 23 | pub const global_symbol_bit: u32 = 0x80000000; | ||
| 24 | pub const symbol_mask: u32 = 0x7fffffff; | ||
| 25 | pub const SHN_ATOM: u16 = 0x100; | ||
| 26 | |||
| 27 | pub fn deinit(self: *ZigModule, allocator: Allocator) void { | ||
| 28 | self.local_esyms.deinit(allocator); | ||
| 29 | self.global_esyms.deinit(allocator); | ||
| 30 | self.local_symbols.deinit(allocator); | ||
| 31 | self.global_symbols.deinit(allocator); | ||
| 32 | self.globals_lookup.deinit(allocator); | ||
| 33 | self.atoms.deinit(allocator); | ||
| 34 | for (self.relocs.items) |*list| { | ||
| 35 | list.deinit(allocator); | ||
| 36 | } | ||
| 37 | self.relocs.deinit(allocator); | ||
| 38 | } | ||
| 39 | |||
| 40 | pub fn addLocalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index { | ||
| 41 | try self.local_esyms.ensureUnusedCapacity(allocator, 1); | ||
| 42 | const index = @as(Symbol.Index, @intCast(self.local_esyms.addOneAssumeCapacity())); | ||
| 43 | var esym = ElfSym{ .elf_sym = Elf.null_sym }; | ||
| 44 | esym.elf_sym.st_info = elf.STB_LOCAL << 4; | ||
| 45 | self.local_esyms.set(index, esym); | ||
| 46 | return index; | ||
| 47 | } | ||
| 48 | |||
| 49 | pub fn addGlobalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index { | ||
| 50 | try self.global_esyms.ensureUnusedCapacity(allocator, 1); | ||
| 51 | const index = @as(Symbol.Index, @intCast(self.global_esyms.addOneAssumeCapacity())); | ||
| 52 | var esym = ElfSym{ .elf_sym = Elf.null_sym }; | ||
| 53 | esym.elf_sym.st_info = elf.STB_GLOBAL << 4; | ||
| 54 | self.global_esyms.set(index, esym); | ||
| 55 | return index | global_symbol_bit; | ||
| 56 | } | ||
| 57 | |||
| 58 | pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index { | ||
| 59 | const gpa = elf_file.base.allocator; | ||
| 60 | |||
| 61 | const atom_index = try elf_file.addAtom(); | ||
| 62 | const symbol_index = try elf_file.addSymbol(); | ||
| 63 | const esym_index = try self.addLocalEsym(gpa); | ||
| 64 | |||
| 65 | const shndx = @as(u32, @intCast(self.atoms.items.len)); | ||
| 66 | try self.atoms.append(gpa, atom_index); | ||
| 67 | try self.local_symbols.append(gpa, symbol_index); | ||
| 68 | |||
| 69 | const atom_ptr = elf_file.atom(atom_index).?; | ||
| 70 | atom_ptr.file_index = self.index; | ||
| 71 | |||
| 72 | const symbol_ptr = elf_file.symbol(symbol_index); | ||
| 73 | symbol_ptr.file_index = self.index; | ||
| 74 | symbol_ptr.atom_index = atom_index; | ||
| 75 | |||
| 76 | self.local_esyms.items(.shndx)[esym_index] = shndx; | ||
| 77 | self.local_esyms.items(.elf_sym)[esym_index].st_shndx = SHN_ATOM; | ||
| 78 | symbol_ptr.esym_index = esym_index; | ||
| 79 | |||
| 80 | const relocs_index = @as(u32, @intCast(self.relocs.items.len)); | ||
| 81 | const relocs = try self.relocs.addOne(gpa); | ||
| 82 | relocs.* = .{}; | ||
| 83 | atom_ptr.relocs_section_index = relocs_index; | ||
| 84 | |||
| 85 | return symbol_index; | ||
| 86 | } | ||
| 87 | |||
| 88 | /// TODO actually create fake input shdrs and return that instead. | ||
| 89 | pub fn inputShdr(self: ZigModule, atom_index: Atom.Index, elf_file: *Elf) Object.ElfShdr { | ||
| 90 | _ = self; | ||
| 91 | const shdr = shdr: { | ||
| 92 | const atom = elf_file.atom(atom_index) orelse break :shdr Elf.null_shdr; | ||
| 93 | const shndx = atom.outputShndx() orelse break :shdr Elf.null_shdr; | ||
| 94 | var shdr = elf_file.shdrs.items[shndx]; | ||
| 95 | shdr.sh_addr = 0; | ||
| 96 | shdr.sh_offset = 0; | ||
| 97 | shdr.sh_size = atom.size; | ||
| 98 | shdr.sh_addralign = atom.alignment.toByteUnits(1); | ||
| 99 | break :shdr shdr; | ||
| 100 | }; | ||
| 101 | return Object.ElfShdr.fromElf64Shdr(shdr) catch unreachable; | ||
| 102 | } | ||
| 103 | |||
| 104 | pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void { | ||
| 105 | for (self.globals(), 0..) |index, i| { | ||
| 106 | const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit; | ||
| 107 | const esym = self.global_esyms.items(.elf_sym)[i]; | ||
| 108 | const shndx = self.global_esyms.items(.shndx)[i]; | ||
| 109 | |||
| 110 | if (esym.st_shndx == elf.SHN_UNDEF) continue; | ||
| 111 | |||
| 112 | if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) { | ||
| 113 | assert(esym.st_shndx == SHN_ATOM); | ||
| 114 | const atom_index = self.atoms.items[shndx]; | ||
| 115 | const atom = elf_file.atom(atom_index) orelse continue; | ||
| 116 | if (!atom.flags.alive) continue; | ||
| 117 | } | ||
| 118 | |||
| 119 | const global = elf_file.symbol(index); | ||
| 120 | if (self.asFile().symbolRank(esym, false) < global.symbolRank(elf_file)) { | ||
| 121 | const atom_index = switch (esym.st_shndx) { | ||
| 122 | elf.SHN_ABS, elf.SHN_COMMON => 0, | ||
| 123 | SHN_ATOM => self.atoms.items[shndx], | ||
| 124 | else => unreachable, | ||
| 125 | }; | ||
| 126 | const output_section_index = if (elf_file.atom(atom_index)) |atom| | ||
| 127 | atom.outputShndx().? | ||
| 128 | else | ||
| 129 | elf.SHN_UNDEF; | ||
| 130 | global.value = esym.st_value; | ||
| 131 | global.atom_index = atom_index; | ||
| 132 | global.esym_index = esym_index; | ||
| 133 | global.file_index = self.index; | ||
| 134 | global.output_section_index = output_section_index; | ||
| 135 | global.version_index = elf_file.default_sym_version; | ||
| 136 | if (esym.st_bind() == elf.STB_WEAK) global.flags.weak = true; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 | pub fn claimUnresolved(self: *ZigModule, elf_file: *Elf) void { | ||
| 142 | for (self.globals(), 0..) |index, i| { | ||
| 143 | const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit; | ||
| 144 | const esym = self.global_esyms.items(.elf_sym)[i]; | ||
| 145 | |||
| 146 | if (esym.st_shndx != elf.SHN_UNDEF) continue; | ||
| 147 | |||
| 148 | const global = elf_file.symbol(index); | ||
| 149 | if (global.file(elf_file)) |_| { | ||
| 150 | if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF) continue; | ||
| 151 | } | ||
| 152 | |||
| 153 | const is_import = blk: { | ||
| 154 | if (!elf_file.isDynLib()) break :blk false; | ||
| 155 | const vis = @as(elf.STV, @enumFromInt(esym.st_other)); | ||
| 156 | if (vis == .HIDDEN) break :blk false; | ||
| 157 | break :blk true; | ||
| 158 | }; | ||
| 159 | |||
| 160 | global.value = 0; | ||
| 161 | global.atom_index = 0; | ||
| 162 | global.esym_index = esym_index; | ||
| 163 | global.file_index = self.index; | ||
| 164 | global.version_index = if (is_import) elf.VER_NDX_LOCAL else elf_file.default_sym_version; | ||
| 165 | global.flags.import = is_import; | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 169 | pub fn scanRelocs(self: *ZigModule, elf_file: *Elf, undefs: anytype) !void { | ||
| 170 | for (self.atoms.items) |atom_index| { | ||
| 171 | const atom = elf_file.atom(atom_index) orelse continue; | ||
| 172 | if (!atom.flags.alive) continue; | ||
| 173 | const shdr = atom.inputShdr(elf_file); | ||
| 174 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | ||
| 175 | if (atom.scanRelocsRequiresCode(elf_file)) { | ||
| 176 | // TODO ideally we don't have to fetch the code here. | ||
| 177 | // Perhaps it would make sense to save the code until flushModule where we | ||
| 178 | // would free all of generated code? | ||
| 179 | const code = try self.codeAlloc(elf_file, atom_index); | ||
| 180 | defer elf_file.base.allocator.free(code); | ||
| 181 | try atom.scanRelocs(elf_file, code, undefs); | ||
| 182 | } else try atom.scanRelocs(elf_file, null, undefs); | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | pub fn resetGlobals(self: *ZigModule, elf_file: *Elf) void { | ||
| 187 | for (self.globals()) |index| { | ||
| 188 | const global = elf_file.symbol(index); | ||
| 189 | const off = global.name_offset; | ||
| 190 | global.* = .{}; | ||
| 191 | global.name_offset = off; | ||
| 192 | } | ||
| 193 | } | ||
| 194 | |||
| 195 | pub fn markLive(self: *ZigModule, elf_file: *Elf) void { | ||
| 196 | for (self.globals(), 0..) |index, i| { | ||
| 197 | const esym = self.global_esyms.items(.elf_sym)[i]; | ||
| 198 | if (esym.st_bind() == elf.STB_WEAK) continue; | ||
| 199 | |||
| 200 | const global = elf_file.symbol(index); | ||
| 201 | const file = global.file(elf_file) orelse continue; | ||
| 202 | const should_keep = esym.st_shndx == elf.SHN_UNDEF or | ||
| 203 | (esym.st_shndx == elf.SHN_COMMON and global.elfSym(elf_file).st_shndx != elf.SHN_COMMON); | ||
| 204 | if (should_keep and !file.isAlive()) { | ||
| 205 | file.setAlive(); | ||
| 206 | file.markLive(elf_file); | ||
| 207 | } | ||
| 208 | } | ||
| 209 | } | ||
| 210 | |||
| 211 | pub fn updateSymtabSize(self: *ZigModule, elf_file: *Elf) void { | ||
| 212 | for (self.locals()) |local_index| { | ||
| 213 | const local = elf_file.symbol(local_index); | ||
| 214 | const esym = local.elfSym(elf_file); | ||
| 215 | switch (esym.st_type()) { | ||
| 216 | elf.STT_SECTION, elf.STT_NOTYPE => { | ||
| 217 | local.flags.output_symtab = false; | ||
| 218 | continue; | ||
| 219 | }, | ||
| 220 | else => {}, | ||
| 221 | } | ||
| 222 | local.flags.output_symtab = true; | ||
| 223 | self.output_symtab_size.nlocals += 1; | ||
| 224 | } | ||
| 225 | |||
| 226 | for (self.globals()) |global_index| { | ||
| 227 | const global = elf_file.symbol(global_index); | ||
| 228 | if (global.file(elf_file)) |file| if (file.index() != self.index) { | ||
| 229 | global.flags.output_symtab = false; | ||
| 230 | continue; | ||
| 231 | }; | ||
| 232 | global.flags.output_symtab = true; | ||
| 233 | if (global.isLocal()) { | ||
| 234 | self.output_symtab_size.nlocals += 1; | ||
| 235 | } else { | ||
| 236 | self.output_symtab_size.nglobals += 1; | ||
| 237 | } | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | pub fn writeSymtab(self: *ZigModule, elf_file: *Elf, ctx: anytype) void { | ||
| 242 | var ilocal = ctx.ilocal; | ||
| 243 | for (self.locals()) |local_index| { | ||
| 244 | const local = elf_file.symbol(local_index); | ||
| 245 | if (!local.flags.output_symtab) continue; | ||
| 246 | local.setOutputSym(elf_file, &ctx.symtab[ilocal]); | ||
| 247 | ilocal += 1; | ||
| 248 | } | ||
| 249 | |||
| 250 | var iglobal = ctx.iglobal; | ||
| 251 | for (self.globals()) |global_index| { | ||
| 252 | const global = elf_file.symbol(global_index); | ||
| 253 | if (global.file(elf_file)) |file| if (file.index() != self.index) continue; | ||
| 254 | if (!global.flags.output_symtab) continue; | ||
| 255 | if (global.isLocal()) { | ||
| 256 | global.setOutputSym(elf_file, &ctx.symtab[ilocal]); | ||
| 257 | ilocal += 1; | ||
| 258 | } else { | ||
| 259 | global.setOutputSym(elf_file, &ctx.symtab[iglobal]); | ||
| 260 | iglobal += 1; | ||
| 261 | } | ||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 265 | pub fn symbol(self: *ZigModule, index: Symbol.Index) Symbol.Index { | ||
| 266 | const is_global = index & global_symbol_bit != 0; | ||
| 267 | const actual_index = index & symbol_mask; | ||
| 268 | if (is_global) return self.global_symbols.items[actual_index]; | ||
| 269 | return self.local_symbols.items[actual_index]; | ||
| 270 | } | ||
| 271 | |||
| 272 | pub fn elfSym(self: *ZigModule, index: Symbol.Index) *elf.Elf64_Sym { | ||
| 273 | const is_global = index & global_symbol_bit != 0; | ||
| 274 | const actual_index = index & symbol_mask; | ||
| 275 | if (is_global) return &self.global_esyms.items(.elf_sym)[actual_index]; | ||
| 276 | return &self.local_esyms.items(.elf_sym)[actual_index]; | ||
| 277 | } | ||
| 278 | |||
| 279 | pub fn locals(self: *ZigModule) []const Symbol.Index { | ||
| 280 | return self.local_symbols.items; | ||
| 281 | } | ||
| 282 | |||
| 283 | pub fn globals(self: *ZigModule) []const Symbol.Index { | ||
| 284 | return self.global_symbols.items; | ||
| 285 | } | ||
| 286 | |||
| 287 | pub fn asFile(self: *ZigModule) File { | ||
| 288 | return .{ .zig_object = self }; | ||
| 289 | } | ||
| 290 | |||
| 291 | /// Returns atom's code. | ||
| 292 | /// Caller owns the memory. | ||
| 293 | pub fn codeAlloc(self: ZigModule, elf_file: *Elf, atom_index: Atom.Index) ![]u8 { | ||
| 294 | const gpa = elf_file.base.allocator; | ||
| 295 | const atom = elf_file.atom(atom_index).?; | ||
| 296 | assert(atom.file_index == self.index); | ||
| 297 | const shdr = &elf_file.shdrs.items[atom.outputShndx().?]; | ||
| 298 | const file_offset = shdr.sh_offset + atom.value - shdr.sh_addr; | ||
| 299 | const size = std.math.cast(usize, atom.size) orelse return error.Overflow; | ||
| 300 | const code = try gpa.alloc(u8, size); | ||
| 301 | errdefer gpa.free(code); | ||
| 302 | const amt = try elf_file.base.file.?.preadAll(code, file_offset); | ||
| 303 | if (amt != code.len) { | ||
| 304 | log.err("fetching code for {s} failed", .{atom.name(elf_file)}); | ||
| 305 | return error.InputOutput; | ||
| 306 | } | ||
| 307 | return code; | ||
| 308 | } | ||
| 309 | |||
| 310 | pub fn fmtSymtab(self: *ZigModule, elf_file: *Elf) std.fmt.Formatter(formatSymtab) { | ||
| 311 | return .{ .data = .{ | ||
| 312 | .self = self, | ||
| 313 | .elf_file = elf_file, | ||
| 314 | } }; | ||
| 315 | } | ||
| 316 | |||
| 317 | const FormatContext = struct { | ||
| 318 | self: *ZigModule, | ||
| 319 | elf_file: *Elf, | ||
| 320 | }; | ||
| 321 | |||
| 322 | fn formatSymtab( | ||
| 323 | ctx: FormatContext, | ||
| 324 | comptime unused_fmt_string: []const u8, | ||
| 325 | options: std.fmt.FormatOptions, | ||
| 326 | writer: anytype, | ||
| 327 | ) !void { | ||
| 328 | _ = unused_fmt_string; | ||
| 329 | _ = options; | ||
| 330 | try writer.writeAll(" locals\n"); | ||
| 331 | for (ctx.self.locals()) |index| { | ||
| 332 | const local = ctx.elf_file.symbol(index); | ||
| 333 | try writer.print(" {}\n", .{local.fmt(ctx.elf_file)}); | ||
| 334 | } | ||
| 335 | try writer.writeAll(" globals\n"); | ||
| 336 | for (ctx.self.globals()) |index| { | ||
| 337 | const global = ctx.elf_file.symbol(index); | ||
| 338 | try writer.print(" {}\n", .{global.fmt(ctx.elf_file)}); | ||
| 339 | } | ||
| 340 | } | ||
| 341 | |||
| 342 | pub fn fmtAtoms(self: *ZigModule, elf_file: *Elf) std.fmt.Formatter(formatAtoms) { | ||
| 343 | return .{ .data = .{ | ||
| 344 | .self = self, | ||
| 345 | .elf_file = elf_file, | ||
| 346 | } }; | ||
| 347 | } | ||
| 348 | |||
| 349 | fn formatAtoms( | ||
| 350 | ctx: FormatContext, | ||
| 351 | comptime unused_fmt_string: []const u8, | ||
| 352 | options: std.fmt.FormatOptions, | ||
| 353 | writer: anytype, | ||
| 354 | ) !void { | ||
| 355 | _ = unused_fmt_string; | ||
| 356 | _ = options; | ||
| 357 | try writer.writeAll(" atoms\n"); | ||
| 358 | for (ctx.self.atoms.items) |atom_index| { | ||
| 359 | const atom = ctx.elf_file.atom(atom_index) orelse continue; | ||
| 360 | try writer.print(" {}\n", .{atom.fmt(ctx.elf_file)}); | ||
| 361 | } | ||
| 362 | } | ||
| 363 | |||
| 364 | const ElfSym = struct { | ||
| 365 | elf_sym: elf.Elf64_Sym, | ||
| 366 | shndx: u32 = elf.SHN_UNDEF, | ||
| 367 | }; | ||
| 368 | |||
| 369 | const assert = std.debug.assert; | ||
| 370 | const std = @import("std"); | ||
| 371 | const elf = std.elf; | ||
| 372 | const log = std.log.scoped(.link); | ||
| 373 | |||
| 374 | const Allocator = std.mem.Allocator; | ||
| 375 | const Atom = @import("Atom.zig"); | ||
| 376 | const Elf = @import("../Elf.zig"); | ||
| 377 | const File = @import("file.zig").File; | ||
| 378 | const Module = @import("../../Module.zig"); | ||
| 379 | const Object = @import("Object.zig"); | ||
| 380 | const Symbol = @import("Symbol.zig"); | ||
| 381 | const ZigModule = @This(); | ||
src/link/Elf/file.zig+7-7| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | pub const File = union(enum) { | 1 | pub const File = union(enum) { |
| 2 | zig_module: *ZigModule, | 2 | zig_object: *ZigObject, |
| 3 | linker_defined: *LinkerDefined, | 3 | linker_defined: *LinkerDefined, |
| 4 | object: *Object, | 4 | object: *Object, |
| 5 | shared_object: *SharedObject, | 5 | shared_object: *SharedObject, |
| ... | @@ -23,7 +23,7 @@ pub const File = union(enum) { | ... | @@ -23,7 +23,7 @@ pub const File = union(enum) { |
| 23 | _ = unused_fmt_string; | 23 | _ = unused_fmt_string; |
| 24 | _ = options; | 24 | _ = options; |
| 25 | switch (file) { | 25 | switch (file) { |
| 26 | .zig_module => |x| try writer.print("{s}", .{x.path}), | 26 | .zig_object => |x| try writer.print("{s}", .{x.path}), |
| 27 | .linker_defined => try writer.writeAll("(linker defined)"), | 27 | .linker_defined => try writer.writeAll("(linker defined)"), |
| 28 | .object => |x| try writer.print("{}", .{x.fmtPath()}), | 28 | .object => |x| try writer.print("{}", .{x.fmtPath()}), |
| 29 | .shared_object => |x| try writer.writeAll(x.path), | 29 | .shared_object => |x| try writer.writeAll(x.path), |
| ... | @@ -32,7 +32,7 @@ pub const File = union(enum) { | ... | @@ -32,7 +32,7 @@ pub const File = union(enum) { |
| 32 | 32 | ||
| 33 | pub fn isAlive(file: File) bool { | 33 | pub fn isAlive(file: File) bool { |
| 34 | return switch (file) { | 34 | return switch (file) { |
| 35 | .zig_module => true, | 35 | .zig_object => true, |
| 36 | .linker_defined => true, | 36 | .linker_defined => true, |
| 37 | inline else => |x| x.alive, | 37 | inline else => |x| x.alive, |
| 38 | }; | 38 | }; |
| ... | @@ -76,7 +76,7 @@ pub const File = union(enum) { | ... | @@ -76,7 +76,7 @@ pub const File = union(enum) { |
| 76 | 76 | ||
| 77 | pub fn setAlive(file: File) void { | 77 | pub fn setAlive(file: File) void { |
| 78 | switch (file) { | 78 | switch (file) { |
| 79 | .zig_module, .linker_defined => {}, | 79 | .zig_object, .linker_defined => {}, |
| 80 | inline else => |x| x.alive = true, | 80 | inline else => |x| x.alive = true, |
| 81 | } | 81 | } |
| 82 | } | 82 | } |
| ... | @@ -92,7 +92,7 @@ pub const File = union(enum) { | ... | @@ -92,7 +92,7 @@ pub const File = union(enum) { |
| 92 | return switch (file) { | 92 | return switch (file) { |
| 93 | .linker_defined => unreachable, | 93 | .linker_defined => unreachable, |
| 94 | .shared_object => unreachable, | 94 | .shared_object => unreachable, |
| 95 | .zig_module => |x| x.atoms.items, | 95 | .zig_object => |x| x.atoms.items, |
| 96 | .object => |x| x.atoms.items, | 96 | .object => |x| x.atoms.items, |
| 97 | }; | 97 | }; |
| 98 | } | 98 | } |
| ... | @@ -115,7 +115,7 @@ pub const File = union(enum) { | ... | @@ -115,7 +115,7 @@ pub const File = union(enum) { |
| 115 | 115 | ||
| 116 | pub const Entry = union(enum) { | 116 | pub const Entry = union(enum) { |
| 117 | null: void, | 117 | null: void, |
| 118 | zig_module: ZigModule, | 118 | zig_object: ZigObject, |
| 119 | linker_defined: LinkerDefined, | 119 | linker_defined: LinkerDefined, |
| 120 | object: Object, | 120 | object: Object, |
| 121 | shared_object: SharedObject, | 121 | shared_object: SharedObject, |
| ... | @@ -132,4 +132,4 @@ const LinkerDefined = @import("LinkerDefined.zig"); | ... | @@ -132,4 +132,4 @@ const LinkerDefined = @import("LinkerDefined.zig"); |
| 132 | const Object = @import("Object.zig"); | 132 | const Object = @import("Object.zig"); |
| 133 | const SharedObject = @import("SharedObject.zig"); | 133 | const SharedObject = @import("SharedObject.zig"); |
| 134 | const Symbol = @import("Symbol.zig"); | 134 | const Symbol = @import("Symbol.zig"); |
| 135 | const ZigModule = @import("ZigModule.zig"); | 135 | const ZigObject = @import("ZigObject.zig"); |