| ... | ... | @@ -66,6 +66,13 @@ pub const Zld = struct { |
| 66 | 66 | segments: std.ArrayListUnmanaged(macho.segment_command_64) = .{}, |
| 67 | 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 | 76 | text_section_index: ?u8 = null, |
| 70 | 77 | got_section_index: ?u8 = null, |
| 71 | 78 | tlv_ptr_section_index: ?u8 = null, |
| ... | ... | @@ -550,6 +557,7 @@ pub const Zld = struct { |
| 550 | 557 | log.warn("requested __PAGEZERO size (0x{x}) is not page aligned", .{pagezero_vmsize}); |
| 551 | 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 | 561 | try self.segments.append(self.gpa, .{ |
| 554 | 562 | .cmdsize = @sizeOf(macho.segment_command_64), |
| 555 | 563 | .segname = makeStaticString("__PAGEZERO"), |
| ... | ... | @@ -560,6 +568,8 @@ pub const Zld = struct { |
| 560 | 568 | // __TEXT segment is non-optional |
| 561 | 569 | { |
| 562 | 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 | 573 | try self.segments.append(self.gpa, .{ |
| 564 | 574 | .cmdsize = @sizeOf(macho.segment_command_64), |
| 565 | 575 | .segname = makeStaticString("__TEXT"), |
| ... | ... | @@ -590,9 +600,18 @@ pub const Zld = struct { |
| 590 | 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 | 611 | // __LINKEDIT always comes last |
| 594 | 612 | { |
| 595 | 613 | const protection = MachO.getSegmentMemoryProtection("__LINKEDIT"); |
| 614 | self.linkedit_segment_cmd_index = @intCast(self.segments.items.len); |
| 596 | 615 | try self.segments.append(self.gpa, .{ |
| 597 | 616 | .cmdsize = @sizeOf(macho.segment_command_64), |
| 598 | 617 | .segname = makeStaticString("__LINKEDIT"), |
| ... | ... | @@ -1154,13 +1173,26 @@ pub const Zld = struct { |
| 1154 | 1173 | } |
| 1155 | 1174 | |
| 1156 | 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 | 1190 | try self.writeDyldInfoData(); |
| 1158 | 1191 | try self.writeFunctionStarts(); |
| 1159 | 1192 | try self.writeDataInCode(); |
| 1160 | 1193 | try self.writeSymtabs(); |
| 1161 | 1194 | |
| 1162 | | const seg = self.getLinkeditSegmentPtr(); |
| 1163 | | seg.vmsize = mem.alignForward(u64, seg.filesize, MachO.getPageSize(self.options.target.cpu.arch)); |
| 1195 | seg.vmsize = mem.alignForward(u64, seg.filesize, page_size); |
| 1164 | 1196 | } |
| 1165 | 1197 | |
| 1166 | 1198 | fn collectRebaseData(self: *Zld, rebase: *Rebase) !void { |