Commit 55fa8a04f1
Changed files (3)
src
link
src/link/Elf/file.zig
@@ -204,6 +204,31 @@ pub const File = union(enum) {
};
}
+ pub fn updateArStrtab(file: File, allocator: Allocator, ar_strtab: *Archive.ArStrtab) !void {
+ return switch (file) {
+ .zig_object => |x| x.updateArStrtab(allocator, ar_strtab),
+ .object => @panic("TODO"),
+ inline else => unreachable,
+ };
+ }
+
+ pub fn updateArSize(file: File, elf_file: *Elf) void {
+ return switch (file) {
+ .zig_object => |x| x.updateArSize(elf_file),
+ .object => @panic("TODO"),
+ inline else => unreachable,
+ };
+ }
+
+ pub fn writeAr(file: File, elf_file: *Elf, writer: anytype) !void {
+ return switch (file) {
+ .zig_object => |x| x.writeAr(elf_file, writer),
+ // .object => |x| x.writeAr(elf_file, writer),
+ .object => @panic("TODO"),
+ inline else => unreachable,
+ };
+ }
+
pub const Index = u32;
pub const Entry = union(enum) {
src/link/Elf/Object.zig
@@ -20,6 +20,7 @@ alive: bool = true,
num_dynrelocs: u32 = 0,
output_symtab_size: Elf.SymtabSize = .{},
+output_ar_state: Archive.ArState = .{},
pub fn isObject(path: []const u8) !bool {
const file = try std.fs.cwd().openFile(path, .{});
@@ -924,6 +925,7 @@ const math = std.math;
const mem = std.mem;
const Allocator = mem.Allocator;
+const Archive = @import("Archive.zig");
const Atom = @import("Atom.zig");
const Cie = eh_frame.Cie;
const Elf = @import("../Elf.zig");
src/link/Elf.zig
@@ -939,12 +939,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
} else null;
const gc_sections = self.base.options.gc_sections orelse false;
- if (self.isRelocatable() and self.zig_object_index == null) {
- if (self.isStaticLib()) {
- var err = try self.addErrorWithNotes(0);
- try err.addMsg(self, "fatal linker error: emitting static libs unimplemented", .{});
- return;
- }
+ if (self.isObject() and self.zig_object_index == null) {
// TODO this will become -r route I guess. For now, just copy the object file.
assert(self.base.file == null); // TODO uncomment once we implement -r
const the_object_path = blk: {
@@ -1555,15 +1550,18 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
try self.writeElfHeader();
}
- // TODO parse positionals that we want to make part of the archive
-
- // TODO update ar symtab from parsed positionals
+ var files = std.ArrayList(File.Index).init(gpa);
+ defer files.deinit();
+ try files.ensureTotalCapacityPrecise(self.objects.items.len + 1);
+ if (self.zigObjectPtr()) |zig_object| files.appendAssumeCapacity(zig_object.index);
+ for (self.objects.items) |index| files.appendAssumeCapacity(index);
+ // Update ar symtab from parsed objects
var ar_symtab: Archive.ArSymtab = .{};
defer ar_symtab.deinit(gpa);
- if (self.zigObjectPtr()) |zig_object| {
- try zig_object.updateArSymtab(&ar_symtab, self);
+ for (files.items) |index| {
+ try self.file(index).?.updateArSymtab(&ar_symtab, self);
}
ar_symtab.sort();
@@ -1572,9 +1570,10 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
var ar_strtab: Archive.ArStrtab = .{};
defer ar_strtab.deinit(gpa);
- if (self.zigObjectPtr()) |zig_object| {
- try zig_object.updateArStrtab(gpa, &ar_strtab);
- zig_object.updateArSize(self);
+ for (files.items) |index| {
+ const file_ptr = self.file(index).?;
+ try file_ptr.updateArStrtab(gpa, &ar_strtab);
+ file_ptr.updateArSize(self);
}
// Update file offsets of contributing objects.
@@ -1587,10 +1586,16 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
pos += @sizeOf(Archive.ar_hdr) + ar_strtab.size();
}
- if (self.zigObjectPtr()) |zig_object| {
+ for (files.items) |index| {
+ const file_ptr = self.file(index).?;
+ const state = switch (file_ptr) {
+ .zig_object => |x| &x.output_ar_state,
+ .object => |x| &x.output_ar_state,
+ else => unreachable,
+ };
pos = mem.alignForward(usize, pos, 2);
- zig_object.output_ar_state.file_off = pos;
- pos += @sizeOf(Archive.ar_hdr) + (math.cast(usize, zig_object.output_ar_state.size) orelse return error.Overflow);
+ state.file_off = pos;
+ pos += @sizeOf(Archive.ar_hdr) + (math.cast(usize, state.size) orelse return error.Overflow);
}
break :blk pos;
@@ -1618,9 +1623,9 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
}
// Write object files
- if (self.zigObjectPtr()) |zig_object| {
+ for (files.items) |index| {
if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
- try zig_object.writeAr(self, buffer.writer());
+ try self.file(index).?.writeAr(self, buffer.writer());
}
assert(buffer.items.len == total_size);