authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-05-07 01:44:26+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-05-07 01:44:26+02:00
loga2dbe6589ee6f33bb796ea3fd88b0bda5915e58e
treecd0c6375fef25d698d029d11b2da13c0bc86ee7a
parenta2b8a9756f867b75e9e9dfd0ecea9de162ad5eb1

macho: share traditional codepaths with stage2+llvm backend


2 files changed, 13 insertions(+), 10 deletions(-)

ci/azure/macos_script+1-2
...@@ -58,8 +58,7 @@ make $JOBS install...@@ -58,8 +58,7 @@ make $JOBS install
58# Build stage2 standalone so that we can test stage2 against stage2 compiler-rt.58# Build stage2 standalone so that we can test stage2 against stage2 compiler-rt.
59release/bin/zig build -p stage2 -Denable-llvm59release/bin/zig build -p stage2 -Denable-llvm
6060
61# TODO: enable this61stage2/bin/zig build test-behavior
62#stage2/bin/zig build test-behavior
6362
64# TODO: upgrade these to test stage2 instead of stage163# TODO: upgrade these to test stage2 instead of stage1
65# TODO: upgrade these to test stage3 instead of stage264# TODO: upgrade these to test stage3 instead of stage2
src/link/MachO.zig+12-8
...@@ -392,8 +392,9 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {...@@ -392,8 +392,9 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
392 // Adhoc code signature is required when targeting aarch64-macos either directly or indirectly via the simulator392 // Adhoc code signature is required when targeting aarch64-macos either directly or indirectly via the simulator
393 // ABI such as aarch64-ios-simulator, etc.393 // ABI such as aarch64-ios-simulator, etc.
394 const requires_adhoc_codesig = cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator);394 const requires_adhoc_codesig = cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator);
395 const use_llvm = build_options.have_llvm and options.use_llvm;
395 const use_stage1 = build_options.is_stage1 and options.use_stage1;396 const use_stage1 = build_options.is_stage1 and options.use_stage1;
396 const needs_prealloc = !(use_stage1 or options.cache_mode == .whole);397 const needs_prealloc = !(use_stage1 or use_llvm or options.cache_mode == .whole);
397398
398 const self = try gpa.create(MachO);399 const self = try gpa.create(MachO);
399 errdefer gpa.destroy(self);400 errdefer gpa.destroy(self);
...@@ -410,7 +411,6 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {...@@ -410,7 +411,6 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
410 .needs_prealloc = needs_prealloc,411 .needs_prealloc = needs_prealloc,
411 };412 };
412413
413 const use_llvm = build_options.have_llvm and options.use_llvm;
414 if (use_llvm and !use_stage1) {414 if (use_llvm and !use_stage1) {
415 self.llvm_object = try LlvmObject.create(gpa, options);415 self.llvm_object = try LlvmObject.create(gpa, options);
416 }416 }
...@@ -571,7 +571,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -571,7 +571,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
571 if (mem.eql(u8, prev_digest, &digest)) {571 if (mem.eql(u8, prev_digest, &digest)) {
572 // Hot diggity dog! The output binary is already there.572 // Hot diggity dog! The output binary is already there.
573573
574 if (use_stage1) {574 const use_llvm = build_options.have_llvm and self.base.options.use_llvm;
575 if (use_llvm or use_stage1) {
575 log.debug("MachO Zld digest={s} match - skipping invocation", .{std.fmt.fmtSliceHexLower(&digest)});576 log.debug("MachO Zld digest={s} match - skipping invocation", .{std.fmt.fmtSliceHexLower(&digest)});
576 self.base.lock = man.toOwnedLock();577 self.base.lock = man.toOwnedLock();
577 return;578 return;
...@@ -1025,7 +1026,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -1025,7 +1026,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
1025 try self.createTentativeDefAtoms();1026 try self.createTentativeDefAtoms();
1026 try self.parseObjectsIntoAtoms();1027 try self.parseObjectsIntoAtoms();
10271028
1028 if (use_stage1) {1029 const use_llvm = build_options.have_llvm and self.base.options.use_llvm;
1030 if (use_llvm or use_stage1) {
1029 try self.sortSections();1031 try self.sortSections();
1030 try self.allocateTextSegment();1032 try self.allocateTextSegment();
1031 try self.allocateDataConstSegment();1033 try self.allocateDataConstSegment();
...@@ -1041,7 +1043,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -1041,7 +1043,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
1041 self.logSectionOrdinals();1043 self.logSectionOrdinals();
1042 }1044 }
10431045
1044 if (use_stage1) {1046 if (use_llvm or use_stage1) {
1045 try self.writeAllAtoms();1047 try self.writeAllAtoms();
1046 } else {1048 } else {
1047 try self.writeAtoms();1049 try self.writeAtoms();
...@@ -4930,12 +4932,13 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {...@@ -4930,12 +4932,13 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
4930 var start: u64 = offset;4932 var start: u64 = offset;
4931 for (seg.sections.items) |*sect, sect_id| {4933 for (seg.sections.items) |*sect, sect_id| {
4932 const is_zerofill = sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL;4934 const is_zerofill = sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL;
4935 const use_llvm = build_options.have_llvm and self.base.options.use_llvm;
4933 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;4936 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
4934 const alignment = try math.powi(u32, 2, sect.@"align");4937 const alignment = try math.powi(u32, 2, sect.@"align");
4935 const start_aligned = mem.alignForwardGeneric(u64, start, alignment);4938 const start_aligned = mem.alignForwardGeneric(u64, start, alignment);
49364939
4937 // TODO handle zerofill sections in stage24940 // TODO handle zerofill sections in stage2
4938 sect.offset = if (is_zerofill and use_stage1) 0 else @intCast(u32, seg.inner.fileoff + start_aligned);4941 sect.offset = if (is_zerofill and (use_stage1 or use_llvm)) 0 else @intCast(u32, seg.inner.fileoff + start_aligned);
4939 sect.addr = seg.inner.vmaddr + start_aligned;4942 sect.addr = seg.inner.vmaddr + start_aligned;
49404943
4941 // Recalculate section size given the allocated start address4944 // Recalculate section size given the allocated start address
...@@ -4963,7 +4966,7 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {...@@ -4963,7 +4966,7 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
49634966
4964 start = start_aligned + sect.size;4967 start = start_aligned + sect.size;
49654968
4966 if (!(is_zerofill and use_stage1)) {4969 if (!(is_zerofill and (use_stage1 or use_llvm))) {
4967 seg.inner.filesize = start;4970 seg.inner.filesize = start;
4968 }4971 }
4969 seg.inner.vmsize = start;4972 seg.inner.vmsize = start;
...@@ -5012,10 +5015,11 @@ fn initSection(...@@ -5012,10 +5015,11 @@ fn initSection(
5012 sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff;5015 sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff;
50135016
5014 const is_zerofill = opts.flags == macho.S_ZEROFILL or opts.flags == macho.S_THREAD_LOCAL_ZEROFILL;5017 const is_zerofill = opts.flags == macho.S_ZEROFILL or opts.flags == macho.S_THREAD_LOCAL_ZEROFILL;
5018 const use_llvm = build_options.have_llvm and self.base.options.use_llvm;
5015 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;5019 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
50165020
5017 // TODO handle zerofill in stage25021 // TODO handle zerofill in stage2
5018 if (!(is_zerofill and use_stage1)) {5022 if (!(is_zerofill and (use_stage1 or use_llvm))) {
5019 sect.offset = @intCast(u32, off);5023 sect.offset = @intCast(u32, off);
5020 }5024 }
5021 }5025 }