authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-05 12:56:17+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-05 12:56:17+01:00
log55fa8a04f1853deb473339cdc610cbf012ae0d61
treee614530b5be669123ed4278d532d7827ae982589
parent5c482361034a0b1575ecb719724c942b5709b449

elf: add hooks for archiving Objects


3 files changed, 51 insertions(+), 19 deletions(-)

src/link/Elf.zig+24-19
...@@ -939,12 +939,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -939,12 +939,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
939 } else null;939 } else null;
940 const gc_sections = self.base.options.gc_sections orelse false;940 const gc_sections = self.base.options.gc_sections orelse false;
941941
942 if (self.isRelocatable() and self.zig_object_index == null) {942 if (self.isObject() and self.zig_object_index == null) {
943 if (self.isStaticLib()) {
944 var err = try self.addErrorWithNotes(0);
945 try err.addMsg(self, "fatal linker error: emitting static libs unimplemented", .{});
946 return;
947 }
948 // TODO this will become -r route I guess. For now, just copy the object file.943 // TODO this will become -r route I guess. For now, just copy the object file.
949 assert(self.base.file == null); // TODO uncomment once we implement -r944 assert(self.base.file == null); // TODO uncomment once we implement -r
950 const the_object_path = blk: {945 const the_object_path = blk: {
...@@ -1555,15 +1550,18 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void...@@ -1555,15 +1550,18 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
1555 try self.writeElfHeader();1550 try self.writeElfHeader();
1556 }1551 }
15571552
1558 // TODO parse positionals that we want to make part of the archive1553 var files = std.ArrayList(File.Index).init(gpa);
15591554 defer files.deinit();
1560 // TODO update ar symtab from parsed positionals1555 try files.ensureTotalCapacityPrecise(self.objects.items.len + 1);
1556 if (self.zigObjectPtr()) |zig_object| files.appendAssumeCapacity(zig_object.index);
1557 for (self.objects.items) |index| files.appendAssumeCapacity(index);
15611558
1559 // Update ar symtab from parsed objects
1562 var ar_symtab: Archive.ArSymtab = .{};1560 var ar_symtab: Archive.ArSymtab = .{};
1563 defer ar_symtab.deinit(gpa);1561 defer ar_symtab.deinit(gpa);
15641562
1565 if (self.zigObjectPtr()) |zig_object| {1563 for (files.items) |index| {
1566 try zig_object.updateArSymtab(&ar_symtab, self);1564 try self.file(index).?.updateArSymtab(&ar_symtab, self);
1567 }1565 }
15681566
1569 ar_symtab.sort();1567 ar_symtab.sort();
...@@ -1572,9 +1570,10 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void...@@ -1572,9 +1570,10 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
1572 var ar_strtab: Archive.ArStrtab = .{};1570 var ar_strtab: Archive.ArStrtab = .{};
1573 defer ar_strtab.deinit(gpa);1571 defer ar_strtab.deinit(gpa);
15741572
1575 if (self.zigObjectPtr()) |zig_object| {1573 for (files.items) |index| {
1576 try zig_object.updateArStrtab(gpa, &ar_strtab);1574 const file_ptr = self.file(index).?;
1577 zig_object.updateArSize(self);1575 try file_ptr.updateArStrtab(gpa, &ar_strtab);
1576 file_ptr.updateArSize(self);
1578 }1577 }
15791578
1580 // Update file offsets of contributing objects.1579 // Update file offsets of contributing objects.
...@@ -1587,10 +1586,16 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void...@@ -1587,10 +1586,16 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
1587 pos += @sizeOf(Archive.ar_hdr) + ar_strtab.size();1586 pos += @sizeOf(Archive.ar_hdr) + ar_strtab.size();
1588 }1587 }
15891588
1590 if (self.zigObjectPtr()) |zig_object| {1589 for (files.items) |index| {
1590 const file_ptr = self.file(index).?;
1591 const state = switch (file_ptr) {
1592 .zig_object => |x| &x.output_ar_state,
1593 .object => |x| &x.output_ar_state,
1594 else => unreachable,
1595 };
1591 pos = mem.alignForward(usize, pos, 2);1596 pos = mem.alignForward(usize, pos, 2);
1592 zig_object.output_ar_state.file_off = pos;1597 state.file_off = pos;
1593 pos += @sizeOf(Archive.ar_hdr) + (math.cast(usize, zig_object.output_ar_state.size) orelse return error.Overflow);1598 pos += @sizeOf(Archive.ar_hdr) + (math.cast(usize, state.size) orelse return error.Overflow);
1594 }1599 }
15951600
1596 break :blk pos;1601 break :blk pos;
...@@ -1618,9 +1623,9 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void...@@ -1618,9 +1623,9 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
1618 }1623 }
16191624
1620 // Write object files1625 // Write object files
1621 if (self.zigObjectPtr()) |zig_object| {1626 for (files.items) |index| {
1622 if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);1627 if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
1623 try zig_object.writeAr(self, buffer.writer());1628 try self.file(index).?.writeAr(self, buffer.writer());
1624 }1629 }
16251630
1626 assert(buffer.items.len == total_size);1631 assert(buffer.items.len == total_size);
src/link/Elf/Object.zig+2
...@@ -20,6 +20,7 @@ alive: bool = true,...@@ -20,6 +20,7 @@ alive: bool = true,
20num_dynrelocs: u32 = 0,20num_dynrelocs: u32 = 0,
2121
22output_symtab_size: Elf.SymtabSize = .{},22output_symtab_size: Elf.SymtabSize = .{},
23output_ar_state: Archive.ArState = .{},
2324
24pub fn isObject(path: []const u8) !bool {25pub fn isObject(path: []const u8) !bool {
25 const file = try std.fs.cwd().openFile(path, .{});26 const file = try std.fs.cwd().openFile(path, .{});
...@@ -924,6 +925,7 @@ const math = std.math;...@@ -924,6 +925,7 @@ const math = std.math;
924const mem = std.mem;925const mem = std.mem;
925926
926const Allocator = mem.Allocator;927const Allocator = mem.Allocator;
928const Archive = @import("Archive.zig");
927const Atom = @import("Atom.zig");929const Atom = @import("Atom.zig");
928const Cie = eh_frame.Cie;930const Cie = eh_frame.Cie;
929const Elf = @import("../Elf.zig");931const Elf = @import("../Elf.zig");
src/link/Elf/file.zig+25
...@@ -204,6 +204,31 @@ pub const File = union(enum) {...@@ -204,6 +204,31 @@ pub const File = union(enum) {
204 };204 };
205 }205 }
206206
207 pub fn updateArStrtab(file: File, allocator: Allocator, ar_strtab: *Archive.ArStrtab) !void {
208 return switch (file) {
209 .zig_object => |x| x.updateArStrtab(allocator, ar_strtab),
210 .object => @panic("TODO"),
211 inline else => unreachable,
212 };
213 }
214
215 pub fn updateArSize(file: File, elf_file: *Elf) void {
216 return switch (file) {
217 .zig_object => |x| x.updateArSize(elf_file),
218 .object => @panic("TODO"),
219 inline else => unreachable,
220 };
221 }
222
223 pub fn writeAr(file: File, elf_file: *Elf, writer: anytype) !void {
224 return switch (file) {
225 .zig_object => |x| x.writeAr(elf_file, writer),
226 // .object => |x| x.writeAr(elf_file, writer),
227 .object => @panic("TODO"),
228 inline else => unreachable,
229 };
230 }
231
207 pub const Index = u32;232 pub const Index = u32;
208233
209 pub const Entry = union(enum) {234 pub const Entry = union(enum) {