| ... | ... | @@ -27,6 +27,8 @@ pub fn build(b: *Build) void { |
| 27 | 27 | elf_step.dependOn(testEmptyObject(b, .{ .target = musl_target })); |
| 28 | 28 | elf_step.dependOn(testEntryPoint(b, .{ .target = musl_target })); |
| 29 | 29 | elf_step.dependOn(testGcSections(b, .{ .target = musl_target })); |
| 30 | elf_step.dependOn(testImageBase(b, .{ .target = musl_target })); |
| 31 | elf_step.dependOn(testInitArrayOrder(b, .{ .target = musl_target })); |
| 30 | 32 | elf_step.dependOn(testLinkingC(b, .{ .target = musl_target })); |
| 31 | 33 | elf_step.dependOn(testLinkingCpp(b, .{ .target = musl_target })); |
| 32 | 34 | elf_step.dependOn(testLinkingZig(b, .{ .target = musl_target })); |
| ... | ... | @@ -44,8 +46,24 @@ pub fn build(b: *Build) void { |
| 44 | 46 | elf_step.dependOn(testDsoUndef(b, .{ .target = glibc_target })); |
| 45 | 47 | elf_step.dependOn(testExportDynamic(b, .{ .target = glibc_target })); |
| 46 | 48 | elf_step.dependOn(testExportSymbolsFromExe(b, .{ .target = glibc_target })); |
| 49 | // https://github.com/ziglang/zig/issues/17430 |
| 50 | // elf_step.dependOn(testFuncAddress(b, .{ .target = glibc_target })); |
| 51 | elf_step.dependOn(testHiddenWeakUndef(b, .{ .target = glibc_target })); |
| 52 | elf_step.dependOn(testIFuncAlias(b, .{ .target = glibc_target })); |
| 53 | // https://github.com/ziglang/zig/issues/17430 |
| 54 | // elf_step.dependOn(testIFuncDlopen(b, .{ .target = glibc_target })); |
| 55 | elf_step.dependOn(testIFuncDso(b, .{ .target = glibc_target })); |
| 56 | elf_step.dependOn(testIFuncDynamic(b, .{ .target = glibc_target })); |
| 57 | elf_step.dependOn(testIFuncExport(b, .{ .target = glibc_target })); |
| 58 | elf_step.dependOn(testIFuncFuncPtr(b, .{ .target = glibc_target })); |
| 59 | elf_step.dependOn(testIFuncNoPlt(b, .{ .target = glibc_target })); |
| 60 | // https://github.com/ziglang/zig/issues/17430 ?? |
| 61 | // elf_step.dependOn(testIFuncStatic(b, .{ .target = glibc_target })); |
| 62 | // elf_step.dependOn(testIFuncStaticPie(b, .{ .target = glibc_target })); |
| 63 | elf_step.dependOn(testInitArrayOrder(b, .{ .target = glibc_target })); |
| 47 | 64 | elf_step.dependOn(testLargeAlignmentDso(b, .{ .target = glibc_target })); |
| 48 | 65 | elf_step.dependOn(testLargeAlignmentExe(b, .{ .target = glibc_target })); |
| 66 | elf_step.dependOn(testPie(b, .{ .target = glibc_target })); |
| 49 | 67 | } |
| 50 | 68 | |
| 51 | 69 | fn testAbsSymbols(b: *Build, opts: Options) *Step { |
| ... | ... | @@ -686,6 +704,32 @@ fn testExportSymbolsFromExe(b: *Build, opts: Options) *Step { |
| 686 | 704 | return test_step; |
| 687 | 705 | } |
| 688 | 706 | |
| 707 | fn testFuncAddress(b: *Build, opts: Options) *Step { |
| 708 | const test_step = addTestStep(b, "func-address", opts); |
| 709 | |
| 710 | const dso = addSharedLibrary(b, "a", opts); |
| 711 | addCSourceBytes(dso, "void fn() {}", &.{}); |
| 712 | |
| 713 | const exe = addExecutable(b, "main", opts); |
| 714 | addCSourceBytes(exe, |
| 715 | \\#include <assert.h> |
| 716 | \\typedef void Func(); |
| 717 | \\void fn(); |
| 718 | \\Func *const ptr = fn; |
| 719 | \\int main() { |
| 720 | \\ assert(fn == ptr); |
| 721 | \\} |
| 722 | , &.{}); |
| 723 | exe.linkLibrary(dso); |
| 724 | exe.force_pic = false; |
| 725 | exe.pie = false; |
| 726 | |
| 727 | const run = addRunArtifact(exe); |
| 728 | test_step.dependOn(&run.step); |
| 729 | |
| 730 | return test_step; |
| 731 | } |
| 732 | |
| 689 | 733 | fn testGcSections(b: *Build, opts: Options) *Step { |
| 690 | 734 | const test_step = addTestStep(b, "gc-sections", opts); |
| 691 | 735 | |
| ... | ... | @@ -776,6 +820,449 @@ fn testGcSections(b: *Build, opts: Options) *Step { |
| 776 | 820 | return test_step; |
| 777 | 821 | } |
| 778 | 822 | |
| 823 | fn testHiddenWeakUndef(b: *Build, opts: Options) *Step { |
| 824 | const test_step = addTestStep(b, "hidden-weak-undef", opts); |
| 825 | |
| 826 | const dso = addSharedLibrary(b, "a", opts); |
| 827 | addCSourceBytes(dso, |
| 828 | \\__attribute__((weak, visibility("hidden"))) void foo(); |
| 829 | \\void bar() { foo(); } |
| 830 | , &.{}); |
| 831 | |
| 832 | const check = dso.checkObject(); |
| 833 | check.checkInDynamicSymtab(); |
| 834 | check.checkNotPresent("foo"); |
| 835 | check.checkInDynamicSymtab(); |
| 836 | check.checkContains("bar"); |
| 837 | test_step.dependOn(&check.step); |
| 838 | |
| 839 | return test_step; |
| 840 | } |
| 841 | |
| 842 | fn testIFuncAlias(b: *Build, opts: Options) *Step { |
| 843 | const test_step = addTestStep(b, "ifunc-alias", opts); |
| 844 | |
| 845 | const exe = addExecutable(b, "main", opts); |
| 846 | addCSourceBytes(exe, |
| 847 | \\#include <assert.h> |
| 848 | \\void foo() {} |
| 849 | \\int bar() __attribute__((ifunc("resolve_bar"))); |
| 850 | \\void *resolve_bar() { return foo; } |
| 851 | \\void *bar2 = bar; |
| 852 | \\int main() { |
| 853 | \\ assert(bar == bar2); |
| 854 | \\} |
| 855 | , &.{}); |
| 856 | exe.force_pic = true; |
| 857 | exe.linkLibC(); |
| 858 | |
| 859 | const run = addRunArtifact(exe); |
| 860 | run.expectExitCode(0); |
| 861 | test_step.dependOn(&run.step); |
| 862 | |
| 863 | return test_step; |
| 864 | } |
| 865 | |
| 866 | fn testIFuncDlopen(b: *Build, opts: Options) *Step { |
| 867 | const test_step = addTestStep(b, "ifunc-dlopen", opts); |
| 868 | |
| 869 | const dso = addSharedLibrary(b, "a", opts); |
| 870 | addCSourceBytes(dso, |
| 871 | \\__attribute__((ifunc("resolve_foo"))) |
| 872 | \\void foo(void); |
| 873 | \\static void real_foo(void) { |
| 874 | \\} |
| 875 | \\typedef void Func(); |
| 876 | \\static Func *resolve_foo(void) { |
| 877 | \\ return real_foo; |
| 878 | \\} |
| 879 | , &.{}); |
| 880 | |
| 881 | const exe = addExecutable(b, "main", opts); |
| 882 | addCSourceBytes(exe, |
| 883 | \\#include <dlfcn.h> |
| 884 | \\#include <assert.h> |
| 885 | \\#include <stdlib.h> |
| 886 | \\typedef void Func(); |
| 887 | \\void foo(void); |
| 888 | \\int main() { |
| 889 | \\ void *handle = dlopen(NULL, RTLD_NOW); |
| 890 | \\ Func *p = dlsym(handle, "foo"); |
| 891 | \\ |
| 892 | \\ foo(); |
| 893 | \\ p(); |
| 894 | \\ assert(foo == p); |
| 895 | \\} |
| 896 | , &.{}); |
| 897 | exe.linkLibrary(dso); |
| 898 | exe.linkLibC(); |
| 899 | exe.linkSystemLibrary2("dl", .{}); |
| 900 | exe.force_pic = false; |
| 901 | exe.pie = false; |
| 902 | |
| 903 | const run = addRunArtifact(exe); |
| 904 | test_step.dependOn(&run.step); |
| 905 | |
| 906 | return test_step; |
| 907 | } |
| 908 | |
| 909 | fn testIFuncDso(b: *Build, opts: Options) *Step { |
| 910 | const test_step = addTestStep(b, "ifunc-dso", opts); |
| 911 | |
| 912 | const dso = addSharedLibrary(b, "a", opts); |
| 913 | addCSourceBytes(dso, |
| 914 | \\#include<stdio.h> |
| 915 | \\__attribute__((ifunc("resolve_foobar"))) |
| 916 | \\void foobar(void); |
| 917 | \\static void real_foobar(void) { |
| 918 | \\ printf("Hello world\n"); |
| 919 | \\} |
| 920 | \\typedef void Func(); |
| 921 | \\static Func *resolve_foobar(void) { |
| 922 | \\ return real_foobar; |
| 923 | \\} |
| 924 | , &.{}); |
| 925 | dso.linkLibC(); |
| 926 | |
| 927 | const exe = addExecutable(b, "main", opts); |
| 928 | addCSourceBytes(exe, |
| 929 | \\void foobar(void); |
| 930 | \\int main() { |
| 931 | \\ foobar(); |
| 932 | \\} |
| 933 | , &.{}); |
| 934 | exe.linkLibrary(dso); |
| 935 | |
| 936 | const run = addRunArtifact(exe); |
| 937 | run.expectStdOutEqual("Hello world\n"); |
| 938 | test_step.dependOn(&run.step); |
| 939 | |
| 940 | return test_step; |
| 941 | } |
| 942 | |
| 943 | fn testIFuncDynamic(b: *Build, opts: Options) *Step { |
| 944 | const test_step = addTestStep(b, "ifunc-dynamic", opts); |
| 945 | |
| 946 | const main_c = |
| 947 | \\#include <stdio.h> |
| 948 | \\__attribute__((ifunc("resolve_foobar"))) |
| 949 | \\static void foobar(void); |
| 950 | \\static void real_foobar(void) { |
| 951 | \\ printf("Hello world\n"); |
| 952 | \\} |
| 953 | \\typedef void Func(); |
| 954 | \\static Func *resolve_foobar(void) { |
| 955 | \\ return real_foobar; |
| 956 | \\} |
| 957 | \\int main() { |
| 958 | \\ foobar(); |
| 959 | \\} |
| 960 | ; |
| 961 | |
| 962 | { |
| 963 | const exe = addExecutable(b, "main", opts); |
| 964 | addCSourceBytes(exe, main_c, &.{}); |
| 965 | exe.linkLibC(); |
| 966 | exe.link_z_lazy = true; |
| 967 | |
| 968 | const run = addRunArtifact(exe); |
| 969 | run.expectStdOutEqual("Hello world\n"); |
| 970 | test_step.dependOn(&run.step); |
| 971 | } |
| 972 | { |
| 973 | const exe = addExecutable(b, "other", opts); |
| 974 | addCSourceBytes(exe, main_c, &.{}); |
| 975 | exe.linkLibC(); |
| 976 | |
| 977 | const run = addRunArtifact(exe); |
| 978 | run.expectStdOutEqual("Hello world\n"); |
| 979 | test_step.dependOn(&run.step); |
| 980 | } |
| 981 | |
| 982 | return test_step; |
| 983 | } |
| 984 | |
| 985 | fn testIFuncExport(b: *Build, opts: Options) *Step { |
| 986 | const test_step = addTestStep(b, "ifunc-export", opts); |
| 987 | |
| 988 | const dso = addSharedLibrary(b, "a", opts); |
| 989 | addCSourceBytes(dso, |
| 990 | \\#include <stdio.h> |
| 991 | \\__attribute__((ifunc("resolve_foobar"))) |
| 992 | \\void foobar(void); |
| 993 | \\void real_foobar(void) { |
| 994 | \\ printf("Hello world\n"); |
| 995 | \\} |
| 996 | \\typedef void Func(); |
| 997 | \\Func *resolve_foobar(void) { |
| 998 | \\ return real_foobar; |
| 999 | \\} |
| 1000 | , &.{}); |
| 1001 | dso.linkLibC(); |
| 1002 | |
| 1003 | const check = dso.checkObject(); |
| 1004 | check.checkInDynamicSymtab(); |
| 1005 | check.checkContains("IFUNC GLOBAL DEFAULT foobar"); |
| 1006 | test_step.dependOn(&check.step); |
| 1007 | |
| 1008 | return test_step; |
| 1009 | } |
| 1010 | |
| 1011 | fn testIFuncFuncPtr(b: *Build, opts: Options) *Step { |
| 1012 | const test_step = addTestStep(b, "ifunc-func-ptr", opts); |
| 1013 | |
| 1014 | const exe = addExecutable(b, "main", opts); |
| 1015 | addCSourceBytes(exe, |
| 1016 | \\typedef int Fn(); |
| 1017 | \\int foo() __attribute__((ifunc("resolve_foo"))); |
| 1018 | \\int real_foo() { return 3; } |
| 1019 | \\Fn *resolve_foo(void) { |
| 1020 | \\ return real_foo; |
| 1021 | \\} |
| 1022 | , &.{}); |
| 1023 | addCSourceBytes(exe, |
| 1024 | \\typedef int Fn(); |
| 1025 | \\int foo(); |
| 1026 | \\Fn *get_foo() { return foo; } |
| 1027 | , &.{}); |
| 1028 | addCSourceBytes(exe, |
| 1029 | \\#include <stdio.h> |
| 1030 | \\typedef int Fn(); |
| 1031 | \\Fn *get_foo(); |
| 1032 | \\int main() { |
| 1033 | \\ Fn *f = get_foo(); |
| 1034 | \\ printf("%d\n", f()); |
| 1035 | \\} |
| 1036 | , &.{}); |
| 1037 | exe.force_pic = true; |
| 1038 | exe.linkLibC(); |
| 1039 | |
| 1040 | const run = addRunArtifact(exe); |
| 1041 | run.expectStdOutEqual("3\n"); |
| 1042 | test_step.dependOn(&run.step); |
| 1043 | |
| 1044 | return test_step; |
| 1045 | } |
| 1046 | |
| 1047 | fn testIFuncNoPlt(b: *Build, opts: Options) *Step { |
| 1048 | const test_step = addTestStep(b, "ifunc-noplt", opts); |
| 1049 | |
| 1050 | const exe = addExecutable(b, "main", opts); |
| 1051 | addCSourceBytes(exe, |
| 1052 | \\#include <stdio.h> |
| 1053 | \\__attribute__((ifunc("resolve_foo"))) |
| 1054 | \\void foo(void); |
| 1055 | \\void hello(void) { |
| 1056 | \\ printf("Hello world\n"); |
| 1057 | \\} |
| 1058 | \\typedef void Fn(); |
| 1059 | \\Fn *resolve_foo(void) { |
| 1060 | \\ return hello; |
| 1061 | \\} |
| 1062 | \\int main() { |
| 1063 | \\ foo(); |
| 1064 | \\} |
| 1065 | , &.{"-fno-plt"}); |
| 1066 | exe.force_pic = true; |
| 1067 | exe.linkLibC(); |
| 1068 | |
| 1069 | const run = addRunArtifact(exe); |
| 1070 | run.expectStdOutEqual("Hello world\n"); |
| 1071 | test_step.dependOn(&run.step); |
| 1072 | |
| 1073 | return test_step; |
| 1074 | } |
| 1075 | |
| 1076 | fn testIFuncStatic(b: *Build, opts: Options) *Step { |
| 1077 | const test_step = addTestStep(b, "ifunc-static", opts); |
| 1078 | |
| 1079 | const exe = addExecutable(b, "main", opts); |
| 1080 | addCSourceBytes(exe, |
| 1081 | \\#include <stdio.h> |
| 1082 | \\void foo() __attribute__((ifunc("resolve_foo"))); |
| 1083 | \\void hello() { |
| 1084 | \\ printf("Hello world\n"); |
| 1085 | \\} |
| 1086 | \\void *resolve_foo() { |
| 1087 | \\ return hello; |
| 1088 | \\} |
| 1089 | \\int main() { |
| 1090 | \\ foo(); |
| 1091 | \\ return 0; |
| 1092 | \\} |
| 1093 | , &.{}); |
| 1094 | exe.linkLibC(); |
| 1095 | exe.linkage = .static; |
| 1096 | |
| 1097 | const run = addRunArtifact(exe); |
| 1098 | run.expectStdOutEqual("Hello world\n"); |
| 1099 | test_step.dependOn(&run.step); |
| 1100 | |
| 1101 | return test_step; |
| 1102 | } |
| 1103 | |
| 1104 | fn testIFuncStaticPie(b: *Build, opts: Options) *Step { |
| 1105 | const test_step = addTestStep(b, "ifunc-static-pie", opts); |
| 1106 | |
| 1107 | const exe = addExecutable(b, "main", opts); |
| 1108 | addCSourceBytes(exe, |
| 1109 | \\#include <stdio.h> |
| 1110 | \\void foo() __attribute__((ifunc("resolve_foo"))); |
| 1111 | \\void hello() { |
| 1112 | \\ printf("Hello world\n"); |
| 1113 | \\} |
| 1114 | \\void *resolve_foo() { |
| 1115 | \\ return hello; |
| 1116 | \\} |
| 1117 | \\int main() { |
| 1118 | \\ foo(); |
| 1119 | \\ return 0; |
| 1120 | \\} |
| 1121 | , &.{}); |
| 1122 | exe.linkage = .static; |
| 1123 | exe.force_pic = true; |
| 1124 | exe.pie = true; |
| 1125 | exe.linkLibC(); |
| 1126 | |
| 1127 | const run = addRunArtifact(exe); |
| 1128 | run.expectStdOutEqual("Hello world\n"); |
| 1129 | test_step.dependOn(&run.step); |
| 1130 | |
| 1131 | const check = exe.checkObject(); |
| 1132 | check.checkStart(); |
| 1133 | check.checkExact("header"); |
| 1134 | check.checkExact("type DYN"); |
| 1135 | check.checkStart(); |
| 1136 | check.checkExact("section headers"); |
| 1137 | check.checkExact("name .dynamic"); |
| 1138 | check.checkStart(); |
| 1139 | check.checkExact("section headers"); |
| 1140 | check.checkNotPresent("name .interp"); |
| 1141 | test_step.dependOn(&check.step); |
| 1142 | |
| 1143 | return test_step; |
| 1144 | } |
| 1145 | |
| 1146 | fn testImageBase(b: *Build, opts: Options) *Step { |
| 1147 | const test_step = addTestStep(b, "image-base", opts); |
| 1148 | |
| 1149 | { |
| 1150 | const exe = addExecutable(b, "main1", opts); |
| 1151 | addCSourceBytes(exe, |
| 1152 | \\#include <stdio.h> |
| 1153 | \\int main() { |
| 1154 | \\ printf("Hello World!\n"); |
| 1155 | \\ return 0; |
| 1156 | \\} |
| 1157 | , &.{}); |
| 1158 | exe.linkLibC(); |
| 1159 | exe.image_base = 0x8000000; |
| 1160 | |
| 1161 | const run = addRunArtifact(exe); |
| 1162 | run.expectStdOutEqual("Hello World!\n"); |
| 1163 | test_step.dependOn(&run.step); |
| 1164 | |
| 1165 | const check = exe.checkObject(); |
| 1166 | check.checkStart(); |
| 1167 | check.checkExact("header"); |
| 1168 | check.checkExtract("entry {addr}"); |
| 1169 | check.checkComputeCompare("addr", .{ .op = .gte, .value = .{ .literal = 0x8000000 } }); |
| 1170 | test_step.dependOn(&check.step); |
| 1171 | } |
| 1172 | |
| 1173 | { |
| 1174 | const exe = addExecutable(b, "main2", opts); |
| 1175 | addCSourceBytes(exe, "void _start() {}", &.{}); |
| 1176 | exe.image_base = 0xffffffff8000000; |
| 1177 | |
| 1178 | const check = exe.checkObject(); |
| 1179 | check.checkStart(); |
| 1180 | check.checkExact("header"); |
| 1181 | check.checkExtract("entry {addr}"); |
| 1182 | check.checkComputeCompare("addr", .{ .op = .gte, .value = .{ .literal = 0xffffffff8000000 } }); |
| 1183 | test_step.dependOn(&check.step); |
| 1184 | } |
| 1185 | |
| 1186 | return test_step; |
| 1187 | } |
| 1188 | |
| 1189 | fn testInitArrayOrder(b: *Build, opts: Options) *Step { |
| 1190 | const test_step = addTestStep(b, "init-array-order", opts); |
| 1191 | |
| 1192 | const a_o = addObject(b, "a", opts); |
| 1193 | addCSourceBytes(a_o, |
| 1194 | \\#include <stdio.h> |
| 1195 | \\__attribute__((constructor(10000))) void init4() { printf("1"); } |
| 1196 | , &.{}); |
| 1197 | a_o.linkLibC(); |
| 1198 | |
| 1199 | const b_o = addObject(b, "b", opts); |
| 1200 | addCSourceBytes(b_o, |
| 1201 | \\#include <stdio.h> |
| 1202 | \\__attribute__((constructor(1000))) void init3() { printf("2"); } |
| 1203 | , &.{}); |
| 1204 | b_o.linkLibC(); |
| 1205 | |
| 1206 | const c_o = addObject(b, "c", opts); |
| 1207 | addCSourceBytes(c_o, |
| 1208 | \\#include <stdio.h> |
| 1209 | \\__attribute__((constructor)) void init1() { printf("3"); } |
| 1210 | , &.{}); |
| 1211 | c_o.linkLibC(); |
| 1212 | |
| 1213 | const d_o = addObject(b, "d", opts); |
| 1214 | addCSourceBytes(d_o, |
| 1215 | \\#include <stdio.h> |
| 1216 | \\__attribute__((constructor)) void init2() { printf("4"); } |
| 1217 | , &.{}); |
| 1218 | d_o.linkLibC(); |
| 1219 | |
| 1220 | const e_o = addObject(b, "e", opts); |
| 1221 | addCSourceBytes(e_o, |
| 1222 | \\#include <stdio.h> |
| 1223 | \\__attribute__((destructor(10000))) void fini4() { printf("5"); } |
| 1224 | , &.{}); |
| 1225 | e_o.linkLibC(); |
| 1226 | |
| 1227 | const f_o = addObject(b, "f", opts); |
| 1228 | addCSourceBytes(f_o, |
| 1229 | \\#include <stdio.h> |
| 1230 | \\__attribute__((destructor(1000))) void fini3() { printf("6"); } |
| 1231 | , &.{}); |
| 1232 | f_o.linkLibC(); |
| 1233 | |
| 1234 | const g_o = addObject(b, "g", opts); |
| 1235 | addCSourceBytes(g_o, |
| 1236 | \\#include <stdio.h> |
| 1237 | \\__attribute__((destructor)) void fini1() { printf("7"); } |
| 1238 | , &.{}); |
| 1239 | g_o.linkLibC(); |
| 1240 | |
| 1241 | const h_o = addObject(b, "h", opts); |
| 1242 | addCSourceBytes(h_o, |
| 1243 | \\#include <stdio.h> |
| 1244 | \\__attribute__((destructor)) void fini2() { printf("8"); } |
| 1245 | , &.{}); |
| 1246 | h_o.linkLibC(); |
| 1247 | |
| 1248 | const exe = addExecutable(b, "main", opts); |
| 1249 | addCSourceBytes(exe, "int main() { return 0; }", &.{}); |
| 1250 | exe.addObject(a_o); |
| 1251 | exe.addObject(b_o); |
| 1252 | exe.addObject(c_o); |
| 1253 | exe.addObject(d_o); |
| 1254 | exe.addObject(e_o); |
| 1255 | exe.addObject(f_o); |
| 1256 | exe.addObject(g_o); |
| 1257 | exe.addObject(h_o); |
| 1258 | |
| 1259 | const run = addRunArtifact(exe); |
| 1260 | run.expectStdOutEqual("21348756"); |
| 1261 | test_step.dependOn(&run.step); |
| 1262 | |
| 1263 | return test_step; |
| 1264 | } |
| 1265 | |
| 779 | 1266 | fn testLargeAlignmentDso(b: *Build, opts: Options) *Step { |
| 780 | 1267 | const test_step = addTestStep(b, "large-alignment-dso", opts); |
| 781 | 1268 | |
| ... | ... | @@ -951,6 +1438,37 @@ fn testLinkingZig(b: *Build, opts: Options) *Step { |
| 951 | 1438 | return test_step; |
| 952 | 1439 | } |
| 953 | 1440 | |
| 1441 | fn testPie(b: *Build, opts: Options) *Step { |
| 1442 | const test_step = addTestStep(b, "hello-pie", opts); |
| 1443 | |
| 1444 | const exe = addExecutable(b, "main", opts); |
| 1445 | addCSourceBytes(exe, |
| 1446 | \\#include <stdio.h> |
| 1447 | \\int main() { |
| 1448 | \\ printf("Hello!\n"); |
| 1449 | \\ return 0; |
| 1450 | \\} |
| 1451 | , &.{}); |
| 1452 | exe.linkLibC(); |
| 1453 | exe.force_pic = true; |
| 1454 | exe.pie = true; |
| 1455 | |
| 1456 | const run = addRunArtifact(exe); |
| 1457 | run.expectStdOutEqual("Hello!\n"); |
| 1458 | test_step.dependOn(&run.step); |
| 1459 | |
| 1460 | const check = exe.checkObject(); |
| 1461 | check.checkStart(); |
| 1462 | check.checkExact("header"); |
| 1463 | check.checkExact("type DYN"); |
| 1464 | check.checkStart(); |
| 1465 | check.checkExact("section headers"); |
| 1466 | check.checkExact("name .dynamic"); |
| 1467 | test_step.dependOn(&check.step); |
| 1468 | |
| 1469 | return test_step; |
| 1470 | } |
| 1471 | |
| 954 | 1472 | fn testTlsStatic(b: *Build, opts: Options) *Step { |
| 955 | 1473 | const test_step = addTestStep(b, "tls-static", opts); |
| 956 | 1474 | |