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...@@ -1572,8 +1572,11 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
1572 const total_size: u64 = blk: {1572 const total_size: u64 = blk: {
1573 var pos: u64 = Archive.SARMAG;1573 var pos: u64 = Archive.SARMAG;
1574 pos += @sizeOf(Archive.ar_hdr) + ar_symtab.size(.p64);1574 pos += @sizeOf(Archive.ar_hdr) + ar_symtab.size(.p64);
1575 pos = mem.alignForward(u64, pos, 2);1575
1576 pos += @sizeOf(Archive.ar_hdr) + ar_strtab.size();1576 if (ar_strtab.size() > 0) {
1577 pos = mem.alignForward(u64, pos, 2);
1578 pos += @sizeOf(Archive.ar_hdr) + ar_strtab.size();
1579 }
15771580
1578 if (self.zigObjectPtr()) |zig_object| {1581 if (self.zigObjectPtr()) |zig_object| {
1579 pos = mem.alignForward(u64, pos, 2);1582 pos = mem.alignForward(u64, pos, 2);
...@@ -1598,19 +1601,22 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void...@@ -1598,19 +1601,22 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
15981601
1599 // Write symtab1602 // Write symtab
1600 try ar_symtab.write(.p64, self, buffer.writer());1603 try ar_symtab.write(.p64, self, buffer.writer());
1601 if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
16021604
1603 // Write strtab1605 // Write strtab
1604 try ar_strtab.write(buffer.writer());1606 if (ar_strtab.size() > 0) {
1605 if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);1607 if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
1608 try ar_strtab.write(buffer.writer());
1609 }
16061610
1607 // Write object files1611 // Write object files
1608 if (self.zigObjectPtr()) |zig_object| {1612 if (self.zigObjectPtr()) |zig_object| {
1613 if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
1609 try zig_object.writeAr(self, buffer.writer());1614 try zig_object.writeAr(self, buffer.writer());
1610 }1615 }
16111616
1612 assert(buffer.items.len == total_size);1617 assert(buffer.items.len == total_size);
16131618
1619 try self.base.file.?.setEndPos(total_size);
1614 try self.base.file.?.pwriteAll(buffer.items, 0);1620 try self.base.file.?.pwriteAll(buffer.items, 0);
1615}1621}
16161622
src/link/Elf/Archive.zig+15-9
...@@ -61,14 +61,15 @@ pub fn parse(self: *Archive, elf_file: *Elf) !void {...@@ -61,14 +61,15 @@ pub fn parse(self: *Archive, elf_file: *Elf) !void {
61 const object_name = blk: {61 const object_name = blk: {
62 if (name[0] == '/') {62 if (name[0] == '/') {
63 const off = try std.fmt.parseInt(u32, name[1..], 10);63 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 '/'
65 }66 }
66 break :blk name;67 break :blk try gpa.dupe(u8, name);
67 };68 };
6869
69 const object = Object{70 const object = Object{
70 .archive = try gpa.dupe(u8, self.path),71 .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,
72 .data = try gpa.dupe(u8, self.data[stream.pos..][0..size]),73 .data = try gpa.dupe(u8, self.data[stream.pos..][0..size]),
73 .index = undefined,74 .index = undefined,
74 .alive = false,75 .alive = false,
...@@ -86,8 +87,12 @@ fn getString(self: Archive, off: u32) []const u8 {...@@ -86,8 +87,12 @@ fn getString(self: Archive, off: u32) []const u8 {
86}87}
8788
88pub fn setArHdr(opts: struct {89pub fn setArHdr(opts: struct {
89 kind: enum { symtab, strtab, object },90 name: union(enum) {
90 name_off: u32,91 symtab: void,
92 strtab: void,
93 name: []const u8,
94 name_off: u32,
95 },
91 size: u32,96 size: u32,
92}) ar_hdr {97}) ar_hdr {
93 var hdr: ar_hdr = .{98 var hdr: ar_hdr = .{
...@@ -105,10 +110,11 @@ pub fn setArHdr(opts: struct {...@@ -105,10 +110,11 @@ pub fn setArHdr(opts: struct {
105 {110 {
106 var stream = std.io.fixedBufferStream(&hdr.ar_name);111 var stream = std.io.fixedBufferStream(&hdr.ar_name);
107 const writer = stream.writer();112 const writer = stream.writer();
108 switch (opts.kind) {113 switch (opts.name) {
109 .symtab => writer.print("{s}", .{Archive.SYM64NAME}) catch unreachable,114 .symtab => writer.print("{s}", .{Archive.SYM64NAME}) catch unreachable,
110 .strtab => writer.print("//", .{}) catch unreachable,115 .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,
112 }118 }
113 }119 }
114 {120 {
...@@ -213,7 +219,7 @@ pub const ArSymtab = struct {...@@ -213,7 +219,7 @@ pub const ArSymtab = struct {
213219
214 pub fn write(ar: ArSymtab, kind: enum { p32, p64 }, elf_file: *Elf, writer: anytype) !void {220 pub fn write(ar: ArSymtab, kind: enum { p32, p64 }, elf_file: *Elf, writer: anytype) !void {
215 assert(kind == .p64); // TODO p32221 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)) });
217 try writer.writeAll(mem.asBytes(&hdr));223 try writer.writeAll(mem.asBytes(&hdr));
218224
219 const gpa = elf_file.base.allocator;225 const gpa = elf_file.base.allocator;
...@@ -314,7 +320,7 @@ pub const ArStrtab = struct {...@@ -314,7 +320,7 @@ pub const ArStrtab = struct {
314 }320 }
315321
316 pub fn write(ar: ArStrtab, writer: anytype) !void {322 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()) });
318 try writer.writeAll(mem.asBytes(&hdr));324 try writer.writeAll(mem.asBytes(&hdr));
319 try writer.writeAll(ar.buffer.items);325 try writer.writeAll(ar.buffer.items);
320 }326 }
src/link/Elf/ZigObject.zig+8-2
...@@ -526,6 +526,7 @@ pub fn updateArStrtab(...@@ -526,6 +526,7 @@ pub fn updateArStrtab(
526) error{OutOfMemory}!void {526) error{OutOfMemory}!void {
527 const name = try std.fmt.allocPrint(allocator, "{s}.o", .{std.fs.path.stem(self.path)});527 const name = try std.fmt.allocPrint(allocator, "{s}.o", .{std.fs.path.stem(self.path)});
528 defer allocator.free(name);528 defer allocator.free(name);
529 if (name.len <= 15) return;
529 const name_off = try ar_strtab.insert(allocator, name);530 const name_off = try ar_strtab.insert(allocator, name);
530 self.output_ar_state.name_off = name_off;531 self.output_ar_state.name_off = name_off;
531}532}
...@@ -540,13 +541,18 @@ pub fn updateArSize(self: *ZigObject, elf_file: *Elf) void {...@@ -540,13 +541,18 @@ pub fn updateArSize(self: *ZigObject, elf_file: *Elf) void {
540541
541pub fn writeAr(self: ZigObject, elf_file: *Elf, writer: anytype) !void {542pub fn writeAr(self: ZigObject, elf_file: *Elf, writer: anytype) !void {
542 const gpa = elf_file.base.allocator;543 const gpa = elf_file.base.allocator;
544
543 const contents = try gpa.alloc(u8, self.output_ar_state.size);545 const contents = try gpa.alloc(u8, self.output_ar_state.size);
544 defer gpa.free(contents);546 defer gpa.free(contents);
547
545 const amt = try elf_file.base.file.?.preadAll(contents, 0);548 const amt = try elf_file.base.file.?.preadAll(contents, 0);
546 if (amt != self.output_ar_state.size) return error.InputOutput;549 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
547 const hdr = Archive.setArHdr(.{554 const hdr = Archive.setArHdr(.{
548 .kind = .object,555 .name = if (name.len <= 15) .{ .name = name } else .{ .name_off = self.output_ar_state.name_off },
549 .name_off = self.output_ar_state.name_off,
550 .size = @intCast(self.output_ar_state.size),556 .size = @intCast(self.output_ar_state.size),
551 });557 });
552 try writer.writeAll(mem.asBytes(&hdr));558 try writer.writeAll(mem.asBytes(&hdr));