mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
zld: clean up memory management and refactor
This commit is contained in:
parent
1ff3ebffa3
commit
52a9d3f037
@ -41,6 +41,9 @@ pub fn init(allocator: *Allocator) Stub {
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Stub) void {
|
||||
for (self.symbols.keys()) |key| {
|
||||
self.allocator.free(key);
|
||||
}
|
||||
self.symbols.deinit(self.allocator);
|
||||
|
||||
if (self.lib_stub) |*lib_stub| {
|
||||
@ -56,6 +59,18 @@ pub fn deinit(self: *Stub) void {
|
||||
}
|
||||
}
|
||||
|
||||
fn addObjCClassSymbols(self: *Stub, sym_name: []const u8) !void {
|
||||
const expanded = &[_][]const u8{
|
||||
try std.fmt.allocPrint(self.allocator, "_OBJC_CLASS_$_{s}", .{sym_name}),
|
||||
try std.fmt.allocPrint(self.allocator, "_OBJC_METACLASS_$_{s}", .{sym_name}),
|
||||
};
|
||||
|
||||
for (expanded) |sym| {
|
||||
if (self.symbols.contains(sym)) continue;
|
||||
try self.symbols.putNoClobber(self.allocator, sym, .{});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(self: *Stub) !void {
|
||||
const lib_stub = self.lib_stub orelse return error.EmptyStubFile;
|
||||
if (lib_stub.inner.len == 0) return error.EmptyStubFile;
|
||||
@ -87,32 +102,13 @@ pub fn parse(self: *Stub) !void {
|
||||
if (exp.symbols) |symbols| {
|
||||
for (symbols) |sym_name| {
|
||||
if (self.symbols.contains(sym_name)) continue;
|
||||
try self.symbols.putNoClobber(self.allocator, sym_name, {});
|
||||
try self.symbols.putNoClobber(self.allocator, try self.allocator.dupe(u8, sym_name), {});
|
||||
}
|
||||
}
|
||||
|
||||
if (exp.objc_classes) |classes| {
|
||||
for (classes) |sym_name| {
|
||||
log.debug(" | {s}", .{sym_name});
|
||||
{
|
||||
const actual_sym_name = try std.fmt.allocPrint(
|
||||
self.allocator,
|
||||
"_OBJC_CLASS_$_{s}",
|
||||
.{sym_name},
|
||||
);
|
||||
if (self.symbols.contains(actual_sym_name)) continue;
|
||||
try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
|
||||
}
|
||||
|
||||
{
|
||||
const actual_sym_name = try std.fmt.allocPrint(
|
||||
self.allocator,
|
||||
"_OBJC_METACLASS_$_{s}",
|
||||
.{sym_name},
|
||||
);
|
||||
if (self.symbols.contains(actual_sym_name)) continue;
|
||||
try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
|
||||
}
|
||||
try self.addObjCClassSymbols(sym_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,34 +120,14 @@ pub fn parse(self: *Stub) !void {
|
||||
|
||||
for (reexp.symbols) |sym_name| {
|
||||
if (self.symbols.contains(sym_name)) continue;
|
||||
try self.symbols.putNoClobber(self.allocator, sym_name, {});
|
||||
try self.symbols.putNoClobber(self.allocator, try self.allocator.dupe(u8, sym_name), {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stub.objc_classes) |classes| {
|
||||
log.debug(" | objc_classes", .{});
|
||||
for (classes) |sym_name| {
|
||||
log.debug(" | {s}", .{sym_name});
|
||||
{
|
||||
const actual_sym_name = try std.fmt.allocPrint(
|
||||
self.allocator,
|
||||
"_OBJC_CLASS_$_{s}",
|
||||
.{sym_name},
|
||||
);
|
||||
if (self.symbols.contains(actual_sym_name)) continue;
|
||||
try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
|
||||
}
|
||||
|
||||
{
|
||||
const actual_sym_name = try std.fmt.allocPrint(
|
||||
self.allocator,
|
||||
"_OBJC_METACLASS_$_{s}",
|
||||
.{sym_name},
|
||||
);
|
||||
if (self.symbols.contains(actual_sym_name)) continue;
|
||||
try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
|
||||
}
|
||||
try self.addObjCClassSymbols(sym_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,6 +74,8 @@ pub const Regular = struct {
|
||||
global,
|
||||
};
|
||||
|
||||
pub fn deinit(regular: *Regular, allocator: *Allocator) void {}
|
||||
|
||||
pub fn isTemp(regular: *Regular) bool {
|
||||
if (regular.linkage == .translation_unit) {
|
||||
return mem.startsWith(u8, regular.base.name, "l") or mem.startsWith(u8, regular.base.name, "L");
|
||||
@ -85,6 +87,8 @@ pub const Regular = struct {
|
||||
pub const Proxy = struct {
|
||||
base: Symbol,
|
||||
|
||||
/// Dynamic binding info - spots within the final
|
||||
/// executable where this proxy is referenced from.
|
||||
bind_info: std.ArrayListUnmanaged(struct {
|
||||
segment_id: u16,
|
||||
address: u64,
|
||||
@ -99,6 +103,10 @@ pub const Proxy = struct {
|
||||
|
||||
pub const base_type: Symbol.Type = .proxy;
|
||||
|
||||
pub fn deinit(proxy: *Proxy, allocator: *Allocator) void {
|
||||
proxy.bind_info.deinit(allocator);
|
||||
}
|
||||
|
||||
pub fn dylibOrdinal(proxy: *Proxy) u16 {
|
||||
const file = proxy.file orelse return 0;
|
||||
return switch (file) {
|
||||
@ -115,6 +123,8 @@ pub const Unresolved = struct {
|
||||
file: *Object,
|
||||
|
||||
pub const base_type: Symbol.Type = .unresolved;
|
||||
|
||||
pub fn deinit(unresolved: *Unresolved, allocator: *Allocator) void {}
|
||||
};
|
||||
|
||||
pub const Tentative = struct {
|
||||
@ -130,10 +140,18 @@ pub const Tentative = struct {
|
||||
file: *Object,
|
||||
|
||||
pub const base_type: Symbol.Type = .tentative;
|
||||
|
||||
pub fn deinit(tentative: *Tentative, allocator: *Allocator) void {}
|
||||
};
|
||||
|
||||
pub fn deinit(base: *Symbol, allocator: *Allocator) void {
|
||||
allocator.free(base.name);
|
||||
switch (base.@"type") {
|
||||
.regular => @fieldParentPtr(Regular, "base", base).deinit(allocator),
|
||||
.proxy => @fieldParentPtr(Proxy, "base", base).deinit(allocator),
|
||||
.unresolved => @fieldParentPtr(Unresolved, "base", base).deinit(allocator),
|
||||
.tentative => @fieldParentPtr(Tentative, "base", base).deinit(allocator),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cast(base: *Symbol, comptime T: type) ?*T {
|
||||
|
||||
@ -263,7 +263,7 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: L
|
||||
self.allocateLinkeditSegment();
|
||||
try self.allocateSymbols();
|
||||
try self.allocateTentativeSymbols();
|
||||
try self.allocateProxiesBindAddresses();
|
||||
try self.allocateProxyBindAddresses();
|
||||
try self.flush();
|
||||
}
|
||||
|
||||
@ -1347,7 +1347,7 @@ fn allocateTentativeSymbols(self: *Zld) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn allocateProxiesBindAddresses(self: *Zld) !void {
|
||||
fn allocateProxyBindAddresses(self: *Zld) !void {
|
||||
for (self.objects.items) |object| {
|
||||
for (object.sections.items) |sect| {
|
||||
const relocs = sect.relocs orelse continue;
|
||||
@ -1361,6 +1361,7 @@ fn allocateProxiesBindAddresses(self: *Zld) !void {
|
||||
const target_map = sect.target_map orelse continue;
|
||||
const target_seg = self.load_commands.items[target_map.segment_id].Segment;
|
||||
const target_sect = target_seg.sections.items[target_map.section_id];
|
||||
|
||||
try proxy.bind_info.append(self.allocator, .{
|
||||
.segment_id = target_map.segment_id,
|
||||
.address = target_sect.addr + target_map.offset + rel.offset,
|
||||
@ -2119,7 +2120,10 @@ fn relocTargetAddr(self: *Zld, object: *const Object, target: reloc.Relocation.T
|
||||
if (proxy.bind_info.items.len > 0) {
|
||||
break :blk 0; // Dynamically bound by dyld.
|
||||
}
|
||||
log.err("expected stubs index or dynamic bind address when relocating symbol '{s}'", .{final.name});
|
||||
log.err(
|
||||
"expected stubs index or dynamic bind address when relocating symbol '{s}'",
|
||||
.{final.name},
|
||||
);
|
||||
log.err("this is an internal linker error", .{});
|
||||
return error.FailedToResolveRelocationTarget;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user