mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 00:35:10 +00:00
Merge pull request #18761 from ziglang/macho-fixes
macho: misc fixes and improvements
This commit is contained in:
commit
788a0409af
@ -62,7 +62,7 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
.pcrel = true,
|
||||
.has_subtractor = false,
|
||||
.length = 2,
|
||||
.symbolnum = 0,
|
||||
.symbolnum = @intCast(symbol.sym_index),
|
||||
},
|
||||
});
|
||||
} else if (emit.lower.bin_file.cast(link.File.Coff)) |coff_file| {
|
||||
@ -165,7 +165,9 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
const @"type": link.File.MachO.Relocation.Type = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
|
||||
.zig_got_load
|
||||
else if (sym.flags.needs_got)
|
||||
.got_load
|
||||
// TODO: it is possible to emit .got_load here that can potentially be relaxed
|
||||
// however this requires always to use a MOVQ mnemonic
|
||||
.got
|
||||
else if (sym.flags.tlv)
|
||||
.tlv
|
||||
else
|
||||
@ -180,7 +182,7 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
.pcrel = true,
|
||||
.has_subtractor = false,
|
||||
.length = 2,
|
||||
.symbolnum = 0,
|
||||
.symbolnum = @intCast(data.sym_index),
|
||||
},
|
||||
});
|
||||
} else unreachable,
|
||||
|
||||
@ -546,8 +546,8 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void {
|
||||
|
||||
relocs_log.debug("{x}: {s}", .{ self.value, name });
|
||||
|
||||
var has_error = false;
|
||||
var stream = std.io.fixedBufferStream(buffer);
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < relocs.len) : (i += 1) {
|
||||
const rel = relocs[i];
|
||||
@ -562,25 +562,34 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void {
|
||||
self.resolveRelocInner(rel, subtractor, buffer, macho_file, stream.writer()) catch |err| {
|
||||
switch (err) {
|
||||
error.RelaxFail => {
|
||||
const target = switch (rel.tag) {
|
||||
.@"extern" => rel.getTargetSymbol(macho_file).getName(macho_file),
|
||||
.local => rel.getTargetAtom(macho_file).getName(macho_file),
|
||||
};
|
||||
try macho_file.reportParseError2(
|
||||
file.getIndex(),
|
||||
"{s}: 0x{x}: failed to relax relocation: in {s}",
|
||||
.{ name, rel.offset, @tagName(rel.type) },
|
||||
"{s}: 0x{x}: 0x{x}: failed to relax relocation: type {s}, target {s}",
|
||||
.{ name, self.value, rel.offset, @tagName(rel.type), target },
|
||||
);
|
||||
return error.ResolveFailed;
|
||||
has_error = true;
|
||||
},
|
||||
error.RelaxFailUnexpectedInstruction => has_error = true,
|
||||
else => |e| return e,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (has_error) return error.ResolveFailed;
|
||||
}
|
||||
|
||||
const ResolveError = error{
|
||||
RelaxFail,
|
||||
RelaxFailUnexpectedInstruction,
|
||||
NoSpaceLeft,
|
||||
DivisionByZero,
|
||||
UnexpectedRemainder,
|
||||
Overflow,
|
||||
OutOfMemory,
|
||||
};
|
||||
|
||||
fn resolveRelocInner(
|
||||
@ -704,7 +713,7 @@ fn resolveRelocInner(
|
||||
if (rel.getTargetSymbol(macho_file).flags.has_got) {
|
||||
try writer.writeInt(i32, @intCast(G + A - P), .little);
|
||||
} else {
|
||||
try x86_64.relaxGotLoad(code[rel_offset - 3 ..]);
|
||||
try x86_64.relaxGotLoad(self, code[rel_offset - 3 ..], rel, macho_file);
|
||||
try writer.writeInt(i32, @intCast(S + A - P), .little);
|
||||
}
|
||||
},
|
||||
@ -898,7 +907,7 @@ fn resolveRelocInner(
|
||||
}
|
||||
|
||||
const x86_64 = struct {
|
||||
fn relaxGotLoad(code: []u8) error{RelaxFail}!void {
|
||||
fn relaxGotLoad(self: Atom, code: []u8, rel: Relocation, macho_file: *MachO) ResolveError!void {
|
||||
const old_inst = disassemble(code) orelse return error.RelaxFail;
|
||||
switch (old_inst.encoding.mnemonic) {
|
||||
.mov => {
|
||||
@ -906,7 +915,18 @@ const x86_64 = struct {
|
||||
relocs_log.debug(" relaxing {} => {}", .{ old_inst.encoding, inst.encoding });
|
||||
encode(&.{inst}, code) catch return error.RelaxFail;
|
||||
},
|
||||
else => return error.RelaxFail,
|
||||
else => |x| {
|
||||
var err = try macho_file.addErrorWithNotes(2);
|
||||
try err.addMsg(macho_file, "{s}: 0x{x}: 0x{x}: failed to relax relocation of type {s}", .{
|
||||
self.getName(macho_file),
|
||||
self.value,
|
||||
rel.offset,
|
||||
@tagName(rel.type),
|
||||
});
|
||||
try err.addNote(macho_file, "expected .mov instruction but found .{s}", .{@tagName(x)});
|
||||
try err.addNote(macho_file, "while parsing {}", .{self.getFile(macho_file).fmtPath()});
|
||||
return error.RelaxFailUnexpectedInstruction;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -390,7 +390,7 @@ pub fn getDeclVAddr(
|
||||
.pcrel = false,
|
||||
.has_subtractor = false,
|
||||
.length = 3,
|
||||
.symbolnum = 0,
|
||||
.symbolnum = @intCast(sym.nlist_idx),
|
||||
},
|
||||
});
|
||||
return vaddr;
|
||||
@ -416,7 +416,7 @@ pub fn getAnonDeclVAddr(
|
||||
.pcrel = false,
|
||||
.has_subtractor = false,
|
||||
.length = 3,
|
||||
.symbolnum = 0,
|
||||
.symbolnum = @intCast(sym.nlist_idx),
|
||||
},
|
||||
});
|
||||
return vaddr;
|
||||
@ -856,21 +856,18 @@ fn createTlvDescriptor(
|
||||
atom.alignment = alignment;
|
||||
atom.size = size;
|
||||
|
||||
const tlv_bootstrap_index = blk: {
|
||||
const index = try self.getGlobalSymbol(macho_file, "_tlv_bootstrap", null);
|
||||
break :blk self.symbols.items[index];
|
||||
};
|
||||
const tlv_bootstrap_index = try self.getGlobalSymbol(macho_file, "_tlv_bootstrap", null);
|
||||
try atom.addReloc(macho_file, .{
|
||||
.tag = .@"extern",
|
||||
.offset = 0,
|
||||
.target = tlv_bootstrap_index,
|
||||
.target = self.symbols.items[tlv_bootstrap_index],
|
||||
.addend = 0,
|
||||
.type = .unsigned,
|
||||
.meta = .{
|
||||
.pcrel = false,
|
||||
.has_subtractor = false,
|
||||
.length = 3,
|
||||
.symbolnum = 0,
|
||||
.symbolnum = @intCast(tlv_bootstrap_index),
|
||||
},
|
||||
});
|
||||
try atom.addReloc(macho_file, .{
|
||||
@ -883,7 +880,7 @@ fn createTlvDescriptor(
|
||||
.pcrel = false,
|
||||
.has_subtractor = false,
|
||||
.length = 3,
|
||||
.symbolnum = 0,
|
||||
.symbolnum = @intCast(macho_file.getSymbol(init_sym_index).nlist_idx),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user