authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-05-27 19:31:34+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-06-24 08:12:17+02:00
log241180216f92c86f833910d73e1c86f54ae940e4
treedbbf933551c394f573be87bf814dc68906bab765
parentc9f929a18b705451e9c2c81f01019575de8bf5fd

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.

2 files changed, 12 insertions(+), 10 deletions(-)

src/link/Wasm/Archive.zig+8-7
...@@ -181,6 +181,8 @@ pub fn parseObject(self: Archive, allocator: Allocator, file_offset: u32) !Objec...@@ -181,6 +181,8 @@ pub fn parseObject(self: Archive, allocator: Allocator, file_offset: u32) !Objec
181 try self.file.seekTo(file_offset);181 try self.file.seekTo(file_offset);
182 const reader = self.file.reader();182 const reader = self.file.reader();
183 const header = try reader.readStruct(ar_hdr);183 const header = try reader.readStruct(ar_hdr);
184 const current_offset = try self.file.getPos();
185 try self.file.seekTo(0);
184186
185 if (!mem.eql(u8, &header.ar_fmag, ARFMAG)) {187 if (!mem.eql(u8, &header.ar_fmag, ARFMAG)) {
186 log.err("invalid header delimiter: expected '{s}', found '{s}'", .{ ARFMAG, header.ar_fmag });188 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...@@ -191,16 +193,15 @@ pub fn parseObject(self: Archive, allocator: Allocator, file_offset: u32) !Objec
191 defer allocator.free(object_name);193 defer allocator.free(object_name);
192194
193 const name = name: {195 const name = name: {
194 if (object_name.len == 0) {196 var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
195 break :name try std.fmt.allocPrint(allocator, "{s}.o", .{self.name});197 const path = try std.os.realpath(self.name, &buffer);
196 }198 break :name try std.fmt.allocPrint(allocator, "{s}({s})", .{ path, object_name });
197 const base_path = std.fs.path.dirname(self.name);
198 break :name try std.fmt.allocPrint(allocator, "{s}/{s}.o", .{ base_path, object_name });
199 };199 };
200 defer allocator.free(name);
200201
201 log.debug(" parsing object file '{s}' from archive\n", .{name});202 const object_file = try std.fs.cwd().openFile(self.name, .{});
202 const object_file = try std.fs.cwd().openFile(name, .{});
203 errdefer object_file.close();203 errdefer object_file.close();
204204
205 try object_file.seekTo(current_offset);
205 return Object.create(allocator, object_file, name);206 return Object.create(allocator, object_file, name);
206}207}
src/link/Wasm/Object.zig+4-3
...@@ -68,7 +68,7 @@ string_table: Wasm.StringTable = .{},...@@ -68,7 +68,7 @@ string_table: Wasm.StringTable = .{},
68const RelocatableData = struct {68const RelocatableData = struct {
69 /// The type of the relocatable data69 /// The type of the relocatable data
70 type: enum { data, code, custom },70 type: enum { data, code, custom },
71 /// Pointer to the data of the segment, where it's length is written to `size`71 /// Pointer to the data of the segment, where its length is written to `size`
72 data: [*]u8,72 data: [*]u8,
73 /// The size in bytes of the data representing the segment within the section73 /// The size in bytes of the data representing the segment within the section
74 size: u32,74 size: u32,
...@@ -105,10 +105,10 @@ pub const InitError = error{NotObjectFile} || ParseError || std.fs.File.ReadErro...@@ -105,10 +105,10 @@ pub const InitError = error{NotObjectFile} || ParseError || std.fs.File.ReadErro
105105
106/// Initializes a new `Object` from a wasm object file.106/// Initializes a new `Object` from a wasm object file.
107/// This also parses and verifies the object file.107/// This also parses and verifies the object file.
108pub fn create(gpa: Allocator, file: std.fs.File, path: []const u8) InitError!Object {108pub fn create(gpa: Allocator, file: std.fs.File, name: []const u8) InitError!Object {
109 var object: Object = .{109 var object: Object = .{
110 .file = file,110 .file = file,
111 .name = path,111 .name = try gpa.dupe(u8, name),
112 };112 };
113113
114 var is_object_file: bool = false;114 var is_object_file: bool = false;
...@@ -154,6 +154,7 @@ pub fn deinit(self: *Object, gpa: Allocator) void {...@@ -154,6 +154,7 @@ pub fn deinit(self: *Object, gpa: Allocator) void {
154 }154 }
155 gpa.free(self.relocatable_data);155 gpa.free(self.relocatable_data);
156 self.string_table.deinit(gpa);156 self.string_table.deinit(gpa);
157 gpa.free(self.name);
157 self.* = undefined;158 self.* = undefined;
158}159}
159160