aboutsummaryrefslogtreecommitdiff
path: root/src/link/MachO/Zld.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2021-07-08 11:57:14 +0200
committerJakub Konka <kubkon@jakubkonka.com>2021-07-15 18:49:47 +0200
commit961b463fad37e00fa8a2ca2bbfcb58a2b1d2bea9 (patch)
treed519b6a8b66c585d0c1ee87175ae4d95044792af /src/link/MachO/Zld.zig
parent7aeedc0912c8218773891ae98a729bb2b1be5231 (diff)
downloadzig-961b463fad37e00fa8a2ca2bbfcb58a2b1d2bea9.tar.gz
zig-961b463fad37e00fa8a2ca2bbfcb58a2b1d2bea9.zip
zld: track symbols defined within TextBlock
in case TextBlock represents an entire section with symbols defined within.
Diffstat (limited to 'src/link/MachO/Zld.zig')
-rw-r--r--src/link/MachO/Zld.zig76
1 files changed, 55 insertions, 21 deletions
diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig
index e137e16e9b..cdc0732c34 100644
--- a/src/link/MachO/Zld.zig
+++ b/src/link/MachO/Zld.zig
@@ -121,9 +121,11 @@ pub const Output = struct {
};
pub const TextBlock = struct {
+ allocator: *Allocator,
local_sym_index: u32,
aliases: ?[]u32 = null,
references: std.AutoArrayHashMap(u32, void),
+ contained: ?[]SymbolAtOffset = null,
code: []u8,
relocs: std.ArrayList(Relocation),
size: u64,
@@ -133,20 +135,42 @@ pub const TextBlock = struct {
next: ?*TextBlock = null,
prev: ?*TextBlock = null,
+ pub const SymbolAtOffset = struct {
+ local_sym_index: u32,
+ offset: u64,
+ };
+
pub const TlvOffset = struct {
local_sym_index: u32,
offset: u64,
};
- pub fn deinit(block: *TextBlock, allocator: *Allocator) void {
- if (block.aliases) |aliases| {
- allocator.free(aliases);
+ pub fn init(allocator: *Allocator) TextBlock {
+ return .{
+ .allocator = allocator,
+ .local_sym_index = undefined,
+ .references = std.AutoArrayHashMap(u32, void).init(allocator),
+ .code = undefined,
+ .relocs = std.ArrayList(Relocation).init(allocator),
+ .size = undefined,
+ .alignment = undefined,
+ .rebases = std.ArrayList(u64).init(allocator),
+ .tlv_offsets = std.ArrayList(TextBlock.TlvOffset).init(allocator),
+ };
+ }
+
+ pub fn deinit(self: *TextBlock) void {
+ if (self.aliases) |aliases| {
+ self.allocator.free(aliases);
+ }
+ self.references.deinit();
+ if (self.contained) |contained| {
+ self.allocator.free(contained);
}
- block.relocs.deinit();
- block.references.deinit();
- block.rebases.deinit();
- block.tlv_offsets.deinit();
- allocator.free(block.code);
+ self.allocator.free(self.code);
+ self.relocs.deinit();
+ self.rebases.deinit();
+ self.tlv_offsets.deinit();
}
pub fn print_this(self: *const TextBlock, zld: *Zld) void {
@@ -164,6 +188,12 @@ pub const TextBlock = struct {
log.warn(" | {}: {}", .{ index, zld.locals.items[index] });
}
}
+ if (self.contained) |contained| {
+ log.warn(" | contained symbols:", .{});
+ for (contained) |sym_at_off| {
+ log.warn(" | {}: {}", .{ sym_at_off.offset, zld.locals.items[sym_at_off.local_sym_index] });
+ }
+ }
log.warn(" | code.len = {}", .{self.code.len});
if (self.relocs.items.len > 0) {
log.warn(" | relocations:", .{});
@@ -1021,10 +1051,20 @@ fn allocateTextBlocks(self: *Zld) !void {
var base_addr: u64 = sect.addr + sect.size;
while (true) {
+ base_addr -= block.size;
+
const sym = self.locals.items[block.local_sym_index];
assert(sym.payload == .regular);
- sym.payload.regular.address = base_addr - block.size;
- base_addr -= block.size;
+ sym.payload.regular.address = base_addr;
+
+ // Update each symbol contained within the TextBlock
+ if (block.contained) |contained| {
+ for (contained) |sym_at_off| {
+ const contained_sym = self.locals.items[sym_at_off.local_sym_index];
+ assert(contained_sym.payload == .regular);
+ contained_sym.payload.regular.address = base_addr + sym_at_off.offset;
+ }
+ }
if (block.prev) |prev| {
block = prev;
@@ -1476,16 +1516,11 @@ fn resolveSymbols(self: *Zld) !void {
const block = try self.allocator.create(TextBlock);
errdefer self.allocator.destroy(block);
- block.* = .{
- .local_sym_index = local_sym_index,
- .references = std.AutoArrayHashMap(u32, void).init(self.allocator),
- .code = code,
- .relocs = std.ArrayList(Relocation).init(self.allocator),
- .rebases = std.ArrayList(u64).init(self.allocator),
- .tlv_offsets = std.ArrayList(TextBlock.TlvOffset).init(self.allocator),
- .size = size,
- .alignment = alignment,
- };
+ block.* = TextBlock.init(self.allocator);
+ block.local_sym_index = local_sym_index;
+ block.code = code;
+ block.size = size;
+ block.alignment = alignment;
if (self.blocks.getPtr(match)) |last| {
last.*.next = block;
@@ -1907,7 +1942,6 @@ fn addRpaths(self: *Zld, rpaths: []const []const u8) !void {
fn flush(self: *Zld) !void {
try self.writeStubHelperCommon();
- try self.resolveRelocsAndWriteSections();
if (self.common_section_index) |index| {
const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;