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,
5858stub_helper_section_index: ?u16 = null,
5959text_const_section_index: ?u16 = null,
6060cstring_section_index: ?u16 = null,
61ustring_section_index: ?u16 = null,
6162
6263// __DATA_CONST segment sections
6364got_section_index: ?u16 = null,
......@@ -200,7 +201,6 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void {
200201 try self.populateMetadata();
201202 try self.parseInputFiles(files);
202203 try self.resolveSymbols();
203 // self.printSymbols();
204204 try self.resolveStubsAndGotEntries();
205205 try self.updateMetadata();
206206 try self.sortSections();
......@@ -209,8 +209,6 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void {
209209 try self.allocateDataSegment();
210210 self.allocateLinkeditSegment();
211211 try self.allocateSymbols();
212 try self.writeStubHelperCommon();
213 try self.resolveRelocsAndWriteSections();
214212 try self.flush();
215213}
216214
......@@ -356,23 +354,43 @@ fn updateMetadata(self: *Zld) !void {
356354 switch (flags) {
357355 macho.S_REGULAR, macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => {
358356 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 }
376394 } else if (mem.eql(u8, segname, "__DATA")) {
377395 if (!mem.eql(u8, sectname, "__const")) continue;
378396 if (self.data_const_section_index != null) continue;
......@@ -588,6 +606,50 @@ fn updateMetadata(self: *Zld) !void {
588606 }, 0);
589607 }
590608 }
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 }
591653}
592654
593655const MatchingSection = struct {
......@@ -663,10 +725,17 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection {
663725 },
664726 macho.S_REGULAR => {
665727 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 }
670739 } else if (mem.eql(u8, segname, "__DATA")) {
671740 if (mem.eql(u8, sectname, "__data")) {
672741 break :blk .{
......@@ -712,6 +781,7 @@ fn sortSections(self: *Zld) !void {
712781 &self.stub_helper_section_index,
713782 &self.text_const_section_index,
714783 &self.cstring_section_index,
784 &self.ustring_section_index,
715785 };
716786 for (indices) |maybe_index| {
717787 const new_index: u16 = if (maybe_index.*) |index| blk: {
......@@ -1991,6 +2061,9 @@ fn populateMetadata(self: *Zld) !void {
19912061}
19922062
19932063fn flush(self: *Zld) !void {
2064 try self.writeStubHelperCommon();
2065 try self.resolveRelocsAndWriteSections();
2066
19942067 if (self.common_section_index) |index| {
19952068 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
19962069 const sect = &seg.sections.items[index];