| ... | ... | @@ -58,6 +58,7 @@ stubs_section_index: ?u16 = null, |
| 58 | 58 | stub_helper_section_index: ?u16 = null, |
| 59 | 59 | text_const_section_index: ?u16 = null, |
| 60 | 60 | cstring_section_index: ?u16 = null, |
| 61 | ustring_section_index: ?u16 = null, |
| 61 | 62 | |
| 62 | 63 | // __DATA_CONST segment sections |
| 63 | 64 | got_section_index: ?u16 = null, |
| ... | ... | @@ -200,7 +201,6 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { |
| 200 | 201 | try self.populateMetadata(); |
| 201 | 202 | try self.parseInputFiles(files); |
| 202 | 203 | try self.resolveSymbols(); |
| 203 | | // self.printSymbols(); |
| 204 | 204 | try self.resolveStubsAndGotEntries(); |
| 205 | 205 | try self.updateMetadata(); |
| 206 | 206 | try self.sortSections(); |
| ... | ... | @@ -209,8 +209,6 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { |
| 209 | 209 | try self.allocateDataSegment(); |
| 210 | 210 | self.allocateLinkeditSegment(); |
| 211 | 211 | try self.allocateSymbols(); |
| 212 | | try self.writeStubHelperCommon(); |
| 213 | | try self.resolveRelocsAndWriteSections(); |
| 214 | 212 | try self.flush(); |
| 215 | 213 | } |
| 216 | 214 | |
| ... | ... | @@ -356,23 +354,43 @@ fn updateMetadata(self: *Zld) !void { |
| 356 | 354 | switch (flags) { |
| 357 | 355 | macho.S_REGULAR, macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { |
| 358 | 356 | if (mem.eql(u8, segname, "__TEXT")) { |
| 359 | | if (self.text_const_section_index != null) continue; |
| 360 | | |
| 361 | | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); |
| 362 | | try text_seg.addSection(self.allocator, .{ |
| 363 | | .sectname = makeStaticString("__const"), |
| 364 | | .segname = makeStaticString("__TEXT"), |
| 365 | | .addr = 0, |
| 366 | | .size = 0, |
| 367 | | .offset = 0, |
| 368 | | .@"align" = 0, |
| 369 | | .reloff = 0, |
| 370 | | .nreloc = 0, |
| 371 | | .flags = macho.S_REGULAR, |
| 372 | | .reserved1 = 0, |
| 373 | | .reserved2 = 0, |
| 374 | | .reserved3 = 0, |
| 375 | | }); |
| 357 | if (mem.eql(u8, sectname, "__ustring")) { |
| 358 | if (self.ustring_section_index != null) continue; |
| 359 | |
| 360 | self.ustring_section_index = @intCast(u16, text_seg.sections.items.len); |
| 361 | try text_seg.addSection(self.allocator, .{ |
| 362 | .sectname = makeStaticString("__ustring"), |
| 363 | .segname = makeStaticString("__TEXT"), |
| 364 | .addr = 0, |
| 365 | .size = 0, |
| 366 | .offset = 0, |
| 367 | .@"align" = 0, |
| 368 | .reloff = 0, |
| 369 | .nreloc = 0, |
| 370 | .flags = macho.S_REGULAR, |
| 371 | .reserved1 = 0, |
| 372 | .reserved2 = 0, |
| 373 | .reserved3 = 0, |
| 374 | }); |
| 375 | } else { |
| 376 | if (self.text_const_section_index != null) continue; |
| 377 | |
| 378 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); |
| 379 | try text_seg.addSection(self.allocator, .{ |
| 380 | .sectname = makeStaticString("__const"), |
| 381 | .segname = makeStaticString("__TEXT"), |
| 382 | .addr = 0, |
| 383 | .size = 0, |
| 384 | .offset = 0, |
| 385 | .@"align" = 0, |
| 386 | .reloff = 0, |
| 387 | .nreloc = 0, |
| 388 | .flags = macho.S_REGULAR, |
| 389 | .reserved1 = 0, |
| 390 | .reserved2 = 0, |
| 391 | .reserved3 = 0, |
| 392 | }); |
| 393 | } |
| 376 | 394 | } else if (mem.eql(u8, segname, "__DATA")) { |
| 377 | 395 | if (!mem.eql(u8, sectname, "__const")) continue; |
| 378 | 396 | if (self.data_const_section_index != null) continue; |
| ... | ... | @@ -588,6 +606,50 @@ fn updateMetadata(self: *Zld) !void { |
| 588 | 606 | }, 0); |
| 589 | 607 | } |
| 590 | 608 | } |
| 609 | |
| 610 | tlv_align: { |
| 611 | const has_tlv = |
| 612 | self.tlv_section_index != null or |
| 613 | self.tlv_data_section_index != null or |
| 614 | self.tlv_bss_section_index != null; |
| 615 | |
| 616 | if (!has_tlv) break :tlv_align; |
| 617 | |
| 618 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 619 | |
| 620 | if (self.tlv_section_index) |index| { |
| 621 | const sect = &seg.sections.items[index]; |
| 622 | sect.@"align" = 3; // __thread_vars is always 8byte aligned |
| 623 | } |
| 624 | |
| 625 | // Apparently __tlv_data and __tlv_bss need to have matching alignment, so fix it up. |
| 626 | // <rdar://problem/24221680> All __thread_data and __thread_bss sections must have same alignment |
| 627 | // https://github.com/apple-opensource/ld64/blob/e28c028b20af187a16a7161d89e91868a450cadc/src/ld/ld.cpp#L1172 |
| 628 | const data_align: u32 = data: { |
| 629 | if (self.tlv_data_section_index) |index| { |
| 630 | const sect = &seg.sections.items[index]; |
| 631 | break :data sect.@"align"; |
| 632 | } |
| 633 | break :tlv_align; |
| 634 | }; |
| 635 | const bss_align: u32 = bss: { |
| 636 | if (self.tlv_bss_section_index) |index| { |
| 637 | const sect = &seg.sections.items[index]; |
| 638 | break :bss sect.@"align"; |
| 639 | } |
| 640 | break :tlv_align; |
| 641 | }; |
| 642 | const max_align = math.max(data_align, bss_align); |
| 643 | |
| 644 | if (self.tlv_data_section_index) |index| { |
| 645 | const sect = &seg.sections.items[index]; |
| 646 | sect.@"align" = max_align; |
| 647 | } |
| 648 | if (self.tlv_bss_section_index) |index| { |
| 649 | const sect = &seg.sections.items[index]; |
| 650 | sect.@"align" = max_align; |
| 651 | } |
| 652 | } |
| 591 | 653 | } |
| 592 | 654 | |
| 593 | 655 | const MatchingSection = struct { |
| ... | ... | @@ -663,10 +725,17 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { |
| 663 | 725 | }, |
| 664 | 726 | macho.S_REGULAR => { |
| 665 | 727 | if (mem.eql(u8, segname, "__TEXT")) { |
| 666 | | break :blk .{ |
| 667 | | .seg = self.text_segment_cmd_index.?, |
| 668 | | .sect = self.text_const_section_index.?, |
| 669 | | }; |
| 728 | if (mem.eql(u8, sectname, "__ustring")) { |
| 729 | break :blk .{ |
| 730 | .seg = self.text_segment_cmd_index.?, |
| 731 | .sect = self.ustring_section_index.?, |
| 732 | }; |
| 733 | } else { |
| 734 | break :blk .{ |
| 735 | .seg = self.text_segment_cmd_index.?, |
| 736 | .sect = self.text_const_section_index.?, |
| 737 | }; |
| 738 | } |
| 670 | 739 | } else if (mem.eql(u8, segname, "__DATA")) { |
| 671 | 740 | if (mem.eql(u8, sectname, "__data")) { |
| 672 | 741 | break :blk .{ |
| ... | ... | @@ -712,6 +781,7 @@ fn sortSections(self: *Zld) !void { |
| 712 | 781 | &self.stub_helper_section_index, |
| 713 | 782 | &self.text_const_section_index, |
| 714 | 783 | &self.cstring_section_index, |
| 784 | &self.ustring_section_index, |
| 715 | 785 | }; |
| 716 | 786 | for (indices) |maybe_index| { |
| 717 | 787 | const new_index: u16 = if (maybe_index.*) |index| blk: { |
| ... | ... | @@ -1991,6 +2061,9 @@ fn populateMetadata(self: *Zld) !void { |
| 1991 | 2061 | } |
| 1992 | 2062 | |
| 1993 | 2063 | fn flush(self: *Zld) !void { |
| 2064 | try self.writeStubHelperCommon(); |
| 2065 | try self.resolveRelocsAndWriteSections(); |
| 2066 | |
| 1994 | 2067 | if (self.common_section_index) |index| { |
| 1995 | 2068 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1996 | 2069 | const sect = &seg.sections.items[index]; |