From 241180216f92c86f833910d73e1c86f54ae940e4 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Fri, 27 May 2022 19:31:34 +0200 Subject: [PATCH] wasm-linker: Parse object file from the archive Rather than finding the original object file, we seekTo to the object file's position within the archive file, and from there open a new file handle. This file handle is passed to the `Object` parser which will create the object. --- src/link/Wasm/Archive.zig | 15 ++++++++------- src/link/Wasm/Object.zig | 7 ++++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/link/Wasm/Archive.zig b/src/link/Wasm/Archive.zig index 9169a7effa..e214d1b124 100644 --- a/src/link/Wasm/Archive.zig +++ b/src/link/Wasm/Archive.zig @@ -181,6 +181,8 @@ pub fn parseObject(self: Archive, allocator: Allocator, file_offset: u32) !Objec try self.file.seekTo(file_offset); const reader = self.file.reader(); const header = try reader.readStruct(ar_hdr); + const current_offset = try self.file.getPos(); + try self.file.seekTo(0); if (!mem.eql(u8, &header.ar_fmag, ARFMAG)) { log.err("invalid header delimiter: expected '{s}', found '{s}'", .{ ARFMAG, header.ar_fmag }); @@ -191,16 +193,15 @@ pub fn parseObject(self: Archive, allocator: Allocator, file_offset: u32) !Objec defer allocator.free(object_name); const name = name: { - if (object_name.len == 0) { - break :name try std.fmt.allocPrint(allocator, "{s}.o", .{self.name}); - } - const base_path = std.fs.path.dirname(self.name); - break :name try std.fmt.allocPrint(allocator, "{s}/{s}.o", .{ base_path, object_name }); + var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined; + const path = try std.os.realpath(self.name, &buffer); + break :name try std.fmt.allocPrint(allocator, "{s}({s})", .{ path, object_name }); }; + defer allocator.free(name); - log.debug(" parsing object file '{s}' from archive\n", .{name}); - const object_file = try std.fs.cwd().openFile(name, .{}); + const object_file = try std.fs.cwd().openFile(self.name, .{}); errdefer object_file.close(); + try object_file.seekTo(current_offset); return Object.create(allocator, object_file, name); } diff --git a/src/link/Wasm/Object.zig b/src/link/Wasm/Object.zig index 6fa451af09..9dba838d27 100644 --- a/src/link/Wasm/Object.zig +++ b/src/link/Wasm/Object.zig @@ -68,7 +68,7 @@ string_table: Wasm.StringTable = .{}, const RelocatableData = struct { /// The type of the relocatable data type: enum { data, code, custom }, - /// Pointer to the data of the segment, where it's length is written to `size` + /// Pointer to the data of the segment, where its length is written to `size` data: [*]u8, /// The size in bytes of the data representing the segment within the section size: u32, @@ -105,10 +105,10 @@ pub const InitError = error{NotObjectFile} || ParseError || std.fs.File.ReadErro /// Initializes a new `Object` from a wasm object file. /// This also parses and verifies the object file. -pub fn create(gpa: Allocator, file: std.fs.File, path: []const u8) InitError!Object { +pub fn create(gpa: Allocator, file: std.fs.File, name: []const u8) InitError!Object { var object: Object = .{ .file = file, - .name = path, + .name = try gpa.dupe(u8, name), }; var is_object_file: bool = false; @@ -154,6 +154,7 @@ pub fn deinit(self: *Object, gpa: Allocator) void { } gpa.free(self.relocatable_data); self.string_table.deinit(gpa); + gpa.free(self.name); self.* = undefined; }