authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-15 11:16:03+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:40+01:00
log000598acc9cbd362e533afad9c48cffdd2fae380
treec30be7e9ab35e7f6e9979c779ef22540103e6abc
parent3d835dea2a5e61a6ecff6078207b808441ae937a

test/link/macho: test objc msgsend selector stubs


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

test/link/macho.zig+155
...@@ -53,6 +53,8 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {...@@ -53,6 +53,8 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
53 macho_step.dependOn(testHeaderpad(b, .{ .target = b.host }));53 macho_step.dependOn(testHeaderpad(b, .{ .target = b.host }));
54 macho_step.dependOn(testNeededFramework(b, .{ .target = b.host }));54 macho_step.dependOn(testNeededFramework(b, .{ .target = b.host }));
55 macho_step.dependOn(testObjc(b, .{ .target = b.host }));55 macho_step.dependOn(testObjc(b, .{ .target = b.host }));
56 macho_step.dependOn(testObjcStubs(b, .{ .target = b.host }));
57 macho_step.dependOn(testObjcStubs2(b, .{ .target = b.host }));
56 macho_step.dependOn(testWeakFramework(b, .{ .target = b.host }));58 macho_step.dependOn(testWeakFramework(b, .{ .target = b.host }));
57 }59 }
58 }60 }
...@@ -289,6 +291,7 @@ fn testEntryPointArchive(b: *Build, opts: Options) *Step {...@@ -289,6 +291,7 @@ fn testEntryPointArchive(b: *Build, opts: Options) *Step {
289 exe.root_module.addLibraryPath(lib.getEmittedBinDirectory());291 exe.root_module.addLibraryPath(lib.getEmittedBinDirectory());
290292
291 const run = addRunArtifact(exe);293 const run = addRunArtifact(exe);
294 run.expectExitCode(0);
292 test_step.dependOn(&run.step);295 test_step.dependOn(&run.step);
293 }296 }
294297
...@@ -299,6 +302,7 @@ fn testEntryPointArchive(b: *Build, opts: Options) *Step {...@@ -299,6 +302,7 @@ fn testEntryPointArchive(b: *Build, opts: Options) *Step {
299 exe.link_gc_sections = true;302 exe.link_gc_sections = true;
300303
301 const run = addRunArtifact(exe);304 const run = addRunArtifact(exe);
305 run.expectExitCode(0);
302 test_step.dependOn(&run.step);306 test_step.dependOn(&run.step);
303 }307 }
304308
...@@ -769,6 +773,7 @@ fn testNoDeadStrip(b: *Build, opts: Options) *Step {...@@ -769,6 +773,7 @@ fn testNoDeadStrip(b: *Build, opts: Options) *Step {
769 test_step.dependOn(&check.step);773 test_step.dependOn(&check.step);
770774
771 const run = addRunArtifact(exe);775 const run = addRunArtifact(exe);
776 run.expectExitCode(0);
772 test_step.dependOn(&run.step);777 test_step.dependOn(&run.step);
773778
774 return test_step;779 return test_step;
...@@ -859,6 +864,155 @@ fn testObjc(b: *Build, opts: Options) *Step {...@@ -859,6 +864,155 @@ fn testObjc(b: *Build, opts: Options) *Step {
859 return test_step;864 return test_step;
860}865}
861866
867fn testObjcStubs(b: *Build, opts: Options) *Step {
868 const test_step = addTestStep(b, "macho-objc-stubs", opts);
869
870 const exe = addExecutable(b, opts, .{
871 .name = "main",
872 .objc_source_bytes =
873 \\@import Foundation;
874 \\@interface Foo : NSObject
875 \\@property (nonatomic, assign) NSString* name;
876 \\@end
877 \\@implementation Foo
878 \\- (void)bar {
879 \\ printf("%s", [self.name UTF8String]);
880 \\}
881 \\@end
882 \\int main() {
883 \\ Foo *foo = [[Foo alloc] init];
884 \\ foo.name = @"Foo";
885 \\ [foo bar];
886 \\ return 0;
887 \\}
888 ,
889 .objc_source_flags = &.{ "-fmodules", "-fobjc-msgsend-selector-stubs" },
890 });
891 exe.root_module.linkFramework("Foundation", .{});
892
893 const run = addRunArtifact(exe);
894 run.expectStdOutEqual("Foo");
895 test_step.dependOn(&run.step);
896
897 const check = exe.checkObject();
898 check.checkInHeaders();
899 check.checkExact("sectname __objc_stubs");
900 check.checkInHeaders();
901 check.checkExact("sectname __objc_methname");
902 check.checkInHeaders();
903 check.checkExact("sectname __objc_selrefs");
904 check.checkInSymtab();
905 check.checkContains("(__TEXT,__objc_stubs) (was private external) _objc_msgSend$bar");
906 check.checkInSymtab();
907 check.checkContains("(__TEXT,__objc_stubs) (was private external) _objc_msgSend$name");
908 check.checkInSymtab();
909 check.checkContains("(__TEXT,__objc_stubs) (was private external) _objc_msgSend$setName");
910 test_step.dependOn(&check.step);
911
912 return test_step;
913}
914
915fn testObjcStubs2(b: *Build, opts: Options) *Step {
916 const test_step = addTestStep(b, "macho-objc-stubs-2", opts);
917
918 const all_h = all_h: {
919 const wf = WriteFile.create(b);
920 break :all_h wf.add("all.h",
921 \\#import <Foundation/Foundation.h>
922 \\
923 \\@interface Foo : NSObject
924 \\@property (nonatomic, assign) NSString* name;
925 \\- (void) foo;
926 \\@end
927 \\@interface Bar : NSObject
928 \\@property (nonatomic, assign) NSString* name;
929 \\- (void) bar;
930 \\- (void) foobar: (Foo*) foo;
931 \\@end
932 );
933 };
934
935 const foo_o = addObject(b, opts, .{
936 .name = "foo",
937 .objc_source_bytes =
938 \\#import <Foundation/Foundation.h>
939 \\#import "all.h"
940 \\@implementation Foo
941 \\- (void)foo {
942 \\ printf("%s", [self.name UTF8String]);
943 \\}
944 \\@end
945 ,
946 .objc_source_flags = &.{"-fobjc-msgsend-selector-stubs"},
947 });
948 foo_o.root_module.addIncludePath(all_h.dirname());
949
950 const bar_o = addObject(b, opts, .{
951 .name = "bar",
952 .objc_source_bytes =
953 \\#import <Foundation/Foundation.h>
954 \\#import "all.h"
955 \\@implementation Bar
956 \\- (void)bar {
957 \\ printf("%s", [self.name UTF8String]);
958 \\}
959 \\- (void)foobar: (Foo*) foo {
960 \\ printf("%s%s", [foo.name UTF8String], [self.name UTF8String]);
961 \\}
962 \\@end
963 ,
964 .objc_source_flags = &.{"-fobjc-msgsend-selector-stubs"},
965 });
966 bar_o.root_module.addIncludePath(all_h.dirname());
967
968 const main_o = addObject(b, opts, .{
969 .name = "main",
970 .objc_source_bytes =
971 \\#import <Foundation/Foundation.h>
972 \\#import "all.h"
973 \\int main() {
974 \\ Foo *foo = [[Foo alloc] init];
975 \\ foo.name = @"Foo";
976 \\ Bar *bar = [[Bar alloc] init];
977 \\ bar.name = @"Bar";
978 \\ [foo foo];
979 \\ [bar bar];
980 \\ [bar foobar:foo];
981 \\ return 0;
982 \\}
983 ,
984 .objc_source_flags = &.{"-fobjc-msgsend-selector-stubs"},
985 });
986 main_o.root_module.addIncludePath(all_h.dirname());
987
988 const exe = addExecutable(b, opts, .{ .name = "main" });
989 exe.addObject(main_o);
990 exe.addObject(foo_o);
991 exe.addObject(bar_o);
992 exe.root_module.linkFramework("Foundation", .{});
993
994 const run = addRunArtifact(exe);
995 run.expectStdOutEqual("FooBarFooBar");
996 test_step.dependOn(&run.step);
997
998 const check = exe.checkObject();
999 check.checkInHeaders();
1000 check.checkExact("sectname __objc_stubs");
1001 check.checkInHeaders();
1002 check.checkExact("sectname __objc_methname");
1003 check.checkInHeaders();
1004 check.checkExact("sectname __objc_selrefs");
1005 check.checkInSymtab();
1006 check.checkContains("(__TEXT,__objc_stubs) (was private external) _objc_msgSend$foo");
1007 check.checkInSymtab();
1008 check.checkContains("(__TEXT,__objc_stubs) (was private external) _objc_msgSend$bar");
1009 check.checkInSymtab();
1010 check.checkContains("(__TEXT,__objc_stubs) (was private external) _objc_msgSend$foobar");
1011 test_step.dependOn(&check.step);
1012
1013 return test_step;
1014}
1015
862fn testRelocatable(b: *Build, opts: Options) *Step {1016fn testRelocatable(b: *Build, opts: Options) *Step {
863 const test_step = addTestStep(b, "macho-relocatable", opts);1017 const test_step = addTestStep(b, "macho-relocatable", opts);
8641018
...@@ -1647,3 +1801,4 @@ const BuildOptions = link.BuildOptions;...@@ -1647,3 +1801,4 @@ const BuildOptions = link.BuildOptions;
1647const Compile = Step.Compile;1801const Compile = Step.Compile;
1648const Options = link.Options;1802const Options = link.Options;
1649const Step = Build.Step;1803const Step = Build.Step;
1804const WriteFile = Step.WriteFile;