aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/link/MachO/Object.zig28
-rw-r--r--src/link/MachO/Symbol.zig5
-rw-r--r--src/link/MachO/Zld.zig29
-rw-r--r--src/link/MachO/reloc.zig14
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: {