| author | |
| committer | |
| log | e524f43a6fbb5189d24aa42667ababdcd92a2ab2 |
| tree | ec68e9b10d3c6d9e03932db7a09459419ccbf3e4 |
| parent | 7c662db8d95670f8ac0c88e9a2d6f49ef6782f13 |
instead of as part of the Symbol. This seems to be more
optimal way of handling dyld ops in presence of no splittable
input sections in object files.4 files changed, 36 insertions(+), 40 deletions(-)
src/link/MachO/Object.zig+4-24| ... | @@ -435,6 +435,8 @@ const TextBlockParser = struct { | ... | @@ -435,6 +435,8 @@ const TextBlockParser = struct { |
| 435 | .references = std.AutoArrayHashMap(u32, void).init(self.allocator), | 435 | .references = std.AutoArrayHashMap(u32, void).init(self.allocator), |
| 436 | .code = try self.allocator.dupe(u8, code), | 436 | .code = try self.allocator.dupe(u8, code), |
| 437 | .relocs = std.ArrayList(Relocation).init(self.allocator), | 437 | .relocs = std.ArrayList(Relocation).init(self.allocator), |
| 438 | .rebases = std.ArrayList(u64).init(self.allocator), | ||
| 439 | .tlv_offsets = std.ArrayList(u64).init(self.allocator), | ||
| 438 | .size = size, | 440 | .size = size, |
| 439 | .alignment = self.section.@"align", | 441 | .alignment = self.section.@"align", |
| 440 | }; | 442 | }; |
| ... | @@ -444,18 +446,6 @@ const TextBlockParser = struct { | ... | @@ -444,18 +446,6 @@ const TextBlockParser = struct { |
| 444 | try self.object.parseRelocs(self.zld, relocs, block, start_addr); | 446 | try self.object.parseRelocs(self.zld, relocs, block, start_addr); |
| 445 | } | 447 | } |
| 446 | 448 | ||
| 447 | const is_zerofill = blk: { | ||
| 448 | const tseg = self.zld.load_commands.items[self.match.seg].Segment; | ||
| 449 | const tsect = tseg.sections.items[self.match.sect]; | ||
| 450 | const tsect_type = sectionType(tsect); | ||
| 451 | break :blk tsect_type == macho.S_ZEROFILL or | ||
| 452 | tsect_type == macho.S_THREAD_LOCAL_ZEROFILL or | ||
| 453 | tsect_type == macho.S_THREAD_LOCAL_VARIABLES; | ||
| 454 | }; | ||
| 455 | if (is_zerofill) { | ||
| 456 | mem.set(u8, block.code, 0); | ||
| 457 | } | ||
| 458 | |||
| 459 | self.index += 1; | 449 | self.index += 1; |
| 460 | 450 | ||
| 461 | return block; | 451 | return block; |
| ... | @@ -589,6 +579,8 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void { | ... | @@ -589,6 +579,8 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void { |
| 589 | .references = std.AutoArrayHashMap(u32, void).init(self.allocator), | 579 | .references = std.AutoArrayHashMap(u32, void).init(self.allocator), |
| 590 | .code = try self.allocator.dupe(u8, code), | 580 | .code = try self.allocator.dupe(u8, code), |
| 591 | .relocs = std.ArrayList(Relocation).init(self.allocator), | 581 | .relocs = std.ArrayList(Relocation).init(self.allocator), |
| 582 | .rebases = std.ArrayList(u64).init(self.allocator), | ||
| 583 | .tlv_offsets = std.ArrayList(u64).init(self.allocator), | ||
| 592 | .size = sect.size, | 584 | .size = sect.size, |
| 593 | .alignment = sect.@"align", | 585 | .alignment = sect.@"align", |
| 594 | }; | 586 | }; |
| ... | @@ -597,18 +589,6 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void { | ... | @@ -597,18 +589,6 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void { |
| 597 | try self.parseRelocs(zld, relocs, block, 0); | 589 | try self.parseRelocs(zld, relocs, block, 0); |
| 598 | } | 590 | } |
| 599 | 591 | ||
| 600 | const is_zerofill = blk: { | ||
| 601 | const tseg = zld.load_commands.items[match.seg].Segment; | ||
| 602 | const tsect = tseg.sections.items[match.sect]; | ||
| 603 | const tsect_type = sectionType(tsect); | ||
| 604 | break :blk tsect_type == macho.S_ZEROFILL or | ||
| 605 | tsect_type == macho.S_THREAD_LOCAL_ZEROFILL or | ||
| 606 | tsect_type == macho.S_THREAD_LOCAL_VARIABLES; | ||
| 607 | }; | ||
| 608 | if (is_zerofill) { | ||
| 609 | mem.set(u8, block.code, 0); | ||
| 610 | } | ||
| 611 | |||
| 612 | if (zld.blocks.getPtr(match)) |last| { | 592 | if (zld.blocks.getPtr(match)) |last| { |
| 613 | last.*.next = block; | 593 | last.*.next = block; |
| 614 | block.prev = last.*; | 594 | block.prev = last.*; |
src/link/MachO/Symbol.zig-5| ... | @@ -58,8 +58,6 @@ pub const Regular = struct { | ... | @@ -58,8 +58,6 @@ pub const Regular = struct { |
| 58 | 58 | ||
| 59 | local_sym_index: u32 = 0, | 59 | local_sym_index: u32 = 0, |
| 60 | 60 | ||
| 61 | should_rebase: bool = false, | ||
| 62 | |||
| 63 | pub const Linkage = enum { | 61 | pub const Linkage = enum { |
| 64 | translation_unit, | 62 | translation_unit, |
| 65 | linkage_unit, | 63 | linkage_unit, |
| ... | @@ -77,9 +75,6 @@ pub const Regular = struct { | ... | @@ -77,9 +75,6 @@ pub const Regular = struct { |
| 77 | if (self.weak_ref) { | 75 | if (self.weak_ref) { |
| 78 | try std.fmt.format(writer, ".weak_ref, ", .{}); | 76 | try std.fmt.format(writer, ".weak_ref, ", .{}); |
| 79 | } | 77 | } |
| 80 | if (self.should_rebase) { | ||
| 81 | try std.fmt.format(writer, ".should_rebase, ", .{}); | ||
| 82 | } | ||
| 83 | if (self.file) |file| { | 78 | if (self.file) |file| { |
| 84 | try std.fmt.format(writer, ".file = {s}, ", .{file.name.?}); | 79 | try std.fmt.format(writer, ".file = {s}, ", .{file.name.?}); |
| 85 | } | 80 | } |
src/link/MachO/Zld.zig+20-9| ... | @@ -128,6 +128,8 @@ pub const TextBlock = struct { | ... | @@ -128,6 +128,8 @@ pub const TextBlock = struct { |
| 128 | relocs: std.ArrayList(Relocation), | 128 | relocs: std.ArrayList(Relocation), |
| 129 | size: u64, | 129 | size: u64, |
| 130 | alignment: u32, | 130 | alignment: u32, |
| 131 | rebases: std.ArrayList(u64), | ||
| 132 | tlv_offsets: std.ArrayList(u64), | ||
| 131 | next: ?*TextBlock = null, | 133 | next: ?*TextBlock = null, |
| 132 | prev: ?*TextBlock = null, | 134 | prev: ?*TextBlock = null, |
| 133 | 135 | ||
| ... | @@ -137,6 +139,8 @@ pub const TextBlock = struct { | ... | @@ -137,6 +139,8 @@ pub const TextBlock = struct { |
| 137 | } | 139 | } |
| 138 | block.relocs.deinit(); | 140 | block.relocs.deinit(); |
| 139 | block.references.deinit(); | 141 | block.references.deinit(); |
| 142 | block.rebases.deinit(); | ||
| 143 | block.tlv_offsets.deinit(); | ||
| 140 | allocator.free(block.code); | 144 | allocator.free(block.code); |
| 141 | } | 145 | } |
| 142 | 146 | ||
| ... | @@ -144,24 +148,30 @@ pub const TextBlock = struct { | ... | @@ -144,24 +148,30 @@ pub const TextBlock = struct { |
| 144 | log.warn("TextBlock", .{}); | 148 | log.warn("TextBlock", .{}); |
| 145 | log.warn(" | {}: {}", .{ self.local_sym_index, zld.locals.items[self.local_sym_index] }); | 149 | log.warn(" | {}: {}", .{ self.local_sym_index, zld.locals.items[self.local_sym_index] }); |
| 146 | if (self.aliases) |aliases| { | 150 | if (self.aliases) |aliases| { |
| 147 | log.warn(" | Aliases:", .{}); | 151 | log.warn(" | aliases:", .{}); |
| 148 | for (aliases) |index| { | 152 | for (aliases) |index| { |
| 149 | log.warn(" | {}: {}", .{ index, zld.locals.items[index] }); | 153 | log.warn(" | {}: {}", .{ index, zld.locals.items[index] }); |
| 150 | } | 154 | } |
| 151 | } | 155 | } |
| 152 | if (self.references.count() > 0) { | 156 | if (self.references.count() > 0) { |
| 153 | log.warn(" | References:", .{}); | 157 | log.warn(" | references:", .{}); |
| 154 | for (self.references.keys()) |index| { | 158 | for (self.references.keys()) |index| { |
| 155 | log.warn(" | {}: {}", .{ index, zld.locals.items[index] }); | 159 | log.warn(" | {}: {}", .{ index, zld.locals.items[index] }); |
| 156 | } | 160 | } |
| 157 | } | 161 | } |
| 158 | log.warn(" | code.len = {}", .{self.code.len}); | 162 | log.warn(" | code.len = {}", .{self.code.len}); |
| 159 | if (self.relocs.items.len > 0) { | 163 | if (self.relocs.items.len > 0) { |
| 160 | log.warn("Relocations:", .{}); | 164 | log.warn(" | relocations:", .{}); |
| 161 | for (self.relocs.items) |rel| { | 165 | for (self.relocs.items) |rel| { |
| 162 | log.warn(" | {}", .{rel}); | 166 | log.warn(" | {}", .{rel}); |
| 163 | } | 167 | } |
| 164 | } | 168 | } |
| 169 | if (self.rebases.items.len > 0) { | ||
| 170 | log.warn(" | rebases: {any}", .{self.rebases.items}); | ||
| 171 | } | ||
| 172 | if (self.tlv_offsets.items.len > 0) { | ||
| 173 | log.warn(" | TLV offsets: {any}", .{self.tlv_offsets.items}); | ||
| 174 | } | ||
| 165 | log.warn(" | size = {}", .{self.size}); | 175 | log.warn(" | size = {}", .{self.size}); |
| 166 | log.warn(" | align = {}", .{self.alignment}); | 176 | log.warn(" | align = {}", .{self.alignment}); |
| 167 | } | 177 | } |
| ... | @@ -271,6 +281,10 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg | ... | @@ -271,6 +281,10 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg |
| 271 | try self.addRpaths(args.rpaths); | 281 | try self.addRpaths(args.rpaths); |
| 272 | try self.addDataInCodeLC(); | 282 | try self.addDataInCodeLC(); |
| 273 | try self.addCodeSignatureLC(); | 283 | try self.addCodeSignatureLC(); |
| 284 | // try self.allocateTextSegment(); | ||
| 285 | // try self.allocateDataConstSegment(); | ||
| 286 | // try self.allocateDataSegment(); | ||
| 287 | // self.allocateLinkeditSegment(); | ||
| 274 | 288 | ||
| 275 | var it = self.blocks.iterator(); | 289 | var it = self.blocks.iterator(); |
| 276 | while (it.next()) |entry| { | 290 | while (it.next()) |entry| { |
| ... | @@ -281,11 +295,6 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg | ... | @@ -281,11 +295,6 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg |
| 281 | entry.value_ptr.*.print(self); | 295 | entry.value_ptr.*.print(self); |
| 282 | } | 296 | } |
| 283 | return error.TODO; | 297 | return error.TODO; |
| 284 | // try self.allocateTextSegment(); | ||
| 285 | // try self.allocateDataConstSegment(); | ||
| 286 | // try self.allocateDataSegment(); | ||
| 287 | // self.allocateLinkeditSegment(); | ||
| 288 | // try self.allocateSymbols(); | ||
| 289 | // try self.flush(); | 298 | // try self.flush(); |
| 290 | } | 299 | } |
| 291 | 300 | ||
| ... | @@ -1477,6 +1486,8 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1477,6 +1486,8 @@ fn resolveSymbols(self: *Zld) !void { |
| 1477 | .references = std.AutoArrayHashMap(u32, void).init(self.allocator), | 1486 | .references = std.AutoArrayHashMap(u32, void).init(self.allocator), |
| 1478 | .code = code, | 1487 | .code = code, |
| 1479 | .relocs = std.ArrayList(Relocation).init(self.allocator), | 1488 | .relocs = std.ArrayList(Relocation).init(self.allocator), |
| 1489 | .rebases = std.ArrayList(u64).init(self.allocator), | ||
| 1490 | .tlv_offsets = std.ArrayList(u64).init(self.allocator), | ||
| 1480 | .size = size, | 1491 | .size = size, |
| 1481 | .alignment = alignment, | 1492 | .alignment = alignment, |
| 1482 | }; | 1493 | }; |
src/link/MachO/reloc.zig+12-2| ... | @@ -405,7 +405,7 @@ pub const Relocation = struct { | ... | @@ -405,7 +405,7 @@ pub const Relocation = struct { |
| 405 | pub fn resolve(self: Relocation, zld: *Zld) !void { | 405 | pub fn resolve(self: Relocation, zld: *Zld) !void { |
| 406 | const source_addr = blk: { | 406 | const source_addr = blk: { |
| 407 | const sym = zld.locals.items[self.block.local_sym_index]; | 407 | const sym = zld.locals.items[self.block.local_sym_index]; |
| 408 | break :blk sym.payload.regular.address; | 408 | break :blk sym.payload.regular.address + self.offset; |
| 409 | }; | 409 | }; |
| 410 | const target_addr = blk: { | 410 | const target_addr = blk: { |
| 411 | const is_via_got = inner: { | 411 | const is_via_got = inner: { |
| ... | @@ -668,7 +668,17 @@ pub const Parser = struct { | ... | @@ -668,7 +668,17 @@ pub const Parser = struct { |
| 668 | 668 | ||
| 669 | break :rebase true; | 669 | break :rebase true; |
| 670 | }; | 670 | }; |
| 671 | source_reg.should_rebase = should_rebase; | 671 | |
| 672 | if (should_rebase) { | ||
| 673 | try self.block.rebases.append(out_rel.offset); | ||
| 674 | } | ||
| 675 | |||
| 676 | // TLV is handled via a separate offset mechanism. | ||
| 677 | // Save the offset to the initializer. | ||
| 678 | // TODO I believe this can be simplified a lot! | ||
| 679 | if (sect_type == macho.S_THREAD_LOCAL_VARIABLES) { | ||
| 680 | try self.block.tlv_offsets.append(out_rel.offset); | ||
| 681 | } | ||
| 672 | }, | 682 | }, |
| 673 | } | 683 | } |
| 674 | } else if (out_rel.payload == .branch) blk: { | 684 | } else if (out_rel.payload == .branch) blk: { |