| ... | @@ -66,6 +66,13 @@ pub const Zld = struct { | ... | @@ -66,6 +66,13 @@ pub const Zld = struct { |
| 66 | segments: std.ArrayListUnmanaged(macho.segment_command_64) = .{}, | 66 | segments: std.ArrayListUnmanaged(macho.segment_command_64) = .{}, |
| 67 | sections: std.MultiArrayList(Section) = .{}, | 67 | sections: std.MultiArrayList(Section) = .{}, |
| 68 | | 68 | |
| | 69 | pagezero_segment_cmd_index: ?u8 = null, |
| | 70 | header_segment_cmd_index: ?u8 = null, |
| | 71 | text_segment_cmd_index: ?u8 = null, |
| | 72 | data_const_segment_cmd_index: ?u8 = null, |
| | 73 | data_segment_cmd_index: ?u8 = null, |
| | 74 | linkedit_segment_cmd_index: ?u8 = null, |
| | 75 | |
| 69 | text_section_index: ?u8 = null, | 76 | text_section_index: ?u8 = null, |
| 70 | got_section_index: ?u8 = null, | 77 | got_section_index: ?u8 = null, |
| 71 | tlv_ptr_section_index: ?u8 = null, | 78 | tlv_ptr_section_index: ?u8 = null, |
| ... | @@ -550,6 +557,7 @@ pub const Zld = struct { | ... | @@ -550,6 +557,7 @@ pub const Zld = struct { |
| 550 | log.warn("requested __PAGEZERO size (0x{x}) is not page aligned", .{pagezero_vmsize}); | 557 | log.warn("requested __PAGEZERO size (0x{x}) is not page aligned", .{pagezero_vmsize}); |
| 551 | log.warn(" rounding down to 0x{x}", .{aligned_pagezero_vmsize}); | 558 | log.warn(" rounding down to 0x{x}", .{aligned_pagezero_vmsize}); |
| 552 | } | 559 | } |
| | 560 | self.pagezero_segment_cmd_index = @intCast(self.segments.items.len); |
| 553 | try self.segments.append(self.gpa, .{ | 561 | try self.segments.append(self.gpa, .{ |
| 554 | .cmdsize = @sizeOf(macho.segment_command_64), | 562 | .cmdsize = @sizeOf(macho.segment_command_64), |
| 555 | .segname = makeStaticString("__PAGEZERO"), | 563 | .segname = makeStaticString("__PAGEZERO"), |
| ... | @@ -560,6 +568,8 @@ pub const Zld = struct { | ... | @@ -560,6 +568,8 @@ pub const Zld = struct { |
| 560 | // __TEXT segment is non-optional | 568 | // __TEXT segment is non-optional |
| 561 | { | 569 | { |
| 562 | const protection = MachO.getSegmentMemoryProtection("__TEXT"); | 570 | const protection = MachO.getSegmentMemoryProtection("__TEXT"); |
| | 571 | self.text_segment_cmd_index = @intCast(self.segments.items.len); |
| | 572 | self.header_segment_cmd_index = self.text_segment_cmd_index.?; |
| 563 | try self.segments.append(self.gpa, .{ | 573 | try self.segments.append(self.gpa, .{ |
| 564 | .cmdsize = @sizeOf(macho.segment_command_64), | 574 | .cmdsize = @sizeOf(macho.segment_command_64), |
| 565 | .segname = makeStaticString("__TEXT"), | 575 | .segname = makeStaticString("__TEXT"), |
| ... | @@ -590,9 +600,18 @@ pub const Zld = struct { | ... | @@ -590,9 +600,18 @@ pub const Zld = struct { |
| 590 | self.sections.items(.segment_index)[sect_id] = segment_id; | 600 | self.sections.items(.segment_index)[sect_id] = segment_id; |
| 591 | } | 601 | } |
| 592 | | 602 | |
| | 603 | if (self.getSegmentByName("__DATA_CONST")) |index| { |
| | 604 | self.data_const_segment_cmd_index = index; |
| | 605 | } |
| | 606 | |
| | 607 | if (self.getSegmentByName("__DATA")) |index| { |
| | 608 | self.data_segment_cmd_index = index; |
| | 609 | } |
| | 610 | |
| 593 | // __LINKEDIT always comes last | 611 | // __LINKEDIT always comes last |
| 594 | { | 612 | { |
| 595 | const protection = MachO.getSegmentMemoryProtection("__LINKEDIT"); | 613 | const protection = MachO.getSegmentMemoryProtection("__LINKEDIT"); |
| | 614 | self.linkedit_segment_cmd_index = @intCast(self.segments.items.len); |
| 596 | try self.segments.append(self.gpa, .{ | 615 | try self.segments.append(self.gpa, .{ |
| 597 | .cmdsize = @sizeOf(macho.segment_command_64), | 616 | .cmdsize = @sizeOf(macho.segment_command_64), |
| 598 | .segname = makeStaticString("__LINKEDIT"), | 617 | .segname = makeStaticString("__LINKEDIT"), |
| ... | @@ -1154,13 +1173,26 @@ pub const Zld = struct { | ... | @@ -1154,13 +1173,26 @@ pub const Zld = struct { |
| 1154 | } | 1173 | } |
| 1155 | | 1174 | |
| 1156 | fn writeLinkeditSegmentData(self: *Zld) !void { | 1175 | fn writeLinkeditSegmentData(self: *Zld) !void { |
| | 1176 | const page_size = MachO.getPageSize(self.options.target.cpu.arch); |
| | 1177 | const seg = self.getLinkeditSegmentPtr(); |
| | 1178 | seg.filesize = 0; |
| | 1179 | seg.vmsize = 0; |
| | 1180 | |
| | 1181 | for (self.segments.items, 0..) |segment, id| { |
| | 1182 | if (self.linkedit_segment_cmd_index.? == @as(u8, @intCast(id))) continue; |
| | 1183 | if (seg.vmaddr < segment.vmaddr + segment.vmsize) { |
| | 1184 | seg.vmaddr = mem.alignForward(u64, segment.vmaddr + segment.vmsize, page_size); |
| | 1185 | } |
| | 1186 | if (seg.fileoff < segment.fileoff + segment.filesize) { |
| | 1187 | seg.fileoff = mem.alignForward(u64, segment.fileoff + segment.filesize, page_size); |
| | 1188 | } |
| | 1189 | } |
| 1157 | try self.writeDyldInfoData(); | 1190 | try self.writeDyldInfoData(); |
| 1158 | try self.writeFunctionStarts(); | 1191 | try self.writeFunctionStarts(); |
| 1159 | try self.writeDataInCode(); | 1192 | try self.writeDataInCode(); |
| 1160 | try self.writeSymtabs(); | 1193 | try self.writeSymtabs(); |
| 1161 | | 1194 | |
| 1162 | const seg = self.getLinkeditSegmentPtr(); | 1195 | seg.vmsize = mem.alignForward(u64, seg.filesize, page_size); |
| 1163 | seg.vmsize = mem.alignForward(u64, seg.filesize, MachO.getPageSize(self.options.target.cpu.arch)); | | |
| 1164 | } | 1196 | } |
| 1165 | | 1197 | |
| 1166 | fn collectRebaseData(self: *Zld, rebase: *Rebase) !void { | 1198 | fn collectRebaseData(self: *Zld, rebase: *Rebase) !void { |