authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-04 00:08:55+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-04 09:13:26+01:00
loge3b82eaa661bc964f62a9481ac9ebfe35cf3bb87
tree615947d93e00e1a4a8dedd50344908938d5d0524
parentacd700ac6b4ec03412e2bac6aaf168f80f83f521

elf: do not store filename in strtab unless longer than 15 chars


3 files changed, 34 insertions(+), 16 deletions(-)

src/link/Elf.zig+11-5
......@@ -1572,8 +1572,11 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
15721572 const total_size: u64 = blk: {
15731573 var pos: u64 = Archive.SARMAG;
15741574 pos += @sizeOf(Archive.ar_hdr) + ar_symtab.size(.p64);
1575 pos = mem.alignForward(u64, pos, 2);
1576 pos += @sizeOf(Archive.ar_hdr) + ar_strtab.size();
1575
1576 if (ar_strtab.size() > 0) {
1577 pos = mem.alignForward(u64, pos, 2);
1578 pos += @sizeOf(Archive.ar_hdr) + ar_strtab.size();
1579 }
15771580
15781581 if (self.zigObjectPtr()) |zig_object| {
15791582 pos = mem.alignForward(u64, pos, 2);
......@@ -1598,19 +1601,22 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
15981601
15991602 // Write symtab
16001603 try ar_symtab.write(.p64, self, buffer.writer());
1601 if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
16021604
16031605 // Write strtab
1604 try ar_strtab.write(buffer.writer());
1605 if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
1606 if (ar_strtab.size() > 0) {
1607 if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
1608 try ar_strtab.write(buffer.writer());
1609 }
16061610
16071611 // Write object files
16081612 if (self.zigObjectPtr()) |zig_object| {
1613 if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
16091614 try zig_object.writeAr(self, buffer.writer());
16101615 }
16111616
16121617 assert(buffer.items.len == total_size);
16131618
1619 try self.base.file.?.setEndPos(total_size);
16141620 try self.base.file.?.pwriteAll(buffer.items, 0);
16151621}
16161622
src/link/Elf/Archive.zig+15-9
......@@ -61,14 +61,15 @@ pub fn parse(self: *Archive, elf_file: *Elf) !void {
6161 const object_name = blk: {
6262 if (name[0] == '/') {
6363 const off = try std.fmt.parseInt(u32, name[1..], 10);
64 break :blk self.getString(off);
64 const object_name = self.getString(off);
65 break :blk try gpa.dupe(u8, object_name[0 .. object_name.len - 1]); // To account for trailing '/'
6566 }
66 break :blk name;
67 break :blk try gpa.dupe(u8, name);
6768 };
6869
6970 const object = Object{
7071 .archive = try gpa.dupe(u8, self.path),
71 .path = try gpa.dupe(u8, object_name[0 .. object_name.len - 1]), // To account for trailing '/'
72 .path = object_name,
7273 .data = try gpa.dupe(u8, self.data[stream.pos..][0..size]),
7374 .index = undefined,
7475 .alive = false,
......@@ -86,8 +87,12 @@ fn getString(self: Archive, off: u32) []const u8 {
8687}
8788
8889pub fn setArHdr(opts: struct {
89 kind: enum { symtab, strtab, object },
90 name_off: u32,
90 name: union(enum) {
91 symtab: void,
92 strtab: void,
93 name: []const u8,
94 name_off: u32,
95 },
9196 size: u32,
9297}) ar_hdr {
9398 var hdr: ar_hdr = .{
......@@ -105,10 +110,11 @@ pub fn setArHdr(opts: struct {
105110 {
106111 var stream = std.io.fixedBufferStream(&hdr.ar_name);
107112 const writer = stream.writer();
108 switch (opts.kind) {
113 switch (opts.name) {
109114 .symtab => writer.print("{s}", .{Archive.SYM64NAME}) catch unreachable,
110115 .strtab => writer.print("//", .{}) catch unreachable,
111 .object => writer.print("/{d}", .{opts.name_off}) catch unreachable,
116 .name => |x| writer.print("{s}", .{x}) catch unreachable,
117 .name_off => |x| writer.print("/{d}", .{x}) catch unreachable,
112118 }
113119 }
114120 {
......@@ -213,7 +219,7 @@ pub const ArSymtab = struct {
213219
214220 pub fn write(ar: ArSymtab, kind: enum { p32, p64 }, elf_file: *Elf, writer: anytype) !void {
215221 assert(kind == .p64); // TODO p32
216 const hdr = setArHdr(.{ .kind = .symtab, .name_off = 0, .size = @intCast(ar.size(.p64)) });
222 const hdr = setArHdr(.{ .name = .symtab, .size = @intCast(ar.size(.p64)) });
217223 try writer.writeAll(mem.asBytes(&hdr));
218224
219225 const gpa = elf_file.base.allocator;
......@@ -314,7 +320,7 @@ pub const ArStrtab = struct {
314320 }
315321
316322 pub fn write(ar: ArStrtab, writer: anytype) !void {
317 const hdr = setArHdr(.{ .kind = .strtab, .name_off = 0, .size = @intCast(ar.size()) });
323 const hdr = setArHdr(.{ .name = .strtab, .size = @intCast(ar.size()) });
318324 try writer.writeAll(mem.asBytes(&hdr));
319325 try writer.writeAll(ar.buffer.items);
320326 }
src/link/Elf/ZigObject.zig+8-2
......@@ -526,6 +526,7 @@ pub fn updateArStrtab(
526526) error{OutOfMemory}!void {
527527 const name = try std.fmt.allocPrint(allocator, "{s}.o", .{std.fs.path.stem(self.path)});
528528 defer allocator.free(name);
529 if (name.len <= 15) return;
529530 const name_off = try ar_strtab.insert(allocator, name);
530531 self.output_ar_state.name_off = name_off;
531532}
......@@ -540,13 +541,18 @@ pub fn updateArSize(self: *ZigObject, elf_file: *Elf) void {
540541
541542pub fn writeAr(self: ZigObject, elf_file: *Elf, writer: anytype) !void {
542543 const gpa = elf_file.base.allocator;
544
543545 const contents = try gpa.alloc(u8, self.output_ar_state.size);
544546 defer gpa.free(contents);
547
545548 const amt = try elf_file.base.file.?.preadAll(contents, 0);
546549 if (amt != self.output_ar_state.size) return error.InputOutput;
550
551 const name = try std.fmt.allocPrint(gpa, "{s}.o", .{std.fs.path.stem(self.path)});
552 defer gpa.free(name);
553
547554 const hdr = Archive.setArHdr(.{
548 .kind = .object,
549 .name_off = self.output_ar_state.name_off,
555 .name = if (name.len <= 15) .{ .name = name } else .{ .name_off = self.output_ar_state.name_off },
550556 .size = @intCast(self.output_ar_state.size),
551557 });
552558 try writer.writeAll(mem.asBytes(&hdr));