| ... | @@ -27,6 +27,8 @@ pub fn build(b: *Build) void { | ... | @@ -27,6 +27,8 @@ pub fn build(b: *Build) void { |
| 27 | elf_step.dependOn(testEmptyObject(b, .{ .target = musl_target })); | 27 | elf_step.dependOn(testEmptyObject(b, .{ .target = musl_target })); |
| 28 | elf_step.dependOn(testEntryPoint(b, .{ .target = musl_target })); | 28 | elf_step.dependOn(testEntryPoint(b, .{ .target = musl_target })); |
| 29 | elf_step.dependOn(testGcSections(b, .{ .target = musl_target })); | 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 | elf_step.dependOn(testLinkingC(b, .{ .target = musl_target })); | 32 | elf_step.dependOn(testLinkingC(b, .{ .target = musl_target })); |
| 31 | elf_step.dependOn(testLinkingCpp(b, .{ .target = musl_target })); | 33 | elf_step.dependOn(testLinkingCpp(b, .{ .target = musl_target })); |
| 32 | elf_step.dependOn(testLinkingZig(b, .{ .target = musl_target })); | 34 | elf_step.dependOn(testLinkingZig(b, .{ .target = musl_target })); |
| ... | @@ -44,8 +46,24 @@ pub fn build(b: *Build) void { | ... | @@ -44,8 +46,24 @@ pub fn build(b: *Build) void { |
| 44 | elf_step.dependOn(testDsoUndef(b, .{ .target = glibc_target })); | 46 | elf_step.dependOn(testDsoUndef(b, .{ .target = glibc_target })); |
| 45 | elf_step.dependOn(testExportDynamic(b, .{ .target = glibc_target })); | 47 | elf_step.dependOn(testExportDynamic(b, .{ .target = glibc_target })); |
| 46 | elf_step.dependOn(testExportSymbolsFromExe(b, .{ .target = glibc_target })); | 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 | elf_step.dependOn(testLargeAlignmentDso(b, .{ .target = glibc_target })); | 64 | elf_step.dependOn(testLargeAlignmentDso(b, .{ .target = glibc_target })); |
| 48 | elf_step.dependOn(testLargeAlignmentExe(b, .{ .target = glibc_target })); | 65 | elf_step.dependOn(testLargeAlignmentExe(b, .{ .target = glibc_target })); |
| | 66 | elf_step.dependOn(testPie(b, .{ .target = glibc_target })); |
| 49 | } | 67 | } |
| 50 | | 68 | |
| 51 | fn testAbsSymbols(b: *Build, opts: Options) *Step { | 69 | fn testAbsSymbols(b: *Build, opts: Options) *Step { |
| ... | @@ -686,6 +704,32 @@ fn testExportSymbolsFromExe(b: *Build, opts: Options) *Step { | ... | @@ -686,6 +704,32 @@ fn testExportSymbolsFromExe(b: *Build, opts: Options) *Step { |
| 686 | return test_step; | 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 | fn testGcSections(b: *Build, opts: Options) *Step { | 733 | fn testGcSections(b: *Build, opts: Options) *Step { |
| 690 | const test_step = addTestStep(b, "gc-sections", opts); | 734 | const test_step = addTestStep(b, "gc-sections", opts); |
| 691 | | 735 | |
| ... | @@ -776,6 +820,449 @@ fn testGcSections(b: *Build, opts: Options) *Step { | ... | @@ -776,6 +820,449 @@ fn testGcSections(b: *Build, opts: Options) *Step { |
| 776 | return test_step; | 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 | fn testLargeAlignmentDso(b: *Build, opts: Options) *Step { | 1266 | fn testLargeAlignmentDso(b: *Build, opts: Options) *Step { |
| 780 | const test_step = addTestStep(b, "large-alignment-dso", opts); | 1267 | const test_step = addTestStep(b, "large-alignment-dso", opts); |
| 781 | | 1268 | |
| ... | @@ -951,6 +1438,37 @@ fn testLinkingZig(b: *Build, opts: Options) *Step { | ... | @@ -951,6 +1438,37 @@ fn testLinkingZig(b: *Build, opts: Options) *Step { |
| 951 | return test_step; | 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 | fn testTlsStatic(b: *Build, opts: Options) *Step { | 1472 | fn testTlsStatic(b: *Build, opts: Options) *Step { |
| 955 | const test_step = addTestStep(b, "tls-static", opts); | 1473 | const test_step = addTestStep(b, "tls-static", opts); |
| 956 | | 1474 | |