authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-05-04 10:59:33+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-05-04 13:09:32+02:00
log96556ce8b885c9c56e24f26a65b6234eb8b102be
tree186269a6655538ea5d6269bb7a843819540eb064
parent1867c3c34c10312a742041e6525aea8abe32f48d

zld: port over a few more bits from ld64

* UTF16 gets its own section, `__TEXT,__ustring` * TLV data and bss sections have to aligned to the same max alignment according to Apple rdar comment in the latest ld64

1 files changed, 97 insertions(+), 24 deletions(-)

src/link/MachO/Zld.zig+97-24
...@@ -58,6 +58,7 @@ stubs_section_index: ?u16 = null,...@@ -58,6 +58,7 @@ stubs_section_index: ?u16 = null,
58stub_helper_section_index: ?u16 = null,58stub_helper_section_index: ?u16 = null,
59text_const_section_index: ?u16 = null,59text_const_section_index: ?u16 = null,
60cstring_section_index: ?u16 = null,60cstring_section_index: ?u16 = null,
61ustring_section_index: ?u16 = null,
6162
62// __DATA_CONST segment sections63// __DATA_CONST segment sections
63got_section_index: ?u16 = null,64got_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}
216214
...@@ -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")) {
360358 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}
592654
593const MatchingSection = struct {655const 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}
19922062
1993fn flush(self: *Zld) !void {2063fn 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];