mirror of
https://github.com/ziglang/zig.git
synced 2026-02-04 05:33:39 +00:00
elf: add hooks for archiving Objects
This commit is contained in:
parent
5c48236103
commit
55fa8a04f1
@ -939,12 +939,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
} else null;
|
||||
const gc_sections = self.base.options.gc_sections orelse false;
|
||||
|
||||
if (self.isRelocatable() and self.zig_object_index == null) {
|
||||
if (self.isStaticLib()) {
|
||||
var err = try self.addErrorWithNotes(0);
|
||||
try err.addMsg(self, "fatal linker error: emitting static libs unimplemented", .{});
|
||||
return;
|
||||
}
|
||||
if (self.isObject() and self.zig_object_index == null) {
|
||||
// TODO this will become -r route I guess. For now, just copy the object file.
|
||||
assert(self.base.file == null); // TODO uncomment once we implement -r
|
||||
const the_object_path = blk: {
|
||||
@ -1555,15 +1550,18 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
|
||||
try self.writeElfHeader();
|
||||
}
|
||||
|
||||
// TODO parse positionals that we want to make part of the archive
|
||||
|
||||
// TODO update ar symtab from parsed positionals
|
||||
var files = std.ArrayList(File.Index).init(gpa);
|
||||
defer files.deinit();
|
||||
try files.ensureTotalCapacityPrecise(self.objects.items.len + 1);
|
||||
if (self.zigObjectPtr()) |zig_object| files.appendAssumeCapacity(zig_object.index);
|
||||
for (self.objects.items) |index| files.appendAssumeCapacity(index);
|
||||
|
||||
// Update ar symtab from parsed objects
|
||||
var ar_symtab: Archive.ArSymtab = .{};
|
||||
defer ar_symtab.deinit(gpa);
|
||||
|
||||
if (self.zigObjectPtr()) |zig_object| {
|
||||
try zig_object.updateArSymtab(&ar_symtab, self);
|
||||
for (files.items) |index| {
|
||||
try self.file(index).?.updateArSymtab(&ar_symtab, self);
|
||||
}
|
||||
|
||||
ar_symtab.sort();
|
||||
@ -1572,9 +1570,10 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
|
||||
var ar_strtab: Archive.ArStrtab = .{};
|
||||
defer ar_strtab.deinit(gpa);
|
||||
|
||||
if (self.zigObjectPtr()) |zig_object| {
|
||||
try zig_object.updateArStrtab(gpa, &ar_strtab);
|
||||
zig_object.updateArSize(self);
|
||||
for (files.items) |index| {
|
||||
const file_ptr = self.file(index).?;
|
||||
try file_ptr.updateArStrtab(gpa, &ar_strtab);
|
||||
file_ptr.updateArSize(self);
|
||||
}
|
||||
|
||||
// Update file offsets of contributing objects.
|
||||
@ -1587,10 +1586,16 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
|
||||
pos += @sizeOf(Archive.ar_hdr) + ar_strtab.size();
|
||||
}
|
||||
|
||||
if (self.zigObjectPtr()) |zig_object| {
|
||||
for (files.items) |index| {
|
||||
const file_ptr = self.file(index).?;
|
||||
const state = switch (file_ptr) {
|
||||
.zig_object => |x| &x.output_ar_state,
|
||||
.object => |x| &x.output_ar_state,
|
||||
else => unreachable,
|
||||
};
|
||||
pos = mem.alignForward(usize, pos, 2);
|
||||
zig_object.output_ar_state.file_off = pos;
|
||||
pos += @sizeOf(Archive.ar_hdr) + (math.cast(usize, zig_object.output_ar_state.size) orelse return error.Overflow);
|
||||
state.file_off = pos;
|
||||
pos += @sizeOf(Archive.ar_hdr) + (math.cast(usize, state.size) orelse return error.Overflow);
|
||||
}
|
||||
|
||||
break :blk pos;
|
||||
@ -1618,9 +1623,9 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
|
||||
}
|
||||
|
||||
// Write object files
|
||||
if (self.zigObjectPtr()) |zig_object| {
|
||||
for (files.items) |index| {
|
||||
if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
|
||||
try zig_object.writeAr(self, buffer.writer());
|
||||
try self.file(index).?.writeAr(self, buffer.writer());
|
||||
}
|
||||
|
||||
assert(buffer.items.len == total_size);
|
||||
|
||||
@ -20,6 +20,7 @@ alive: bool = true,
|
||||
num_dynrelocs: u32 = 0,
|
||||
|
||||
output_symtab_size: Elf.SymtabSize = .{},
|
||||
output_ar_state: Archive.ArState = .{},
|
||||
|
||||
pub fn isObject(path: []const u8) !bool {
|
||||
const file = try std.fs.cwd().openFile(path, .{});
|
||||
@ -924,6 +925,7 @@ const math = std.math;
|
||||
const mem = std.mem;
|
||||
|
||||
const Allocator = mem.Allocator;
|
||||
const Archive = @import("Archive.zig");
|
||||
const Atom = @import("Atom.zig");
|
||||
const Cie = eh_frame.Cie;
|
||||
const Elf = @import("../Elf.zig");
|
||||
|
||||
@ -204,6 +204,31 @@ pub const File = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn updateArStrtab(file: File, allocator: Allocator, ar_strtab: *Archive.ArStrtab) !void {
|
||||
return switch (file) {
|
||||
.zig_object => |x| x.updateArStrtab(allocator, ar_strtab),
|
||||
.object => @panic("TODO"),
|
||||
inline else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn updateArSize(file: File, elf_file: *Elf) void {
|
||||
return switch (file) {
|
||||
.zig_object => |x| x.updateArSize(elf_file),
|
||||
.object => @panic("TODO"),
|
||||
inline else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn writeAr(file: File, elf_file: *Elf, writer: anytype) !void {
|
||||
return switch (file) {
|
||||
.zig_object => |x| x.writeAr(elf_file, writer),
|
||||
// .object => |x| x.writeAr(elf_file, writer),
|
||||
.object => @panic("TODO"),
|
||||
inline else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub const Index = u32;
|
||||
|
||||
pub const Entry = union(enum) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user