elf: do not store filename in strtab unless longer than 15 chars
This commit is contained in:
@@ -1572,8 +1572,11 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
|
||||
const total_size: u64 = blk: {
|
||||
var pos: u64 = Archive.SARMAG;
|
||||
pos += @sizeOf(Archive.ar_hdr) + ar_symtab.size(.p64);
|
||||
pos = mem.alignForward(u64, pos, 2);
|
||||
pos += @sizeOf(Archive.ar_hdr) + ar_strtab.size();
|
||||
|
||||
if (ar_strtab.size() > 0) {
|
||||
pos = mem.alignForward(u64, pos, 2);
|
||||
pos += @sizeOf(Archive.ar_hdr) + ar_strtab.size();
|
||||
}
|
||||
|
||||
if (self.zigObjectPtr()) |zig_object| {
|
||||
pos = mem.alignForward(u64, pos, 2);
|
||||
@@ -1598,19 +1601,22 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
|
||||
|
||||
// Write symtab
|
||||
try ar_symtab.write(.p64, self, buffer.writer());
|
||||
if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
|
||||
|
||||
// Write strtab
|
||||
try ar_strtab.write(buffer.writer());
|
||||
if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
|
||||
if (ar_strtab.size() > 0) {
|
||||
if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
|
||||
try ar_strtab.write(buffer.writer());
|
||||
}
|
||||
|
||||
// Write object files
|
||||
if (self.zigObjectPtr()) |zig_object| {
|
||||
if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
|
||||
try zig_object.writeAr(self, buffer.writer());
|
||||
}
|
||||
|
||||
assert(buffer.items.len == total_size);
|
||||
|
||||
try self.base.file.?.setEndPos(total_size);
|
||||
try self.base.file.?.pwriteAll(buffer.items, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,14 +61,15 @@ pub fn parse(self: *Archive, elf_file: *Elf) !void {
|
||||
const object_name = blk: {
|
||||
if (name[0] == '/') {
|
||||
const off = try std.fmt.parseInt(u32, name[1..], 10);
|
||||
break :blk self.getString(off);
|
||||
const object_name = self.getString(off);
|
||||
break :blk try gpa.dupe(u8, object_name[0 .. object_name.len - 1]); // To account for trailing '/'
|
||||
}
|
||||
break :blk name;
|
||||
break :blk try gpa.dupe(u8, name);
|
||||
};
|
||||
|
||||
const object = Object{
|
||||
.archive = try gpa.dupe(u8, self.path),
|
||||
.path = try gpa.dupe(u8, object_name[0 .. object_name.len - 1]), // To account for trailing '/'
|
||||
.path = object_name,
|
||||
.data = try gpa.dupe(u8, self.data[stream.pos..][0..size]),
|
||||
.index = undefined,
|
||||
.alive = false,
|
||||
@@ -86,8 +87,12 @@ fn getString(self: Archive, off: u32) []const u8 {
|
||||
}
|
||||
|
||||
pub fn setArHdr(opts: struct {
|
||||
kind: enum { symtab, strtab, object },
|
||||
name_off: u32,
|
||||
name: union(enum) {
|
||||
symtab: void,
|
||||
strtab: void,
|
||||
name: []const u8,
|
||||
name_off: u32,
|
||||
},
|
||||
size: u32,
|
||||
}) ar_hdr {
|
||||
var hdr: ar_hdr = .{
|
||||
@@ -105,10 +110,11 @@ pub fn setArHdr(opts: struct {
|
||||
{
|
||||
var stream = std.io.fixedBufferStream(&hdr.ar_name);
|
||||
const writer = stream.writer();
|
||||
switch (opts.kind) {
|
||||
switch (opts.name) {
|
||||
.symtab => writer.print("{s}", .{Archive.SYM64NAME}) catch unreachable,
|
||||
.strtab => writer.print("//", .{}) catch unreachable,
|
||||
.object => writer.print("/{d}", .{opts.name_off}) catch unreachable,
|
||||
.name => |x| writer.print("{s}", .{x}) catch unreachable,
|
||||
.name_off => |x| writer.print("/{d}", .{x}) catch unreachable,
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -213,7 +219,7 @@ pub const ArSymtab = struct {
|
||||
|
||||
pub fn write(ar: ArSymtab, kind: enum { p32, p64 }, elf_file: *Elf, writer: anytype) !void {
|
||||
assert(kind == .p64); // TODO p32
|
||||
const hdr = setArHdr(.{ .kind = .symtab, .name_off = 0, .size = @intCast(ar.size(.p64)) });
|
||||
const hdr = setArHdr(.{ .name = .symtab, .size = @intCast(ar.size(.p64)) });
|
||||
try writer.writeAll(mem.asBytes(&hdr));
|
||||
|
||||
const gpa = elf_file.base.allocator;
|
||||
@@ -314,7 +320,7 @@ pub const ArStrtab = struct {
|
||||
}
|
||||
|
||||
pub fn write(ar: ArStrtab, writer: anytype) !void {
|
||||
const hdr = setArHdr(.{ .kind = .strtab, .name_off = 0, .size = @intCast(ar.size()) });
|
||||
const hdr = setArHdr(.{ .name = .strtab, .size = @intCast(ar.size()) });
|
||||
try writer.writeAll(mem.asBytes(&hdr));
|
||||
try writer.writeAll(ar.buffer.items);
|
||||
}
|
||||
|
||||
@@ -526,6 +526,7 @@ pub fn updateArStrtab(
|
||||
) error{OutOfMemory}!void {
|
||||
const name = try std.fmt.allocPrint(allocator, "{s}.o", .{std.fs.path.stem(self.path)});
|
||||
defer allocator.free(name);
|
||||
if (name.len <= 15) return;
|
||||
const name_off = try ar_strtab.insert(allocator, name);
|
||||
self.output_ar_state.name_off = name_off;
|
||||
}
|
||||
@@ -540,13 +541,18 @@ pub fn updateArSize(self: *ZigObject, elf_file: *Elf) void {
|
||||
|
||||
pub fn writeAr(self: ZigObject, elf_file: *Elf, writer: anytype) !void {
|
||||
const gpa = elf_file.base.allocator;
|
||||
|
||||
const contents = try gpa.alloc(u8, self.output_ar_state.size);
|
||||
defer gpa.free(contents);
|
||||
|
||||
const amt = try elf_file.base.file.?.preadAll(contents, 0);
|
||||
if (amt != self.output_ar_state.size) return error.InputOutput;
|
||||
|
||||
const name = try std.fmt.allocPrint(gpa, "{s}.o", .{std.fs.path.stem(self.path)});
|
||||
defer gpa.free(name);
|
||||
|
||||
const hdr = Archive.setArHdr(.{
|
||||
.kind = .object,
|
||||
.name_off = self.output_ar_state.name_off,
|
||||
.name = if (name.len <= 15) .{ .name = name } else .{ .name_off = self.output_ar_state.name_off },
|
||||
.size = @intCast(self.output_ar_state.size),
|
||||
});
|
||||
try writer.writeAll(mem.asBytes(&hdr));
|
||||
|
||||
Reference in New Issue
Block a user