aboutsummaryrefslogtreecommitdiff
path: root/src/link/Wasm/Object.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/link/Wasm/Object.zig')
-rw-r--r--src/link/Wasm/Object.zig75
1 files changed, 39 insertions, 36 deletions
diff --git a/src/link/Wasm/Object.zig b/src/link/Wasm/Object.zig
index aaa99292bc..de6f0500e8 100644
--- a/src/link/Wasm/Object.zig
+++ b/src/link/Wasm/Object.zig
@@ -9,6 +9,7 @@ const std = @import("std");
const Wasm = @import("../Wasm.zig");
const Symbol = @import("Symbol.zig");
const Alignment = types.Alignment;
+const File = @import("file.zig").File;
const Allocator = std.mem.Allocator;
const leb = std.leb;
@@ -16,12 +17,14 @@ const meta = std.meta;
const log = std.log.scoped(.link);
+/// Index into the list of relocatable object files within the linker driver.
+index: File.Index = .null,
/// Wasm spec version used for this `Object`
version: u32 = 0,
/// The file descriptor that represents the wasm object file.
file: ?std.fs.File = null,
/// Name (read path) of the object file.
-name: []const u8,
+path: []const u8,
/// Parsed type section
func_types: []const std.wasm.Type = &.{},
/// A list of all imports for this module
@@ -64,6 +67,12 @@ relocatable_data: std.AutoHashMapUnmanaged(RelocatableData.Tag, []RelocatableDat
/// import name, module name and export names. Each string will be deduplicated
/// and returns an offset into the table.
string_table: Wasm.StringTable = .{},
+/// Amount of functions in the `import` sections.
+imported_functions_count: u32 = 0,
+/// Amount of globals in the `import` section.
+imported_globals_count: u32 = 0,
+/// Amount of tables in the `import` section.
+imported_tables_count: u32 = 0,
/// Represents a single item within a section (depending on its `type`)
const RelocatableData = struct {
@@ -121,7 +130,7 @@ pub const InitError = error{NotObjectFile} || ParseError || std.fs.File.ReadErro
pub fn create(gpa: Allocator, file: std.fs.File, name: []const u8, maybe_max_size: ?usize) InitError!Object {
var object: Object = .{
.file = file,
- .name = try gpa.dupe(u8, name),
+ .path = try gpa.dupe(u8, name),
};
var is_object_file: bool = false;
@@ -199,29 +208,17 @@ pub fn deinit(object: *Object, gpa: Allocator) void {
/// Finds the import within the list of imports from a given kind and index of that kind.
/// Asserts the import exists
-pub fn findImport(object: *const Object, import_kind: std.wasm.ExternalKind, index: u32) types.Import {
+pub fn findImport(object: *const Object, index: u32) types.Import {
+ const sym = object.symtable[index];
var i: u32 = 0;
return for (object.imports) |import| {
- if (std.meta.activeTag(import.kind) == import_kind) {
+ if (std.meta.activeTag(import.kind) == sym.tag) {
if (i == index) return import;
i += 1;
}
} else unreachable; // Only existing imports are allowed to be found
}
-/// Counts the entries of imported `kind` and returns the result
-pub fn importedCountByKind(object: *const Object, kind: std.wasm.ExternalKind) u32 {
- var i: u32 = 0;
- return for (object.imports) |imp| {
- if (@as(std.wasm.ExternalKind, imp.kind) == kind) i += 1;
- } else i;
-}
-
-/// From a given `RelocatableDate`, find the corresponding debug section name
-pub fn getDebugName(object: *const Object, relocatable_data: RelocatableData) []const u8 {
- return object.string_table.get(relocatable_data.index);
-}
-
/// Checks if the object file is an MVP version.
/// When that's the case, we check if there's an import table definiton with its name
/// set to '__indirect_function_table". When that's also the case,
@@ -427,16 +424,25 @@ fn Parser(comptime ReaderType: type) type {
const kind = try readEnum(std.wasm.ExternalKind, reader);
const kind_value: std.wasm.Import.Kind = switch (kind) {
- .function => .{ .function = try readLeb(u32, reader) },
+ .function => val: {
+ parser.object.imported_functions_count += 1;
+ break :val .{ .function = try readLeb(u32, reader) };
+ },
.memory => .{ .memory = try readLimits(reader) },
- .global => .{ .global = .{
- .valtype = try readEnum(std.wasm.Valtype, reader),
- .mutable = (try reader.readByte()) == 0x01,
- } },
- .table => .{ .table = .{
- .reftype = try readEnum(std.wasm.RefType, reader),
- .limits = try readLimits(reader),
- } },
+ .global => val: {
+ parser.object.imported_globals_count += 1;
+ break :val .{ .global = .{
+ .valtype = try readEnum(std.wasm.Valtype, reader),
+ .mutable = (try reader.readByte()) == 0x01,
+ } };
+ },
+ .table => val: {
+ parser.object.imported_tables_count += 1;
+ break :val .{ .table = .{
+ .reftype = try readEnum(std.wasm.RefType, reader),
+ .limits = try readLimits(reader),
+ } };
+ },
};
import.* = .{
@@ -904,7 +910,7 @@ fn assertEnd(reader: anytype) !void {
}
/// Parses an object file into atoms, for code and data sections
-pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32, wasm: *Wasm) !Atom.Index {
+pub fn parseSymbolIntoAtom(object: *Object, wasm: *Wasm, symbol_index: u32) !Atom.Index {
const comp = wasm.base.comp;
const gpa = comp.gpa;
const symbol = &object.symtable[symbol_index];
@@ -922,19 +928,16 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32
},
else => unreachable,
};
- const final_index = try wasm.getMatchingSegment(object_index, symbol_index);
- const atom_index = @as(Atom.Index, @intCast(wasm.managed_atoms.items.len));
- const atom = try wasm.managed_atoms.addOne(gpa);
- atom.* = Atom.empty;
+ const final_index = try wasm.getMatchingSegment(object.index, symbol_index);
+ const atom_index = try wasm.createAtom(symbol_index, object.index);
try wasm.appendAtomAtIndex(final_index, atom_index);
- atom.sym_index = symbol_index;
- atom.file = object_index;
+ const atom = wasm.getAtomPtr(atom_index);
atom.size = relocatable_data.size;
atom.alignment = relocatable_data.getAlignment(object);
atom.code = std.ArrayListUnmanaged(u8).fromOwnedSlice(relocatable_data.data[0..relocatable_data.size]);
atom.original_offset = relocatable_data.offset;
- try wasm.symbol_atom.putNoClobber(gpa, atom.symbolLoc(), atom_index);
+
const segment: *Wasm.Segment = &wasm.segments.items[final_index];
if (relocatable_data.type == .data) { //code section and custom sections are 1-byte aligned
segment.alignment = segment.alignment.max(atom.alignment);
@@ -952,7 +955,7 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32
.R_WASM_TABLE_INDEX_SLEB64,
=> {
try wasm.function_table.put(gpa, .{
- .file = object_index,
+ .file = object.index,
.index = reloc.index,
}, 0);
},
@@ -963,7 +966,7 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32
if (sym.tag != .global) {
try wasm.got_symbols.append(
gpa,
- .{ .file = object_index, .index = reloc.index },
+ .{ .file = object.index, .index = reloc.index },
);
}
},