authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-14 00:23:11+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:40+01:00
log1e0eb3c8097a3bd45cd5e6c7b67f6f7d4f974c6f
tree92c2d03c7820e89a15e76dbbc351bcbdcc7bf038
parent2c0c86944ef202788ba7489fe14df12194b720d9

test/link/macho: test weak binding


1 files changed, 137 insertions(+), 0 deletions(-)

test/link/macho.zig+137
......@@ -7,6 +7,10 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
77 const default_target = b.resolveTargetQuery(.{
88 .os_tag = .macos,
99 });
10 const x86_64_target = b.resolveTargetQuery(.{
11 .cpu_arch = .x86_64,
12 .os_tag = .macos,
13 });
1014
1115 macho_step.dependOn(testDeadStrip(b, .{ .target = default_target }));
1216 macho_step.dependOn(testEntryPointDylib(b, .{ .target = default_target }));
......@@ -17,6 +21,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
1721 macho_step.dependOn(testMhExecuteHeader(b, .{ .target = default_target }));
1822 macho_step.dependOn(testSectionBoundarySymbols(b, .{ .target = default_target }));
1923 macho_step.dependOn(testSegmentBoundarySymbols(b, .{ .target = default_target }));
24 macho_step.dependOn(testWeakBind(b, .{ .target = x86_64_target }));
2025
2126 // Tests requiring symlinks when tested on Windows
2227 if (build_opts.has_symlinks_windows) {
......@@ -629,6 +634,138 @@ fn testSegmentBoundarySymbols(b: *Build, opts: Options) *Step {
629634 return test_step;
630635}
631636
637// Adapted from https://github.com/llvm/llvm-project/blob/main/lld/test/MachO/weak-binding.s
638fn testWeakBind(b: *Build, opts: Options) *Step {
639 const test_step = addTestStep(b, "macho-weak-bind", opts);
640
641 const lib = addSharedLibrary(b, opts, .{ .name = "foo", .asm_source_bytes =
642 \\.globl _weak_dysym
643 \\.weak_definition _weak_dysym
644 \\_weak_dysym:
645 \\ .quad 0x1234
646 \\
647 \\.globl _weak_dysym_for_gotpcrel
648 \\.weak_definition _weak_dysym_for_gotpcrel
649 \\_weak_dysym_for_gotpcrel:
650 \\ .quad 0x1234
651 \\
652 \\.globl _weak_dysym_fn
653 \\.weak_definition _weak_dysym_fn
654 \\_weak_dysym_fn:
655 \\ ret
656 \\
657 \\.section __DATA,__thread_vars,thread_local_variables
658 \\
659 \\.globl _weak_dysym_tlv
660 \\.weak_definition _weak_dysym_tlv
661 \\_weak_dysym_tlv:
662 \\ .quad 0x1234
663 });
664
665 {
666 const check = lib.checkObject();
667 check.checkInExports();
668 check.checkExtract("[WEAK] {vmaddr1} _weak_dysym");
669 check.checkExtract("[WEAK] {vmaddr2} _weak_dysym_for_gotpcrel");
670 check.checkExtract("[WEAK] {vmaddr3} _weak_dysym_fn");
671 check.checkExtract("[THREAD_LOCAL, WEAK] {vmaddr4} _weak_dysym_tlv");
672 test_step.dependOn(&check.step);
673 }
674
675 const exe = addExecutable(b, opts, .{ .name = "main", .asm_source_bytes =
676 \\.globl _main, _weak_external, _weak_external_for_gotpcrel, _weak_external_fn
677 \\.weak_definition _weak_external, _weak_external_for_gotpcrel, _weak_external_fn, _weak_internal, _weak_internal_for_gotpcrel, _weak_internal_fn
678 \\
679 \\_main:
680 \\ mov _weak_dysym_for_gotpcrel@GOTPCREL(%rip), %rax
681 \\ mov _weak_external_for_gotpcrel@GOTPCREL(%rip), %rax
682 \\ mov _weak_internal_for_gotpcrel@GOTPCREL(%rip), %rax
683 \\ mov _weak_tlv@TLVP(%rip), %rax
684 \\ mov _weak_dysym_tlv@TLVP(%rip), %rax
685 \\ mov _weak_internal_tlv@TLVP(%rip), %rax
686 \\ callq _weak_dysym_fn
687 \\ callq _weak_external_fn
688 \\ callq _weak_internal_fn
689 \\ mov $0, %rax
690 \\ ret
691 \\
692 \\_weak_external:
693 \\ .quad 0x1234
694 \\
695 \\_weak_external_for_gotpcrel:
696 \\ .quad 0x1234
697 \\
698 \\_weak_external_fn:
699 \\ ret
700 \\
701 \\_weak_internal:
702 \\ .quad 0x1234
703 \\
704 \\_weak_internal_for_gotpcrel:
705 \\ .quad 0x1234
706 \\
707 \\_weak_internal_fn:
708 \\ ret
709 \\
710 \\.data
711 \\ .quad _weak_dysym
712 \\ .quad _weak_external + 2
713 \\ .quad _weak_internal
714 \\
715 \\.tbss _weak_tlv$tlv$init, 4, 2
716 \\.tbss _weak_internal_tlv$tlv$init, 4, 2
717 \\
718 \\.section __DATA,__thread_vars,thread_local_variables
719 \\.globl _weak_tlv
720 \\.weak_definition _weak_tlv, _weak_internal_tlv
721 \\
722 \\_weak_tlv:
723 \\ .quad __tlv_bootstrap
724 \\ .quad 0
725 \\ .quad _weak_tlv$tlv$init
726 \\
727 \\_weak_internal_tlv:
728 \\ .quad __tlv_bootstrap
729 \\ .quad 0
730 \\ .quad _weak_internal_tlv$tlv$init
731 });
732 exe.linkLibrary(lib);
733
734 {
735 const check = exe.checkObject();
736
737 check.checkInExports();
738 check.checkExtract("[WEAK] {vmaddr1} _weak_external");
739 check.checkExtract("[WEAK] {vmaddr2} _weak_external_for_gotpcrel");
740 check.checkExtract("[WEAK] {vmaddr3} _weak_external_fn");
741 check.checkExtract("[THREAD_LOCAL, WEAK] {vmaddr4} _weak_tlv");
742
743 check.checkInDyldBind();
744 check.checkContains("(libfoo.dylib) _weak_dysym_for_gotpcrel");
745 check.checkContains("(libfoo.dylib) _weak_dysym_fn");
746 check.checkContains("(libfoo.dylib) _weak_dysym");
747 check.checkContains("(libfoo.dylib) _weak_dysym_tlv");
748
749 check.checkInDyldWeakBind();
750 check.checkContains("_weak_external_for_gotpcrel");
751 check.checkContains("_weak_dysym_for_gotpcrel");
752 check.checkContains("_weak_external_fn");
753 check.checkContains("_weak_dysym_fn");
754 check.checkContains("_weak_dysym");
755 check.checkContains("_weak_external");
756 check.checkContains("_weak_tlv");
757 check.checkContains("_weak_dysym_tlv");
758
759 test_step.dependOn(&check.step);
760 }
761
762 const run = addRunArtifact(exe);
763 run.expectExitCode(0);
764 test_step.dependOn(&run.step);
765
766 return test_step;
767}
768
632769fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step {
633770 return link.addTestStep(b, "macho-" ++ prefix, opts);
634771}