| ... | @@ -58,6 +58,7 @@ stubs_section_index: ?u16 = null, | ... | @@ -58,6 +58,7 @@ stubs_section_index: ?u16 = null, |
| 58 | stub_helper_section_index: ?u16 = null, | 58 | stub_helper_section_index: ?u16 = null, |
| 59 | text_const_section_index: ?u16 = null, | 59 | text_const_section_index: ?u16 = null, |
| 60 | cstring_section_index: ?u16 = null, | 60 | cstring_section_index: ?u16 = null, |
| | 61 | ustring_section_index: ?u16 = null, |
| 61 | | 62 | |
| 62 | // __DATA_CONST segment sections | 63 | // __DATA_CONST segment sections |
| 63 | got_section_index: ?u16 = null, | 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,7 +201,6 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { |
| 200 | try self.populateMetadata(); | 201 | try self.populateMetadata(); |
| 201 | try self.parseInputFiles(files); | 202 | try self.parseInputFiles(files); |
| 202 | try self.resolveSymbols(); | 203 | try self.resolveSymbols(); |
| 203 | // self.printSymbols(); | | |
| 204 | try self.resolveStubsAndGotEntries(); | 204 | try self.resolveStubsAndGotEntries(); |
| 205 | try self.updateMetadata(); | 205 | try self.updateMetadata(); |
| 206 | try self.sortSections(); | 206 | try self.sortSections(); |
| ... | @@ -209,8 +209,6 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { | ... | @@ -209,8 +209,6 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { |
| 209 | try self.allocateDataSegment(); | 209 | try self.allocateDataSegment(); |
| 210 | self.allocateLinkeditSegment(); | 210 | self.allocateLinkeditSegment(); |
| 211 | try self.allocateSymbols(); | 211 | try self.allocateSymbols(); |
| 212 | try self.writeStubHelperCommon(); | | |
| 213 | try self.resolveRelocsAndWriteSections(); | | |
| 214 | try self.flush(); | 212 | try self.flush(); |
| 215 | } | 213 | } |
| 216 | | 214 | |
| ... | @@ -356,23 +354,43 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -356,23 +354,43 @@ fn updateMetadata(self: *Zld) !void { |
| 356 | switch (flags) { | 354 | switch (flags) { |
| 357 | macho.S_REGULAR, macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { | 355 | macho.S_REGULAR, macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { |
| 358 | if (mem.eql(u8, segname, "__TEXT")) { | 356 | if (mem.eql(u8, segname, "__TEXT")) { |
| 359 | if (self.text_const_section_index != null) continue; | 357 | if (mem.eql(u8, sectname, "__ustring")) { |
| 360 | | 358 | if (self.ustring_section_index != null) continue; |
| 361 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); | 359 | |
| 362 | try text_seg.addSection(self.allocator, .{ | 360 | self.ustring_section_index = @intCast(u16, text_seg.sections.items.len); |
| 363 | .sectname = makeStaticString("__const"), | 361 | try text_seg.addSection(self.allocator, .{ |
| 364 | .segname = makeStaticString("__TEXT"), | 362 | .sectname = makeStaticString("__ustring"), |
| 365 | .addr = 0, | 363 | .segname = makeStaticString("__TEXT"), |
| 366 | .size = 0, | 364 | .addr = 0, |
| 367 | .offset = 0, | 365 | .size = 0, |
| 368 | .@"align" = 0, | 366 | .offset = 0, |
| 369 | .reloff = 0, | 367 | .@"align" = 0, |
| 370 | .nreloc = 0, | 368 | .reloff = 0, |
| 371 | .flags = macho.S_REGULAR, | 369 | .nreloc = 0, |
| 372 | .reserved1 = 0, | 370 | .flags = macho.S_REGULAR, |
| 373 | .reserved2 = 0, | 371 | .reserved1 = 0, |
| 374 | .reserved3 = 0, | 372 | .reserved2 = 0, |
| 375 | }); | 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 | } else if (mem.eql(u8, segname, "__DATA")) { | 394 | } else if (mem.eql(u8, segname, "__DATA")) { |
| 377 | if (!mem.eql(u8, sectname, "__const")) continue; | 395 | if (!mem.eql(u8, sectname, "__const")) continue; |
| 378 | if (self.data_const_section_index != null) continue; | 396 | if (self.data_const_section_index != null) continue; |
| ... | @@ -588,6 +606,50 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -588,6 +606,50 @@ fn updateMetadata(self: *Zld) !void { |
| 588 | }, 0); | 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 | const MatchingSection = struct { | 655 | const MatchingSection = struct { |
| ... | @@ -663,10 +725,17 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { | ... | @@ -663,10 +725,17 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { |
| 663 | }, | 725 | }, |
| 664 | macho.S_REGULAR => { | 726 | macho.S_REGULAR => { |
| 665 | if (mem.eql(u8, segname, "__TEXT")) { | 727 | if (mem.eql(u8, segname, "__TEXT")) { |
| 666 | break :blk .{ | 728 | if (mem.eql(u8, sectname, "__ustring")) { |
| 667 | .seg = self.text_segment_cmd_index.?, | 729 | break :blk .{ |
| 668 | .sect = self.text_const_section_index.?, | 730 | .seg = self.text_segment_cmd_index.?, |
| 669 | }; | 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 | } else if (mem.eql(u8, segname, "__DATA")) { | 739 | } else if (mem.eql(u8, segname, "__DATA")) { |
| 671 | if (mem.eql(u8, sectname, "__data")) { | 740 | if (mem.eql(u8, sectname, "__data")) { |
| 672 | break :blk .{ | 741 | break :blk .{ |
| ... | @@ -712,6 +781,7 @@ fn sortSections(self: *Zld) !void { | ... | @@ -712,6 +781,7 @@ fn sortSections(self: *Zld) !void { |
| 712 | &self.stub_helper_section_index, | 781 | &self.stub_helper_section_index, |
| 713 | &self.text_const_section_index, | 782 | &self.text_const_section_index, |
| 714 | &self.cstring_section_index, | 783 | &self.cstring_section_index, |
| | 784 | &self.ustring_section_index, |
| 715 | }; | 785 | }; |
| 716 | for (indices) |maybe_index| { | 786 | for (indices) |maybe_index| { |
| 717 | const new_index: u16 = if (maybe_index.*) |index| blk: { | 787 | const new_index: u16 = if (maybe_index.*) |index| blk: { |
| ... | @@ -1991,6 +2061,9 @@ fn populateMetadata(self: *Zld) !void { | ... | @@ -1991,6 +2061,9 @@ fn populateMetadata(self: *Zld) !void { |
| 1991 | } | 2061 | } |
| 1992 | | 2062 | |
| 1993 | fn flush(self: *Zld) !void { | 2063 | fn flush(self: *Zld) !void { |
| | 2064 | try self.writeStubHelperCommon(); |
| | 2065 | try self.resolveRelocsAndWriteSections(); |
| | 2066 | |
| 1994 | if (self.common_section_index) |index| { | 2067 | if (self.common_section_index) |index| { |
| 1995 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 2068 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1996 | const sect = &seg.sections.items[index]; | 2069 | const sect = &seg.sections.items[index]; |