mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-26 13:01:34 +03:00
Support ld64.ldd STABS layout in MachOFile.load
Apple's ld emit N_BNSYM and N_ENSYM to mark the start and end of functions, while ld64.lld doesn't. This resulted in MachOFile.load bailing out on unsupported STABS layout when the linker used is ld64.lld. This commit supports both layouts.
This commit is contained in:
committed by
Andrew Kelley
parent
bc08199ef1
commit
07f05426fc
@@ -158,6 +158,10 @@ pub fn load(gpa: Allocator, io: Io, path: []const u8, arch: std.Target.Cpu.Arch)
|
||||
}
|
||||
|
||||
// TODO handle globals N_GSYM, and statics N_STSYM
|
||||
//
|
||||
// NOTE: ld64.lld and Apple's ld differ in STABS layout.
|
||||
// Apple's ld emit N_BNSYM and N_ENSYM to mark the start and end of
|
||||
// functions, while ld64.lld doesn't.
|
||||
switch (sym.n_type.stab) {
|
||||
.oso => switch (state) {
|
||||
.init, .oso_close => {
|
||||
@@ -178,6 +182,14 @@ pub fn load(gpa: Allocator, io: Io, path: []const u8, arch: std.Target.Cpu.Arch)
|
||||
else => return error.InvalidMachO,
|
||||
},
|
||||
.fun => switch (state) {
|
||||
.oso_open => {
|
||||
state = .fun_strx;
|
||||
last_sym = .{
|
||||
.strx = sym.n_strx,
|
||||
.addr = sym.n_value,
|
||||
.ofile = ofile,
|
||||
};
|
||||
},
|
||||
.bnsym => {
|
||||
state = .fun_strx;
|
||||
last_sym.strx = sym.n_strx;
|
||||
@@ -185,20 +197,24 @@ pub fn load(gpa: Allocator, io: Io, path: []const u8, arch: std.Target.Cpu.Arch)
|
||||
.fun_strx => {
|
||||
state = .fun_size;
|
||||
},
|
||||
.fun_size => {
|
||||
if (last_sym.strx != 0) {
|
||||
appendStabSymbol(&symbols, &symbol_names, strings, last_sym);
|
||||
}
|
||||
last_sym = .{
|
||||
.strx = sym.n_strx,
|
||||
.addr = sym.n_value,
|
||||
.ofile = ofile,
|
||||
};
|
||||
state = .fun_strx;
|
||||
},
|
||||
else => return error.InvalidMachO,
|
||||
},
|
||||
.ensym => switch (state) {
|
||||
.fun_size => {
|
||||
state = .ensym;
|
||||
if (last_sym.strx != 0) {
|
||||
const name = std.mem.sliceTo(strings[last_sym.strx..], 0);
|
||||
const gop = symbol_names.getOrPutAssumeCapacity(name);
|
||||
if (!gop.found_existing) {
|
||||
assert(gop.index == symbols.items.len);
|
||||
symbols.appendAssumeCapacity(last_sym);
|
||||
} else {
|
||||
symbols.items[gop.index] = last_sym;
|
||||
}
|
||||
appendStabSymbol(&symbols, &symbol_names, strings, last_sym);
|
||||
}
|
||||
},
|
||||
else => return error.InvalidMachO,
|
||||
@@ -208,6 +224,12 @@ pub fn load(gpa: Allocator, io: Io, path: []const u8, arch: std.Target.Cpu.Arch)
|
||||
.oso_open, .ensym => {
|
||||
state = .oso_close;
|
||||
},
|
||||
.fun_size => {
|
||||
state = .oso_close;
|
||||
if (last_sym.strx != 0) {
|
||||
appendStabSymbol(&symbols, &symbol_names, strings, last_sym);
|
||||
}
|
||||
},
|
||||
else => return error.InvalidMachO,
|
||||
},
|
||||
else => {},
|
||||
@@ -356,6 +378,22 @@ test {
|
||||
_ = Symbol;
|
||||
}
|
||||
|
||||
fn appendStabSymbol(
|
||||
symbols: *std.ArrayList(Symbol),
|
||||
symbol_names: *std.StringArrayHashMapUnmanaged(void),
|
||||
strings: []const u8,
|
||||
last_sym: Symbol,
|
||||
) void {
|
||||
const name = std.mem.sliceTo(strings[last_sym.strx..], 0);
|
||||
const gop = symbol_names.getOrPutAssumeCapacity(name);
|
||||
if (!gop.found_existing) {
|
||||
assert(gop.index == symbols.items.len);
|
||||
symbols.appendAssumeCapacity(last_sym);
|
||||
} else {
|
||||
symbols.items[gop.index] = last_sym;
|
||||
}
|
||||
}
|
||||
|
||||
fn loadOFile(gpa: Allocator, io: Io, o_file_name: []const u8) !OFile {
|
||||
const all_mapped_memory, const mapped_ofile = map: {
|
||||
const open_paren = paren: {
|
||||
|
||||
Reference in New Issue
Block a user