diff options
| author | Luuk de Gram <luuk@degram.dev> | 2024-01-15 16:43:22 +0100 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2024-02-29 15:23:03 +0100 |
| commit | 12505c6d3d4ccfc859b67e4b43c5b3844bebb475 (patch) | |
| tree | 37c53b1a33ebfc4f7f72ad54254b3b4556ee353e /src/link | |
| parent | f6896ef2180709fedeb5bafde3fe58ca6d06aa3a (diff) | |
| download | zig-12505c6d3d4ccfc859b67e4b43c5b3844bebb475.tar.gz zig-12505c6d3d4ccfc859b67e4b43c5b3844bebb475.zip | |
wasm: store `File.Index` on the Atom
Also, consolidate the creation of Atoms so they all use `createAtom`.
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/Wasm.zig | 42 | ||||
| -rw-r--r-- | src/link/Wasm/Atom.zig | 56 | ||||
| -rw-r--r-- | src/link/Wasm/ZigObject.zig | 13 |
3 files changed, 44 insertions, 67 deletions
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index fb808d79fc..55e08babd2 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -569,6 +569,7 @@ pub fn createEmpty( if (!use_llvm) { const index: File.Index = @enumFromInt(wasm.files.len); var zig_object: ZigObject = .{ + .index = index, .path = try std.fmt.allocPrint(gpa, "{s}.o", .{std.fs.path.stem(zcu.main_mod.root_src_path)}), .stack_pointer_sym = undefined, }; @@ -663,12 +664,11 @@ fn parseObjectFile(wasm: *Wasm, path: []const u8) !bool { } /// Creates a new empty `Atom` and returns its `Atom.Index` -pub fn createAtom(wasm: *Wasm, sym_index: u32) !Atom.Index { +pub fn createAtom(wasm: *Wasm, sym_index: u32, file_index: File.Index) !Atom.Index { const gpa = wasm.base.comp.gpa; const index: Atom.Index = @intCast(wasm.managed_atoms.items.len); const atom = try wasm.managed_atoms.addOne(gpa); - atom.* = Atom.empty; - atom.sym_index = sym_index; + atom.* = .{ .file_index = file_index, .sym_index = sym_index }; try wasm.symbol_atom.putNoClobber(gpa, .{ .file = null, .index = sym_index }, index); return index; @@ -1825,20 +1825,11 @@ fn createSyntheticFunction( symbol.index = func_index; // create the atom that will be output into the final binary - const atom_index = @as(Atom.Index, @intCast(wasm.managed_atoms.items.len)); - const atom = try wasm.managed_atoms.addOne(gpa); - atom.* = .{ - .size = @as(u32, @intCast(function_body.items.len)), - .offset = 0, - .sym_index = loc.index, - .file = null, - .alignment = .@"1", - .prev = null, - .code = function_body.moveToUnmanaged(), - .original_offset = 0, - }; + const atom_index = try wasm.createAtom(loc.index, .null); + const atom = wasm.getAtomPtr(atom_index); + atom.code = function_body.moveToUnmanaged(); + atom.size = @intCast(function_body.items.len); try wasm.appendAtomAtIndex(wasm.code_section_index.?, atom_index); - try wasm.symbol_atom.putNoClobber(gpa, loc, atom_index); } /// Unlike `createSyntheticFunction` this function is to be called by @@ -1856,19 +1847,11 @@ pub fn createFunction( const gpa = wasm.base.comp.gpa; const loc = try wasm.createSyntheticSymbol(symbol_name, .function); - const atom_index: Atom.Index = @intCast(wasm.managed_atoms.items.len); - const atom = try wasm.managed_atoms.addOne(gpa); - atom.* = .{ - .size = @intCast(function_body.items.len), - .offset = 0, - .sym_index = loc.index, - .file = null, - .alignment = .@"1", - .prev = null, - .code = function_body.moveToUnmanaged(), - .relocs = relocations.moveToUnmanaged(), - .original_offset = 0, - }; + const atom_index = try wasm.createAtom(loc.index, wasm.zig_object_index); + const atom = wasm.getAtomPtr(atom_index); + atom.code = function_body.moveToUnmanaged(); + atom.relocs = relocations.moveToUnmanaged(); + atom.size = @intCast(function_body.items.len); const symbol = loc.getSymbol(wasm); symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); // ensure function does not get exported @@ -1878,7 +1861,6 @@ pub fn createFunction( break :idx index; }; try wasm.appendAtomAtIndex(section_index, atom_index); - try wasm.symbol_atom.putNoClobber(gpa, loc, atom_index); try wasm.zigObjectPtr().?.atom_types.put( gpa, atom_index, diff --git a/src/link/Wasm/Atom.zig b/src/link/Wasm/Atom.zig index c8d115b872..fb3d1a5724 100644 --- a/src/link/Wasm/Atom.zig +++ b/src/link/Wasm/Atom.zig @@ -1,55 +1,36 @@ -const Atom = @This(); - -const std = @import("std"); -const types = @import("types.zig"); -const Wasm = @import("../Wasm.zig"); -const Symbol = @import("Symbol.zig"); - -const leb = std.leb; -const log = std.log.scoped(.link); -const mem = std.mem; -const Allocator = mem.Allocator; - +/// Represents the index of the file this atom was generated from. +/// This is 'null' when the atom was generated by a synthetic linker symbol. +file: FileIndex, /// symbol index of the symbol representing this atom sym_index: u32, /// Size of the atom, used to calculate section sizes in the final binary -size: u32, +size: u32 = 0, /// List of relocations belonging to this atom relocs: std.ArrayListUnmanaged(types.Relocation) = .{}, /// Contains the binary data of an atom, which can be non-relocated code: std.ArrayListUnmanaged(u8) = .{}, /// For code this is 1, for data this is set to the highest value of all segments -alignment: Wasm.Alignment, +alignment: Wasm.Alignment = .@"1", /// Offset into the section where the atom lives, this already accounts /// for alignment. -offset: u32, +offset: u32 = 0, /// The original offset within the object file. This value is substracted from /// relocation offsets to determine where in the `data` to rewrite the value -original_offset: u32, -/// Represents the index of the file this atom was generated from. -/// This is 'null' when the atom was generated by a Decl from Zig code. -file: ?u16, +original_offset: u32 = 0, +/// Next atom in relation to this atom. +/// When null, this atom is the last atom +next: ?Atom.Index = null, /// Previous atom in relation to this atom. /// is null when this atom is the first in its order -prev: ?Atom.Index, +prev: ?Atom.Index = null, /// Contains atoms local to a decl, all managed by this `Atom`. /// When the parent atom is being freed, it will also do so for all local atoms. locals: std.ArrayListUnmanaged(Atom.Index) = .{}, -/// Alias to an unsigned 32-bit integer +/// Alias to an unsigned 32-bit integer. +// TODO: Make this a non-exhaustive enum. pub const Index = u32; -/// Represents a default empty wasm `Atom` -pub const empty: Atom = .{ - .alignment = .@"1", - .file = null, - .offset = 0, - .prev = null, - .size = 0, - .sym_index = 0, - .original_offset = 0, -}; - /// Frees all resources owned by this `Atom`. pub fn deinit(atom: *Atom, gpa: std.mem.Allocator) void { atom.relocs.deinit(gpa); @@ -217,3 +198,14 @@ fn thombstone(atom: Atom, wasm: *const Wasm) ?i64 { } return null; } +const leb = std.leb; +const log = std.log.scoped(.link); +const mem = std.mem; +const std = @import("std"); +const types = @import("types.zig"); + +const Allocator = mem.Allocator; +const Atom = @This(); +const FileIndex = @import("file.zig").File.Index; +const Symbol = @import("Symbol.zig"); +const Wasm = @import("../Wasm.zig"); diff --git a/src/link/Wasm/ZigObject.zig b/src/link/Wasm/ZigObject.zig index 8b4d703a34..81eda1e413 100644 --- a/src/link/Wasm/ZigObject.zig +++ b/src/link/Wasm/ZigObject.zig @@ -4,6 +4,8 @@ //! Think about this as fake in-memory Object file for the Zig module. path: []const u8, +/// Index within the list of relocatable objects of the linker driver. +index: File.Index, /// List of all `Decl` that are currently alive. /// Each index maps to the corresponding `Atom.Index`. decls: std.AutoHashMapUnmanaged(InternPool.DeclIndex, Atom.Index) = .{}, @@ -292,7 +294,7 @@ pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_ind const gop = try zig_object.decls.getOrPut(gpa, decl_index); if (!gop.found_existing) { const sym_index = try zig_object.allocateSymbol(gpa); - gop.value_ptr.* = try wasm_file.createAtom(sym_index); + gop.value_ptr.* = try wasm_file.createAtom(sym_index, zig_object.index); const mod = wasm_file.base.comp.module.?; const decl = mod.declPtr(decl_index); const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)); @@ -379,7 +381,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty // Create and initialize a new local symbol and atom const sym_index = try zig_object.allocateSymbol(gpa); - const atom_index = try wasm_file.createAtom(sym_index); + const atom_index = try wasm_file.createAtom(sym_index, zig_object.index); var value_bytes = std.ArrayList(u8).init(gpa); defer value_bytes.deinit(); @@ -432,7 +434,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 { // during `flush` when we know all possible error names. const gpa = wasm_file.base.comp.gpa; const sym_index = try zig_object.allocateSymbol(gpa); - const atom_index = try wasm_file.createAtom(sym_index); + const atom_index = try wasm_file.createAtom(sym_index, zig_object.index); const atom = wasm_file.getAtomPtr(atom_index); const slice_ty = Type.slice_const_u8_sentinel_0; const mod = wasm_file.base.comp.module.?; @@ -468,7 +470,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void { // we create a symbol for the entire region of error names. We then calculate // the pointers into the list using addends which are appended to the relocation. const names_sym_index = try zig_object.allocateSymbol(gpa); - const names_atom_index = try wasm_file.createAtom(names_sym_index); + const names_atom_index = try wasm_file.createAtom(names_sym_index, zig_object.index); const names_atom = wasm_file.getAtomPtr(names_atom_index); names_atom.alignment = .@"1"; const sym_name = try zig_object.string_table.insert(gpa, "__zig_err_names"); @@ -1087,7 +1089,7 @@ pub fn createDebugSectionForIndex(zig_object: *ZigObject, wasm_file: *Wasm, inde try zig_object.appendDummySegment(); const sym_index = try zig_object.allocateSymbol(gpa); - const atom_index = try wasm_file.createAtom(sym_index); + const atom_index = try wasm_file.createAtom(sym_index, zig_object.index); const atom = wasm_file.getAtomPtr(atom_index); zig_object.symbols.items[sym_index] = .{ .tag = .section, @@ -1161,6 +1163,7 @@ const types = @import("types.zig"); const Air = @import("../../Air.zig"); const Atom = @import("Atom.zig"); const Dwarf = @import("../Dwarf.zig"); +const File = @import("file.zig").File; const InternPool = @import("../../InternPool.zig"); const Liveness = @import("../../Liveness.zig"); const Module = @import("../../Module.zig"); |
