diff options
| -rw-r--r-- | src/link/MachO/Object.zig | 28 | ||||
| -rw-r--r-- | src/link/MachO/Symbol.zig | 5 | ||||
| -rw-r--r-- | src/link/MachO/Zld.zig | 29 | ||||
| -rw-r--r-- | src/link/MachO/reloc.zig | 14 |
4 files changed, 36 insertions, 40 deletions
diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 011aca06c3..f000119edf 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -435,6 +435,8 @@ const TextBlockParser = struct { .references = std.AutoArrayHashMap(u32, void).init(self.allocator), .code = try self.allocator.dupe(u8, code), .relocs = std.ArrayList(Relocation).init(self.allocator), + .rebases = std.ArrayList(u64).init(self.allocator), + .tlv_offsets = std.ArrayList(u64).init(self.allocator), .size = size, .alignment = self.section.@"align", }; @@ -444,18 +446,6 @@ const TextBlockParser = struct { try self.object.parseRelocs(self.zld, relocs, block, start_addr); } - const is_zerofill = blk: { - const tseg = self.zld.load_commands.items[self.match.seg].Segment; - const tsect = tseg.sections.items[self.match.sect]; - const tsect_type = sectionType(tsect); - break :blk tsect_type == macho.S_ZEROFILL or - tsect_type == macho.S_THREAD_LOCAL_ZEROFILL or - tsect_type == macho.S_THREAD_LOCAL_VARIABLES; - }; - if (is_zerofill) { - mem.set(u8, block.code, 0); - } - self.index += 1; return block; @@ -589,6 +579,8 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void { .references = std.AutoArrayHashMap(u32, void).init(self.allocator), .code = try self.allocator.dupe(u8, code), .relocs = std.ArrayList(Relocation).init(self.allocator), + .rebases = std.ArrayList(u64).init(self.allocator), + .tlv_offsets = std.ArrayList(u64).init(self.allocator), .size = sect.size, .alignment = sect.@"align", }; @@ -597,18 +589,6 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void { try self.parseRelocs(zld, relocs, block, 0); } - const is_zerofill = blk: { - const tseg = zld.load_commands.items[match.seg].Segment; - const tsect = tseg.sections.items[match.sect]; - const tsect_type = sectionType(tsect); - break :blk tsect_type == macho.S_ZEROFILL or - tsect_type == macho.S_THREAD_LOCAL_ZEROFILL or - tsect_type == macho.S_THREAD_LOCAL_VARIABLES; - }; - if (is_zerofill) { - mem.set(u8, block.code, 0); - } - if (zld.blocks.getPtr(match)) |last| { last.*.next = block; block.prev = last.*; diff --git a/src/link/MachO/Symbol.zig b/src/link/MachO/Symbol.zig index 5f437dc209..86624653f5 100644 --- a/src/link/MachO/Symbol.zig +++ b/src/link/MachO/Symbol.zig @@ -58,8 +58,6 @@ pub const Regular = struct { local_sym_index: u32 = 0, - should_rebase: bool = false, - pub const Linkage = enum { translation_unit, linkage_unit, @@ -77,9 +75,6 @@ pub const Regular = struct { if (self.weak_ref) { try std.fmt.format(writer, ".weak_ref, ", .{}); } - if (self.should_rebase) { - try std.fmt.format(writer, ".should_rebase, ", .{}); - } if (self.file) |file| { try std.fmt.format(writer, ".file = {s}, ", .{file.name.?}); } diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig index 485f6eda42..53bb31a718 100644 --- a/src/link/MachO/Zld.zig +++ b/src/link/MachO/Zld.zig @@ -128,6 +128,8 @@ pub const TextBlock = struct { relocs: std.ArrayList(Relocation), size: u64, alignment: u32, + rebases: std.ArrayList(u64), + tlv_offsets: std.ArrayList(u64), next: ?*TextBlock = null, prev: ?*TextBlock = null, @@ -137,6 +139,8 @@ pub const TextBlock = struct { } block.relocs.deinit(); block.references.deinit(); + block.rebases.deinit(); + block.tlv_offsets.deinit(); allocator.free(block.code); } @@ -144,24 +148,30 @@ pub const TextBlock = struct { log.warn("TextBlock", .{}); log.warn(" | {}: {}", .{ self.local_sym_index, zld.locals.items[self.local_sym_index] }); if (self.aliases) |aliases| { - log.warn(" | Aliases:", .{}); + log.warn(" | aliases:", .{}); for (aliases) |index| { log.warn(" | {}: {}", .{ index, zld.locals.items[index] }); } } if (self.references.count() > 0) { - log.warn(" | References:", .{}); + log.warn(" | references:", .{}); for (self.references.keys()) |index| { log.warn(" | {}: {}", .{ index, zld.locals.items[index] }); } } log.warn(" | code.len = {}", .{self.code.len}); if (self.relocs.items.len > 0) { - log.warn("Relocations:", .{}); + log.warn(" | relocations:", .{}); for (self.relocs.items) |rel| { - log.warn(" | {}", .{rel}); + log.warn(" | {}", .{rel}); } } + if (self.rebases.items.len > 0) { + log.warn(" | rebases: {any}", .{self.rebases.items}); + } + if (self.tlv_offsets.items.len > 0) { + log.warn(" | TLV offsets: {any}", .{self.tlv_offsets.items}); + } log.warn(" | size = {}", .{self.size}); log.warn(" | align = {}", .{self.alignment}); } @@ -271,6 +281,10 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg try self.addRpaths(args.rpaths); try self.addDataInCodeLC(); try self.addCodeSignatureLC(); + // try self.allocateTextSegment(); + // try self.allocateDataConstSegment(); + // try self.allocateDataSegment(); + // self.allocateLinkeditSegment(); var it = self.blocks.iterator(); while (it.next()) |entry| { @@ -281,11 +295,6 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg entry.value_ptr.*.print(self); } return error.TODO; - // try self.allocateTextSegment(); - // try self.allocateDataConstSegment(); - // try self.allocateDataSegment(); - // self.allocateLinkeditSegment(); - // try self.allocateSymbols(); // try self.flush(); } @@ -1477,6 +1486,8 @@ fn resolveSymbols(self: *Zld) !void { .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(u64).init(self.allocator), .size = size, .alignment = alignment, }; diff --git a/src/link/MachO/reloc.zig b/src/link/MachO/reloc.zig index d35344c71b..b645ec152e 100644 --- a/src/link/MachO/reloc.zig +++ b/src/link/MachO/reloc.zig @@ -405,7 +405,7 @@ pub const Relocation = struct { pub fn resolve(self: Relocation, zld: *Zld) !void { const source_addr = blk: { const sym = zld.locals.items[self.block.local_sym_index]; - break :blk sym.payload.regular.address; + break :blk sym.payload.regular.address + self.offset; }; const target_addr = blk: { const is_via_got = inner: { @@ -668,7 +668,17 @@ pub const Parser = struct { break :rebase true; }; - source_reg.should_rebase = should_rebase; + + if (should_rebase) { + try self.block.rebases.append(out_rel.offset); + } + + // TLV is handled via a separate offset mechanism. + // Save the offset to the initializer. + // TODO I believe this can be simplified a lot! + if (sect_type == macho.S_THREAD_LOCAL_VARIABLES) { + try self.block.tlv_offsets.append(out_rel.offset); + } }, } } else if (out_rel.payload == .branch) blk: { |
