mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
macho: bring back relocatable mode for ZigObject
This commit is contained in:
parent
cba04ff244
commit
853ca403c4
@ -437,9 +437,48 @@ pub fn calcNumRelocs(self: *ZigObject, macho_file: *MachO) void {
|
||||
for (self.getAtoms()) |atom_index| {
|
||||
const atom = self.getAtom(atom_index) orelse continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
if (!macho_file.isZigSection(atom.out_n_sect) and !macho_file.isDebugSection(atom.out_n_sect)) continue;
|
||||
const header = &macho_file.sections.items(.header)[atom.out_n_sect];
|
||||
header.nreloc += atom.calcNumRelocs(macho_file);
|
||||
if (header.isZerofill()) continue;
|
||||
if (!macho_file.isZigSection(atom.out_n_sect) and !macho_file.isDebugSection(atom.out_n_sect)) continue;
|
||||
const nreloc = atom.calcNumRelocs(macho_file);
|
||||
atom.addExtra(.{ .rel_out_index = header.nreloc, .rel_out_count = nreloc }, macho_file);
|
||||
header.nreloc += nreloc;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeRelocs(self: *ZigObject, macho_file: *MachO) !void {
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
|
||||
for (self.getAtoms()) |atom_index| {
|
||||
const atom = self.getAtom(atom_index) orelse continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
const header = macho_file.sections.items(.header)[atom.out_n_sect];
|
||||
const relocs = macho_file.sections.items(.relocs)[atom.out_n_sect].items;
|
||||
if (header.isZerofill()) continue;
|
||||
if (!macho_file.isZigSection(atom.out_n_sect) and !macho_file.isDebugSection(atom.out_n_sect)) continue;
|
||||
if (atom.getRelocs(macho_file).len == 0) continue;
|
||||
const extra = atom.getExtra(macho_file);
|
||||
const atom_size = std.math.cast(usize, atom.size) orelse return error.Overflow;
|
||||
const code = try gpa.alloc(u8, atom_size);
|
||||
defer gpa.free(code);
|
||||
self.getAtomData(macho_file, atom.*, code) catch |err| switch (err) {
|
||||
error.InputOutput => {
|
||||
try macho_file.reportUnexpectedError("fetching code for '{s}' failed", .{
|
||||
atom.getName(macho_file),
|
||||
});
|
||||
return error.FlushFailure;
|
||||
},
|
||||
else => |e| {
|
||||
try macho_file.reportUnexpectedError("unexpected error while fetching code for '{s}': {s}", .{
|
||||
atom.getName(macho_file),
|
||||
@errorName(e),
|
||||
});
|
||||
return error.FlushFailure;
|
||||
},
|
||||
};
|
||||
const file_offset = header.offset + atom.value;
|
||||
try atom.writeRelocs(macho_file, code, relocs[extra.rel_out_index..][0..extra.rel_out_count]);
|
||||
try macho_file.base.file.?.pwriteAll(code, file_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -372,6 +372,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {
|
||||
if (macho_file.getZigObject()) |zo| {
|
||||
// TODO this will create a race
|
||||
zo.calcNumRelocs(macho_file);
|
||||
zo.calcSymtabSize(macho_file);
|
||||
}
|
||||
|
||||
if (macho_file.eh_frame_sect_index) |_| {
|
||||
@ -390,7 +391,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {
|
||||
if (macho_file.unwind_info_sect_index) |_| {
|
||||
calcCompactUnwindSize(macho_file);
|
||||
}
|
||||
calcSymtabSize(macho_file);
|
||||
try calcSymtabSize(macho_file);
|
||||
}
|
||||
|
||||
fn calcSectionSize(macho_file: *MachO, sect_id: u8) void {
|
||||
@ -445,19 +446,27 @@ fn calcCompactUnwindSize(macho_file: *MachO) void {
|
||||
sect.@"align" = 3;
|
||||
}
|
||||
|
||||
fn calcSymtabSize(macho_file: *MachO) void {
|
||||
fn calcSymtabSize(macho_file: *MachO) error{OutOfMemory}!void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
|
||||
var nlocals: u32 = 0;
|
||||
var nstabs: u32 = 0;
|
||||
var nexports: u32 = 0;
|
||||
var nimports: u32 = 0;
|
||||
var strsize: u32 = 1;
|
||||
|
||||
for (macho_file.objects.items) |index| {
|
||||
const object = macho_file.getFile(index).?.object;
|
||||
const ctx = &object.output_symtab_ctx;
|
||||
var objects = try std.ArrayList(File.Index).initCapacity(gpa, macho_file.objects.items.len + 1);
|
||||
defer objects.deinit();
|
||||
if (macho_file.getZigObject()) |zo| objects.appendAssumeCapacity(zo.index);
|
||||
objects.appendSliceAssumeCapacity(macho_file.objects.items);
|
||||
|
||||
for (objects.items) |index| {
|
||||
const ctx = switch (macho_file.getFile(index).?) {
|
||||
inline else => |x| &x.output_symtab_ctx,
|
||||
};
|
||||
ctx.ilocal = nlocals;
|
||||
ctx.istab = nstabs;
|
||||
ctx.iexport = nexports;
|
||||
@ -470,9 +479,10 @@ fn calcSymtabSize(macho_file: *MachO) void {
|
||||
strsize += ctx.strsize;
|
||||
}
|
||||
|
||||
for (macho_file.objects.items) |index| {
|
||||
const object = macho_file.getFile(index).?.object;
|
||||
const ctx = &object.output_symtab_ctx;
|
||||
for (objects.items) |index| {
|
||||
const ctx = switch (macho_file.getFile(index).?) {
|
||||
inline else => |x| &x.output_symtab_ctx,
|
||||
};
|
||||
ctx.istab += nlocals;
|
||||
ctx.iexport += nlocals + nstabs;
|
||||
ctx.iimport += nlocals + nstabs + nexports;
|
||||
@ -645,6 +655,11 @@ fn writeSections(macho_file: *MachO) !void {
|
||||
macho_file.getFile(index).?.writeSymtab(macho_file, macho_file);
|
||||
}
|
||||
|
||||
if (macho_file.getZigObject()) |zo| {
|
||||
try zo.writeRelocs(macho_file);
|
||||
zo.writeSymtab(macho_file, macho_file);
|
||||
}
|
||||
|
||||
if (macho_file.eh_frame_sect_index) |_| {
|
||||
try writeEhFrame(macho_file);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user