authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-02 21:44:27+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-04 09:12:18+01:00
log875beb25b5493ee3b0aedd730f831e4ea5d124cc
tree102e256076cc1e7017fdc57a9f2310a001b278cb
parent3b9455f0052d4ae648e8eec9685455eb501abcfd

elf: fix writing symtab to an archive


1 files changed, 15 insertions(+), 9 deletions(-)

src/link/Elf.zig+15-9
...@@ -1566,19 +1566,24 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void...@@ -1566,19 +1566,24 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
1566 state_log.debug("{}", .{self.dumpState()});1566 state_log.debug("{}", .{self.dumpState()});
1567 }1567 }
15681568
1569 // Save object paths in strtab.1569 // Save object paths in filenames strtab.
1570 var ar_strtab = std.ArrayList(u8).init(gpa);
1571 defer ar_strtab.deinit();
1572
1570 var files = std.AutoHashMap(File.Index, struct { u32, u64, u64 }).init(gpa);1573 var files = std.AutoHashMap(File.Index, struct { u32, u64, u64 }).init(gpa);
1571 defer files.deinit();1574 defer files.deinit();
1572 try files.ensureUnusedCapacity(@intCast(self.objects.items.len + 1));1575 try files.ensureUnusedCapacity(@intCast(self.objects.items.len + 1));
15731576
1574 if (self.zigObjectPtr()) |zig_object| {1577 if (self.zigObjectPtr()) |zig_object| {
1575 files.putAssumeCapacityNoClobber(zig_object.index, .{ try self.ar_strtab.insert(gpa, zig_object.path), 0, 0 });1578 const off = @as(u32, @intCast(ar_strtab.items.len));
1579 try ar_strtab.writer().print("{s}/\n", .{zig_object.path});
1580 files.putAssumeCapacityNoClobber(zig_object.index, .{ off, 0, 0 });
1576 }1581 }
15771582
1578 // Encode ar symtab in 64bit format.1583 // Encode ar symtab in 64bit format.
1579 var ar_symtab = std.ArrayList(u8).init(gpa);1584 var ar_symtab = std.ArrayList(u8).init(gpa);
1580 defer ar_symtab.deinit();1585 defer ar_symtab.deinit();
1581 try ar_symtab.ensureTotalCapacityPrecise(8 * (3 * self.ar_symtab.items.len + 1));1586 try ar_symtab.ensureUnusedCapacity(8 * (self.ar_symtab.items.len + 1));
15821587
1583 // Number of symbols1588 // Number of symbols
1584 ar_symtab.writer().writeInt(u64, @as(u64, @intCast(self.ar_symtab.items.len)), .big) catch unreachable;1589 ar_symtab.writer().writeInt(u64, @as(u64, @intCast(self.ar_symtab.items.len)), .big) catch unreachable;
...@@ -1590,14 +1595,15 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void...@@ -1590,14 +1595,15 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
15901595
1591 // ASCII offsets into the strtab.1596 // ASCII offsets into the strtab.
1592 for (self.ar_symtab.items) |entry| {1597 for (self.ar_symtab.items) |entry| {
1593 ar_symtab.writer().print("/{d}", .{entry.off}) catch unreachable;1598 const name = self.ar_strtab.getAssumeExists(entry.off);
1599 try ar_symtab.writer().print("{s}\x00", .{name});
1594 }1600 }
15951601
1596 // Align to 8bytes if required1602 // Align to 8bytes if required
1597 {1603 {
1598 const end = ar_symtab.items.len;1604 const end = ar_symtab.items.len;
1599 const aligned = mem.alignForward(usize, end, 8);1605 const aligned = mem.alignForward(usize, end, 8);
1600 ar_symtab.writer().writeByteNTimes(0, aligned - end) catch unreachable;1606 try ar_symtab.writer().writeByteNTimes(0, aligned - end);
1601 }1607 }
16021608
1603 assert(mem.isAligned(ar_symtab.items.len, 8));1609 assert(mem.isAligned(ar_symtab.items.len, 8));
...@@ -1610,7 +1616,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void...@@ -1610,7 +1616,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
1610 // Symtab1616 // Symtab
1611 file_off += @sizeOf(Archive.ar_hdr) + @as(u64, @intCast(ar_symtab.items.len));1617 file_off += @sizeOf(Archive.ar_hdr) + @as(u64, @intCast(ar_symtab.items.len));
1612 // Strtab1618 // Strtab
1613 file_off += @sizeOf(Archive.ar_hdr) + @as(u64, @intCast(self.ar_strtab.buffer.items.len));1619 file_off += @sizeOf(Archive.ar_hdr) + @as(u64, @intCast(ar_strtab.items.len));
1614 // And because we are nice, we will align to 8 bytes.1620 // And because we are nice, we will align to 8 bytes.
1615 file_off = mem.alignForward(u64, file_off, 8);1621 file_off = mem.alignForward(u64, file_off, 8);
16161622
...@@ -1655,12 +1661,12 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void...@@ -1655,12 +1661,12 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
1655 const hdr = setArHdr(.{1661 const hdr = setArHdr(.{
1656 .kind = .strtab,1662 .kind = .strtab,
1657 .name_off = 0,1663 .name_off = 0,
1658 .size = @intCast(mem.alignForward(usize, self.ar_strtab.buffer.items.len, 8)),1664 .size = @intCast(mem.alignForward(usize, ar_strtab.items.len, 8)),
1659 });1665 });
1660 try self.base.file.?.pwriteAll(mem.asBytes(&hdr), pos);1666 try self.base.file.?.pwriteAll(mem.asBytes(&hdr), pos);
1661 pos += @sizeOf(Archive.ar_hdr);1667 pos += @sizeOf(Archive.ar_hdr);
1662 try self.base.file.?.pwriteAll(self.ar_strtab.buffer.items, pos);1668 try self.base.file.?.pwriteAll(ar_strtab.items, pos);
1663 pos += self.ar_strtab.buffer.items.len;1669 pos += ar_strtab.items.len;
1664 }1670 }
16651671
1666 // Zig object if defined1672 // Zig object if defined