Commit e3b82eaa66
Changed files (3)
src
link
src/link/Elf/Archive.zig
@@ -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);
}
src/link/Elf/ZigObject.zig
@@ -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));
src/link/Elf.zig
@@ -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);
}