mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
zld: refactor out logic for dylib LC creation
This commit is contained in:
parent
138cecc028
commit
17b2588598
@ -2096,28 +2096,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
|
||||
}
|
||||
if (self.libsystem_cmd_index == null) {
|
||||
self.libsystem_cmd_index = @intCast(u16, self.load_commands.items.len);
|
||||
const cmdsize = @intCast(u32, mem.alignForwardGeneric(
|
||||
u64,
|
||||
@sizeOf(macho.dylib_command) + mem.lenZ(LIB_SYSTEM_PATH),
|
||||
@sizeOf(u64),
|
||||
));
|
||||
// TODO Find a way to work out runtime version from the OS version triple stored in std.Target.
|
||||
// In the meantime, we're gonna hardcode to the minimum compatibility version of 0.0.0.
|
||||
const min_version = 0x0;
|
||||
var dylib_cmd = emptyGenericCommandWithData(macho.dylib_command{
|
||||
.cmd = macho.LC_LOAD_DYLIB,
|
||||
.cmdsize = cmdsize,
|
||||
.dylib = .{
|
||||
.name = @sizeOf(macho.dylib_command),
|
||||
.timestamp = 2, // not sure why not simply 0; this is reverse engineered from Mach-O files
|
||||
.current_version = min_version,
|
||||
.compatibility_version = min_version,
|
||||
},
|
||||
});
|
||||
dylib_cmd.data = try self.base.allocator.alloc(u8, cmdsize - dylib_cmd.inner.dylib.name);
|
||||
mem.set(u8, dylib_cmd.data, 0);
|
||||
mem.copy(u8, dylib_cmd.data, mem.spanZ(LIB_SYSTEM_PATH));
|
||||
|
||||
var dylib_cmd = try createLoadDylibCommand(self.base.allocator, mem.spanZ(LIB_SYSTEM_PATH), 2, 0, 0);
|
||||
errdefer dylib_cmd.deinit(self.base.allocator);
|
||||
|
||||
try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd });
|
||||
|
||||
self.header_dirty = true;
|
||||
self.load_commands_dirty = true;
|
||||
}
|
||||
|
||||
@ -339,26 +339,10 @@ fn parseDylibs(self: *Zld, shared_libs: []const []const u8) !void {
|
||||
try self.dylibs.append(self.allocator, dylib);
|
||||
|
||||
// Add LC_LOAD_DYLIB command
|
||||
const cmdsize = @intCast(u32, mem.alignForwardGeneric(
|
||||
u64,
|
||||
@sizeOf(macho.dylib_command) + dylib.name.?.len,
|
||||
@sizeOf(u64),
|
||||
));
|
||||
// TODO Read the min version from the dylib itself.
|
||||
const min_version = 0x0;
|
||||
var dylib_cmd = emptyGenericCommandWithData(macho.dylib_command{
|
||||
.cmd = macho.LC_LOAD_DYLIB,
|
||||
.cmdsize = cmdsize,
|
||||
.dylib = .{
|
||||
.name = @sizeOf(macho.dylib_command),
|
||||
.timestamp = 2, // TODO parse from the dylib.
|
||||
.current_version = min_version,
|
||||
.compatibility_version = min_version,
|
||||
},
|
||||
});
|
||||
dylib_cmd.data = try self.allocator.alloc(u8, cmdsize - dylib_cmd.inner.dylib.name);
|
||||
mem.set(u8, dylib_cmd.data, 0);
|
||||
mem.copy(u8, dylib_cmd.data, dylib.name.?);
|
||||
// TODO Read the timestamp and versions from the dylib itself.
|
||||
var dylib_cmd = try createLoadDylibCommand(self.allocator, dylib.name.?, 2, 0, 0);
|
||||
errdefer dylib_cmd.deinit(self.allocator);
|
||||
|
||||
try self.load_commands.append(self.allocator, .{ .Dylib = dylib_cmd });
|
||||
}
|
||||
}
|
||||
@ -2061,27 +2045,10 @@ fn populateMetadata(self: *Zld) !void {
|
||||
|
||||
if (self.libsystem_cmd_index == null) {
|
||||
self.libsystem_cmd_index = @intCast(u16, self.load_commands.items.len);
|
||||
const cmdsize = @intCast(u32, mem.alignForwardGeneric(
|
||||
u64,
|
||||
@sizeOf(macho.dylib_command) + mem.lenZ(LIB_SYSTEM_PATH),
|
||||
@sizeOf(u64),
|
||||
));
|
||||
// TODO Find a way to work out runtime version from the OS version triple stored in std.Target.
|
||||
// In the meantime, we're gonna hardcode to the minimum compatibility version of 0.0.0.
|
||||
const min_version = 0x0;
|
||||
var dylib_cmd = emptyGenericCommandWithData(macho.dylib_command{
|
||||
.cmd = macho.LC_LOAD_DYLIB,
|
||||
.cmdsize = cmdsize,
|
||||
.dylib = .{
|
||||
.name = @sizeOf(macho.dylib_command),
|
||||
.timestamp = 2, // not sure why not simply 0; this is reverse engineered from Mach-O files
|
||||
.current_version = min_version,
|
||||
.compatibility_version = min_version,
|
||||
},
|
||||
});
|
||||
dylib_cmd.data = try self.allocator.alloc(u8, cmdsize - dylib_cmd.inner.dylib.name);
|
||||
mem.set(u8, dylib_cmd.data, 0);
|
||||
mem.copy(u8, dylib_cmd.data, mem.spanZ(LIB_SYSTEM_PATH));
|
||||
|
||||
var dylib_cmd = try createLoadDylibCommand(self.allocator, mem.spanZ(LIB_SYSTEM_PATH), 2, 0, 0);
|
||||
errdefer dylib_cmd.deinit(self.allocator);
|
||||
|
||||
try self.load_commands.append(self.allocator, .{ .Dylib = dylib_cmd });
|
||||
}
|
||||
|
||||
@ -2738,11 +2705,15 @@ fn writeSymbolTable(self: *Zld) !void {
|
||||
|
||||
for (self.imports.items()) |entry| {
|
||||
const sym = entry.value;
|
||||
const ordinal = ordinal: {
|
||||
const dylib = sym.cast(Symbol.Proxy).?.dylib orelse break :ordinal 1; // TODO handle libSystem
|
||||
break :ordinal dylib.ordinal.?;
|
||||
};
|
||||
try undefs.append(.{
|
||||
.n_strx = try self.makeString(sym.name),
|
||||
.n_type = macho.N_UNDF | macho.N_EXT,
|
||||
.n_sect = 0,
|
||||
.n_desc = macho.N_SYMBOL_RESOLVER | macho.REFERENCE_FLAG_UNDEFINED_NON_LAZY,
|
||||
.n_desc = (ordinal * macho.N_SYMBOL_RESOLVER) | macho.REFERENCE_FLAG_UNDEFINED_NON_LAZY,
|
||||
.n_value = 0,
|
||||
});
|
||||
}
|
||||
|
||||
@ -298,6 +298,37 @@ pub fn GenericCommandWithData(comptime Cmd: type) type {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn createLoadDylibCommand(
|
||||
allocator: *Allocator,
|
||||
name: []const u8,
|
||||
timestamp: u32,
|
||||
current_version: u32,
|
||||
compatibility_version: u32,
|
||||
) !GenericCommandWithData(macho.dylib_command) {
|
||||
const cmdsize = @intCast(u32, mem.alignForwardGeneric(
|
||||
u64,
|
||||
@sizeOf(macho.dylib_command) + name.len,
|
||||
@sizeOf(u64),
|
||||
));
|
||||
|
||||
var dylib_cmd = emptyGenericCommandWithData(macho.dylib_command{
|
||||
.cmd = macho.LC_LOAD_DYLIB,
|
||||
.cmdsize = cmdsize,
|
||||
.dylib = .{
|
||||
.name = @sizeOf(macho.dylib_command),
|
||||
.timestamp = timestamp,
|
||||
.current_version = current_version,
|
||||
.compatibility_version = compatibility_version,
|
||||
},
|
||||
});
|
||||
dylib_cmd.data = try allocator.alloc(u8, cmdsize - dylib_cmd.inner.dylib.name);
|
||||
|
||||
mem.set(u8, dylib_cmd.data, 0);
|
||||
mem.copy(u8, dylib_cmd.data, name);
|
||||
|
||||
return dylib_cmd;
|
||||
}
|
||||
|
||||
fn testRead(allocator: *Allocator, buffer: []const u8, expected: anytype) !void {
|
||||
var stream = io.fixedBufferStream(buffer);
|
||||
var given = try LoadCommand.read(allocator, stream.reader());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user