mirror of
https://github.com/ziglang/zig.git
synced 2025-12-12 09:13:11 +00:00
zld: parse dylib's id from tbd
This commit is contained in:
parent
5e0e7b2cb4
commit
ad0be78577
@ -3,8 +3,10 @@ const Dylib = @This();
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const fs = std.fs;
|
const fs = std.fs;
|
||||||
|
const fmt = std.fmt;
|
||||||
const log = std.log.scoped(.dylib);
|
const log = std.log.scoped(.dylib);
|
||||||
const macho = std.macho;
|
const macho = std.macho;
|
||||||
|
const math = std.math;
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
|
|
||||||
const Allocator = mem.Allocator;
|
const Allocator = mem.Allocator;
|
||||||
@ -37,6 +39,7 @@ id: ?Id = null,
|
|||||||
/// a symbol is referenced by an object file.
|
/// a symbol is referenced by an object file.
|
||||||
symbols: std.StringArrayHashMapUnmanaged(void) = .{},
|
symbols: std.StringArrayHashMapUnmanaged(void) = .{},
|
||||||
|
|
||||||
|
// TODO add parsing re-exported libs from binary dylibs
|
||||||
dependent_libs: std.StringArrayHashMapUnmanaged(void) = .{},
|
dependent_libs: std.StringArrayHashMapUnmanaged(void) = .{},
|
||||||
|
|
||||||
pub const Id = struct {
|
pub const Id = struct {
|
||||||
@ -45,9 +48,72 @@ pub const Id = struct {
|
|||||||
current_version: u32,
|
current_version: u32,
|
||||||
compatibility_version: u32,
|
compatibility_version: u32,
|
||||||
|
|
||||||
|
pub fn default(name: []const u8) Id {
|
||||||
|
return .{
|
||||||
|
.name = name,
|
||||||
|
.timestamp = 2,
|
||||||
|
.current_version = 0x10000,
|
||||||
|
.compatibility_version = 0x10000,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn deinit(id: *Id, allocator: *Allocator) void {
|
pub fn deinit(id: *Id, allocator: *Allocator) void {
|
||||||
allocator.free(id.name);
|
allocator.free(id.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ParseError = fmt.ParseIntError || fmt.BufPrintError;
|
||||||
|
|
||||||
|
pub fn parseCurrentVersion(id: *Id, version: anytype) ParseError!void {
|
||||||
|
id.current_version = try parseVersion(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parseCompatibilityVersion(id: *Id, version: anytype) ParseError!void {
|
||||||
|
id.compatibility_version = try parseVersion(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parseVersion(version: anytype) ParseError!u32 {
|
||||||
|
const string = blk: {
|
||||||
|
switch (version) {
|
||||||
|
.int => |int| {
|
||||||
|
var out: u32 = 0;
|
||||||
|
const major = try math.cast(u16, int);
|
||||||
|
out += @intCast(u32, major) << 16;
|
||||||
|
return out;
|
||||||
|
},
|
||||||
|
.float => |float| {
|
||||||
|
var buf: [256]u8 = undefined;
|
||||||
|
break :blk try fmt.bufPrint(&buf, "{d:.2}", .{float});
|
||||||
|
},
|
||||||
|
.string => |string| {
|
||||||
|
break :blk string;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var out: u32 = 0;
|
||||||
|
var values: [3][]const u8 = undefined;
|
||||||
|
|
||||||
|
var split = mem.split(string, ".");
|
||||||
|
var i: u4 = 0;
|
||||||
|
while (split.next()) |value| {
|
||||||
|
if (i > 2) {
|
||||||
|
log.warn("malformed version field: {s}", .{string});
|
||||||
|
return 0x10000;
|
||||||
|
}
|
||||||
|
values[i] = value;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values.len > 2) {
|
||||||
|
out += try fmt.parseInt(u8, values[2], 10);
|
||||||
|
}
|
||||||
|
if (values.len > 1) {
|
||||||
|
out += @intCast(u32, try fmt.parseInt(u8, values[1], 10)) << 8;
|
||||||
|
}
|
||||||
|
out += @intCast(u32, try fmt.parseInt(u16, values[0], 10)) << 16;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Error = error{
|
pub const Error = error{
|
||||||
@ -55,7 +121,7 @@ pub const Error = error{
|
|||||||
EmptyStubFile,
|
EmptyStubFile,
|
||||||
MismatchedCpuArchitecture,
|
MismatchedCpuArchitecture,
|
||||||
UnsupportedCpuArchitecture,
|
UnsupportedCpuArchitecture,
|
||||||
} || fs.File.OpenError || std.os.PReadError;
|
} || fs.File.OpenError || std.os.PReadError || Id.ParseError;
|
||||||
|
|
||||||
pub fn createAndParseFromPath(
|
pub fn createAndParseFromPath(
|
||||||
allocator: *Allocator,
|
allocator: *Allocator,
|
||||||
@ -195,12 +261,7 @@ fn readLoadCommands(self: *Dylib, reader: anytype) !void {
|
|||||||
fn parseId(self: *Dylib) !void {
|
fn parseId(self: *Dylib) !void {
|
||||||
const index = self.id_cmd_index orelse {
|
const index = self.id_cmd_index orelse {
|
||||||
log.debug("no LC_ID_DYLIB load command found; using hard-coded defaults...", .{});
|
log.debug("no LC_ID_DYLIB load command found; using hard-coded defaults...", .{});
|
||||||
self.id = .{
|
self.id = Id.default(try self.allocator.dupe(u8, self.name.?));
|
||||||
.name = try self.allocator.dupe(u8, self.name.?),
|
|
||||||
.timestamp = 2,
|
|
||||||
.current_version = 0,
|
|
||||||
.compatibility_version = 0,
|
|
||||||
};
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
const id_cmd = self.load_commands.items[index].Dylib;
|
const id_cmd = self.load_commands.items[index].Dylib;
|
||||||
@ -266,13 +327,15 @@ pub fn parseFromStub(self: *Dylib, lib_stub: LibStub) !void {
|
|||||||
log.debug("parsing shared library from stub '{s}'", .{self.name.?});
|
log.debug("parsing shared library from stub '{s}'", .{self.name.?});
|
||||||
|
|
||||||
const umbrella_lib = lib_stub.inner[0];
|
const umbrella_lib = lib_stub.inner[0];
|
||||||
self.id = .{
|
|
||||||
.name = try self.allocator.dupe(u8, umbrella_lib.install_name),
|
var id = Id.default(try self.allocator.dupe(u8, umbrella_lib.install_name));
|
||||||
// TODO parse from the stub
|
if (umbrella_lib.current_version) |version| {
|
||||||
.timestamp = 2,
|
try id.parseCurrentVersion(version);
|
||||||
.current_version = 0,
|
}
|
||||||
.compatibility_version = 0,
|
if (umbrella_lib.compatibility_version) |version| {
|
||||||
};
|
try id.parseCompatibilityVersion(version);
|
||||||
|
}
|
||||||
|
self.id = id;
|
||||||
|
|
||||||
const target_string: []const u8 = switch (self.arch.?) {
|
const target_string: []const u8 = switch (self.arch.?) {
|
||||||
.aarch64 => "arm64-macos",
|
.aarch64 => "arm64-macos",
|
||||||
|
|||||||
@ -26,6 +26,11 @@ pub const LibStub = struct {
|
|||||||
float: f64,
|
float: f64,
|
||||||
int: u64,
|
int: u64,
|
||||||
},
|
},
|
||||||
|
compatibility_version: ?union(enum) {
|
||||||
|
string: []const u8,
|
||||||
|
float: f64,
|
||||||
|
int: u64,
|
||||||
|
},
|
||||||
reexported_libraries: ?[]const struct {
|
reexported_libraries: ?[]const struct {
|
||||||
targets: []const []const u8,
|
targets: []const []const u8,
|
||||||
libraries: []const []const u8,
|
libraries: []const []const u8,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user