authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-10-06 00:11:39-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2018-10-06 00:11:39-04:00
logd40c4e7c896c5dfed9dd35e8c0d2117f7cf5c53c
tree07f7204287159ca5c9926e797144ef91ab35cdb6
parent5b84192f07d5e4b3f5ebcd3e08d79852710c04f4
parent2d2734172484871eb56705e77acca50a8c83d8ae
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #1429 from shawnl/arm64

initial arm64 support

16 files changed, 713 insertions(+), 86 deletions(-)

CMakeLists.txt+1
......@@ -578,6 +578,7 @@ set(ZIG_STD_FILES
578578 "os/linux/index.zig"
579579 "os/linux/vdso.zig"
580580 "os/linux/x86_64.zig"
581 "os/linux/arm64.zig"
581582 "os/path.zig"
582583 "os/time.zig"
583584 "os/windows/advapi32.zig"
src-self-hosted/libc_installation.zig+2-2
......@@ -280,7 +280,7 @@ pub const LibCInstallation = struct {
280280 switch (builtin.arch) {
281281 builtin.Arch.i386 => try stream.write("x86"),
282282 builtin.Arch.x86_64 => try stream.write("x64"),
283 builtin.Arch.aarch64 => try stream.write("arm"),
283 builtin.Arch.aarch64v8 => try stream.write("arm"),
284284 else => return error.UnsupportedArchitecture,
285285 }
286286 const ucrt_lib_path = try std.os.path.join(loop.allocator, result_buf.toSliceConst(), "ucrt.lib");
......@@ -355,7 +355,7 @@ pub const LibCInstallation = struct {
355355 switch (builtin.arch) {
356356 builtin.Arch.i386 => try stream.write("x86\\"),
357357 builtin.Arch.x86_64 => try stream.write("x64\\"),
358 builtin.Arch.aarch64 => try stream.write("arm\\"),
358 builtin.Arch.aarch64v8 => try stream.write("arm\\"),
359359 else => return error.UnsupportedArchitecture,
360360 }
361361 const kernel32_path = try std.os.path.join(loop.allocator, result_buf.toSliceConst(), "kernel32.lib");
src-self-hosted/link.zig+2-2
......@@ -330,7 +330,7 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
330330 switch (ctx.comp.target.getArch()) {
331331 builtin.Arch.i386 => try ctx.args.append(c"-MACHINE:X86"),
332332 builtin.Arch.x86_64 => try ctx.args.append(c"-MACHINE:X64"),
333 builtin.Arch.aarch64 => try ctx.args.append(c"-MACHINE:ARM"),
333 builtin.Arch.aarch64v8 => try ctx.args.append(c"-MACHINE:ARM"),
334334 else => return error.UnsupportedLinkArchitecture,
335335 }
336336
......@@ -556,7 +556,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
556556 }
557557 },
558558 DarwinPlatform.Kind.IPhoneOS => {
559 if (ctx.comp.target.getArch() == builtin.Arch.aarch64) {
559 if (ctx.comp.target.getArch() == builtin.Arch.aarch64v8) {
560560 // iOS does not need any crt1 files for arm64
561561 } else if (platform.versionLessThan(3, 1)) {
562562 try ctx.args.append(c"-lcrt1.o");
src-self-hosted/target.zig+39-5
......@@ -250,8 +250,20 @@ pub const Target = union(enum) {
250250 builtin.Arch.renderscript32,
251251 => return 32,
252252
253 builtin.Arch.aarch64,
254 builtin.Arch.aarch64_be,
253 builtin.Arch.aarch64v8_3a,
254 builtin.Arch.aarch64v8_2a,
255 builtin.Arch.aarch64v8_1a,
256 builtin.Arch.aarch64v8,
257 builtin.Arch.aarch64v8r,
258 builtin.Arch.aarch64v8m_baseline,
259 builtin.Arch.aarch64v8m_mainline,
260 builtin.Arch.aarch64_bev8_3a,
261 builtin.Arch.aarch64_bev8_2a,
262 builtin.Arch.aarch64_bev8_1a,
263 builtin.Arch.aarch64_bev8,
264 builtin.Arch.aarch64_bev8r,
265 builtin.Arch.aarch64_bev8m_baseline,
266 builtin.Arch.aarch64_bev8m_mainline,
255267 builtin.Arch.mips64,
256268 builtin.Arch.mips64el,
257269 builtin.Arch.powerpc64,
......@@ -316,8 +328,23 @@ pub const Target = union(enum) {
316328 builtin.Arch.sparcel,
317329 => return "/lib/ld-linux.so.2",
318330
319 builtin.Arch.aarch64 => return "/lib/ld-linux-aarch64.so.1",
320 builtin.Arch.aarch64_be => return "/lib/ld-linux-aarch64_be.so.1",
331 builtin.Arch.aarch64v8_3a,
332 builtin.Arch.aarch64v8_2a,
333 builtin.Arch.aarch64v8_1a,
334 builtin.Arch.aarch64v8,
335 builtin.Arch.aarch64v8r,
336 builtin.Arch.aarch64v8m_baseline,
337 builtin.Arch.aarch64v8m_mainline,
338 => return "/lib/ld-linux-aarch64.so.1",
339
340 builtin.Arch.aarch64_bev8_3a,
341 builtin.Arch.aarch64_bev8_2a,
342 builtin.Arch.aarch64_bev8_1a,
343 builtin.Arch.aarch64_bev8,
344 builtin.Arch.aarch64_bev8r,
345 builtin.Arch.aarch64_bev8m_baseline,
346 builtin.Arch.aarch64_bev8m_mainline,
347 => return "/lib/ld-linux-aarch64_be.so.1",
321348
322349 builtin.Arch.armv8_3a,
323350 builtin.Arch.armv8_2a,
......@@ -530,7 +557,14 @@ pub const Target = union(enum) {
530557 pub fn getDarwinArchString(self: Target) []const u8 {
531558 const arch = self.getArch();
532559 switch (arch) {
533 builtin.Arch.aarch64 => return "arm64",
560 builtin.Arch.aarch64v8_3a,
561 builtin.Arch.aarch64v8_2a,
562 builtin.Arch.aarch64v8_1a,
563 builtin.Arch.aarch64v8,
564 builtin.Arch.aarch64v8r,
565 builtin.Arch.aarch64v8m_baseline,
566 builtin.Arch.aarch64v8m_mainline,
567 => return "arm64",
534568 builtin.Arch.thumb,
535569 builtin.Arch.armv8_3a,
536570 builtin.Arch.armv8_2a,
src/os.cpp+2-2
......@@ -90,7 +90,7 @@ static void populate_termination(Termination *term, int status) {
9090static void os_spawn_process_posix(const char *exe, ZigList<const char *> &args, Termination *term) {
9191 pid_t pid = fork();
9292 if (pid == -1)
93 zig_panic("fork failed");
93 zig_panic("fork failed: %s", strerror(errno));
9494 if (pid == 0) {
9595 // child
9696 const char **argv = allocate<const char *>(args.length + 2);
......@@ -806,7 +806,7 @@ static int os_exec_process_posix(const char *exe, ZigList<const char *> &args,
806806
807807 pid_t pid = fork();
808808 if (pid == -1)
809 zig_panic("fork failed");
809 zig_panic("fork failed: %s", strerror(errno));
810810 if (pid == 0) {
811811 // child
812812 if (dup2(stdin_pipe[0], STDIN_FILENO) == -1)
src/target.cpp+18-3
......@@ -55,8 +55,22 @@ static const ArchType arch_list[] = {
5555 {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v5te},
5656 {ZigLLVM_armeb, ZigLLVM_ARMSubArch_v4t},
5757
58 {ZigLLVM_aarch64, ZigLLVM_NoSubArch},
59 {ZigLLVM_aarch64_be, ZigLLVM_NoSubArch},
58 {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8_3a},
59 {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8_2a},
60 {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8_1a},
61 {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8},
62 {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8r},
63 {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8m_baseline},
64 {ZigLLVM_aarch64, ZigLLVM_ARMSubArch_v8m_mainline},
65
66 {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8_3a},
67 {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8_2a},
68 {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8_1a},
69 {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8},
70 {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8r},
71 {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8m_baseline},
72 {ZigLLVM_aarch64_be, ZigLLVM_ARMSubArch_v8m_mainline},
73
6074 {ZigLLVM_arc, ZigLLVM_NoSubArch},
6175 {ZigLLVM_avr, ZigLLVM_NoSubArch},
6276 {ZigLLVM_bpfel, ZigLLVM_NoSubArch},
......@@ -943,8 +957,9 @@ const char *arch_stack_pointer_register_name(const ArchType *arch) {
943957 return "sp";
944958 case ZigLLVM_x86_64:
945959 return "rsp";
946
947960 case ZigLLVM_aarch64:
961 return "sp";
962
948963 case ZigLLVM_arm:
949964 case ZigLLVM_thumb:
950965 case ZigLLVM_aarch64_be:
std/elf.zig+5
......@@ -859,6 +859,11 @@ pub const Elf_MIPS_ABIFlags_v0 = extern struct {
859859 flags2: Elf32_Word,
860860};
861861
862pub const Auxv = switch (@sizeOf(usize)) {
863 4 => Elf32_auxv_t,
864 8 => Elf64_auxv_t,
865 else => @compileError("expected pointer size of 32 or 64"),
866};
862867pub const Ehdr = switch (@sizeOf(usize)) {
863868 4 => Elf32_Ehdr,
864869 8 => Elf64_Ehdr,
std/fmt/index.zig+3-1
......@@ -1044,7 +1044,9 @@ test "fmt.format" {
10441044 const result = try bufPrint(buf1[0..], "f64: {}\n", math.nan_f64);
10451045 assert(mem.eql(u8, result, "f64: nan\n"));
10461046 }
1047 {
1047 if (builtin.arch != builtin.Arch.armv8) {
1048 // negative nan is not defined by IEE 754,
1049 // and ARM thus normalizes it to positive nan
10481050 var buf1: [32]u8 = undefined;
10491051 const result = try bufPrint(buf1[0..], "f64: {}\n", -math.nan_f64);
10501052 assert(mem.eql(u8, result, "f64: -nan\n"));
std/math/index.zig+7-1
......@@ -8,7 +8,7 @@ pub const pi = 3.14159265358979323846264338327950288419716939937510;
88
99// float.h details
1010pub const f64_true_min = 4.94065645841246544177e-324;
11pub const f64_min = 2.22507385850720138309e-308;
11pub const f64_min = 2.2250738585072014e-308;
1212pub const f64_max = 1.79769313486231570815e+308;
1313pub const f64_epsilon = 2.22044604925031308085e-16;
1414pub const f64_toint = 1.0 / f64_epsilon;
......@@ -650,3 +650,9 @@ pub fn lossyCast(comptime T: type, value: var) T {
650650 else => @compileError("bad type"),
651651 }
652652}
653
654test "math.f64_min" {
655 const f64_min_u64 = 0x0010000000000000;
656 const fmin: f64 = f64_min;
657 assert(@bitCast(u64, fmin) == f64_min_u64);
658}
std/os/index.zig+11-7
......@@ -655,16 +655,21 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError {
655655 }
656656}
657657
658pub var linux_aux_raw = []usize{0} ** 38;
658pub var linux_elf_aux_maybe: ?[*]std.elf.Auxv = null;
659659pub var posix_environ_raw: [][*]u8 = undefined;
660660
661661/// See std.elf for the constants.
662662pub fn linuxGetAuxVal(index: usize) usize {
663663 if (builtin.link_libc) {
664664 return usize(std.c.getauxval(index));
665 } else {
666 return linux_aux_raw[index];
665 } else if (linux_elf_aux_maybe) |auxv| {
666 var i: usize = 0;
667 while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) {
668 if (auxv[i].a_type == index)
669 return auxv[i].a_un.a_val;
670 }
667671 }
672 return 0;
668673}
669674
670675pub fn getBaseAddress() usize {
......@@ -1676,7 +1681,7 @@ pub const Dir = struct {
16761681 }
16771682
16781683 while (true) {
1679 const result = posix.getdents(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len);
1684 const result = posix.getdents64(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len);
16801685 const err = posix.getErrno(result);
16811686 if (err > 0) {
16821687 switch (err) {
......@@ -1694,7 +1699,7 @@ pub const Dir = struct {
16941699 break;
16951700 }
16961701 }
1697 const linux_entry = @ptrCast(*align(1) posix.dirent, &self.handle.buf[self.handle.index]);
1702 const linux_entry = @ptrCast(*align(1) posix.dirent64, &self.handle.buf[self.handle.index]);
16981703 const next_index = self.handle.index + linux_entry.d_reclen;
16991704 self.handle.index = next_index;
17001705
......@@ -1705,8 +1710,7 @@ pub const Dir = struct {
17051710 continue :start_over;
17061711 }
17071712
1708 const type_char = self.handle.buf[next_index - 1];
1709 const entry_kind = switch (type_char) {
1713 const entry_kind = switch (linux_entry.d_type) {
17101714 posix.DT_BLK => Entry.Kind.BlockDevice,
17111715 posix.DT_CHR => Entry.Kind.CharacterDevice,
17121716 posix.DT_DIR => Entry.Kind.Directory,
std/os/linux/arm64.zig created+465
......@@ -0,0 +1,465 @@
1const std = @import("../../index.zig");
2const linux = std.os.linux;
3const socklen_t = linux.socklen_t;
4const iovec = linux.iovec;
5
6pub const SYS_io_setup = 0;
7pub const SYS_io_destroy = 1;
8pub const SYS_io_submit = 2;
9pub const SYS_io_cancel = 3;
10pub const SYS_io_getevents = 4;
11pub const SYS_setxattr = 5;
12pub const SYS_lsetxattr = 6;
13pub const SYS_fsetxattr = 7;
14pub const SYS_getxattr = 8;
15pub const SYS_lgetxattr = 9;
16pub const SYS_fgetxattr = 10;
17pub const SYS_listxattr = 11;
18pub const SYS_llistxattr = 12;
19pub const SYS_flistxattr = 13;
20pub const SYS_removexattr = 14;
21pub const SYS_lremovexattr = 15;
22pub const SYS_fremovexattr = 16;
23pub const SYS_getcwd = 17;
24pub const SYS_lookup_dcookie = 18;
25pub const SYS_eventfd2 = 19;
26pub const SYS_epoll_create1 = 20;
27pub const SYS_epoll_ctl = 21;
28pub const SYS_epoll_pwait = 22;
29pub const SYS_dup = 23;
30pub const SYS_dup3 = 24;
31pub const SYS_fcntl = 25;
32pub const SYS_inotify_init1 = 26;
33pub const SYS_inotify_add_watch = 27;
34pub const SYS_inotify_rm_watch = 28;
35pub const SYS_ioctl = 29;
36pub const SYS_ioprio_set = 30;
37pub const SYS_ioprio_get = 31;
38pub const SYS_flock = 32;
39pub const SYS_mknodat = 33;
40pub const SYS_mkdirat = 34;
41pub const SYS_unlinkat = 35;
42pub const SYS_symlinkat = 36;
43pub const SYS_linkat = 37;
44pub const SYS_renameat = 38;
45pub const SYS_umount2 = 39;
46pub const SYS_mount = 40;
47pub const SYS_pivot_root = 41;
48pub const SYS_nfsservctl = 42;
49pub const SYS_statfs = 43;
50pub const SYS_fstatfs = 44;
51pub const SYS_truncate = 45;
52pub const SYS_ftruncate = 46;
53pub const SYS_fallocate = 47;
54pub const SYS_faccessat = 48;
55pub const SYS_chdir = 49;
56pub const SYS_fchdir = 50;
57pub const SYS_chroot = 51;
58pub const SYS_fchmod = 52;
59pub const SYS_fchmodat = 53;
60pub const SYS_fchownat = 54;
61pub const SYS_fchown = 55;
62pub const SYS_openat = 56;
63pub const SYS_close = 57;
64pub const SYS_vhangup = 58;
65pub const SYS_pipe2 = 59;
66pub const SYS_quotactl = 60;
67pub const SYS_getdents64 = 61;
68pub const SYS_lseek = 62;
69pub const SYS_read = 63;
70pub const SYS_write = 64;
71pub const SYS_readv = 65;
72pub const SYS_writev = 66;
73pub const SYS_pread64 = 67;
74pub const SYS_pwrite64 = 68;
75pub const SYS_preadv = 69;
76pub const SYS_pwritev = 70;
77pub const SYS_pselect6 = 72;
78pub const SYS_ppoll = 73;
79pub const SYS_signalfd4 = 74;
80pub const SYS_vmsplice = 75;
81pub const SYS_splice = 76;
82pub const SYS_tee = 77;
83pub const SYS_readlinkat = 78;
84pub const SYS_fstatat = 79;
85pub const SYS_fstat = 80;
86pub const SYS_sync = 81;
87pub const SYS_fsync = 82;
88pub const SYS_fdatasync = 83;
89pub const SYS_sync_file_range2 = 84;
90pub const SYS_sync_file_range = 84;
91pub const SYS_timerfd_create = 85;
92pub const SYS_timerfd_settime = 86;
93pub const SYS_timerfd_gettime = 87;
94pub const SYS_utimensat = 88;
95pub const SYS_acct = 89;
96pub const SYS_capget = 90;
97pub const SYS_capset = 91;
98pub const SYS_personality = 92;
99pub const SYS_exit = 93;
100pub const SYS_exit_group = 94;
101pub const SYS_waitid = 95;
102pub const SYS_set_tid_address = 96;
103pub const SYS_unshare = 97;
104pub const SYS_futex = 98;
105pub const SYS_set_robust_list = 99;
106pub const SYS_get_robust_list = 100;
107pub const SYS_nanosleep = 101;
108pub const SYS_getitimer = 102;
109pub const SYS_setitimer = 103;
110pub const SYS_kexec_load = 104;
111pub const SYS_init_module = 105;
112pub const SYS_delete_module = 106;
113pub const SYS_timer_create = 107;
114pub const SYS_timer_gettime = 108;
115pub const SYS_timer_getoverrun = 109;
116pub const SYS_timer_settime = 110;
117pub const SYS_timer_delete = 111;
118pub const SYS_clock_settime = 112;
119pub const SYS_clock_gettime = 113;
120pub const SYS_clock_getres = 114;
121pub const SYS_clock_nanosleep = 115;
122pub const SYS_syslog = 116;
123pub const SYS_ptrace = 117;
124pub const SYS_sched_setparam = 118;
125pub const SYS_sched_setscheduler = 119;
126pub const SYS_sched_getscheduler = 120;
127pub const SYS_sched_getparam = 121;
128pub const SYS_sched_setaffinity = 122;
129pub const SYS_sched_getaffinity = 123;
130pub const SYS_sched_yield = 124;
131pub const SYS_sched_get_priority_max = 125;
132pub const SYS_sched_get_priority_min = 126;
133pub const SYS_sched_rr_get_interval = 127;
134pub const SYS_restart_syscall = 128;
135pub const SYS_kill = 129;
136pub const SYS_tkill = 130;
137pub const SYS_tgkill = 131;
138pub const SYS_sigaltstack = 132;
139pub const SYS_rt_sigsuspend = 133;
140pub const SYS_rt_sigaction = 134;
141pub const SYS_rt_sigprocmask = 135;
142pub const SYS_rt_sigpending = 136;
143pub const SYS_rt_sigtimedwait = 137;
144pub const SYS_rt_sigqueueinfo = 138;
145pub const SYS_rt_sigreturn = 139;
146pub const SYS_setpriority = 140;
147pub const SYS_getpriority = 141;
148pub const SYS_reboot = 142;
149pub const SYS_setregid = 143;
150pub const SYS_setgid = 144;
151pub const SYS_setreuid = 145;
152pub const SYS_setuid = 146;
153pub const SYS_setresuid = 147;
154pub const SYS_getresuid = 148;
155pub const SYS_setresgid = 149;
156pub const SYS_getresgid = 150;
157pub const SYS_setfsuid = 151;
158pub const SYS_setfsgid = 152;
159pub const SYS_times = 153;
160pub const SYS_setpgid = 154;
161pub const SYS_getpgid = 155;
162pub const SYS_getsid = 156;
163pub const SYS_setsid = 157;
164pub const SYS_getgroups = 158;
165pub const SYS_setgroups = 159;
166pub const SYS_uname = 160;
167pub const SYS_sethostname = 161;
168pub const SYS_setdomainname = 162;
169pub const SYS_getrlimit = 163;
170pub const SYS_setrlimit = 164;
171pub const SYS_getrusage = 165;
172pub const SYS_umask = 166;
173pub const SYS_prctl = 167;
174pub const SYS_getcpu = 168;
175pub const SYS_gettimeofday = 169;
176pub const SYS_settimeofday = 170;
177pub const SYS_adjtimex = 171;
178pub const SYS_getpid = 172;
179pub const SYS_getppid = 173;
180pub const SYS_getuid = 174;
181pub const SYS_geteuid = 175;
182pub const SYS_getgid = 176;
183pub const SYS_getegid = 177;
184pub const SYS_gettid = 178;
185pub const SYS_sysinfo = 179;
186pub const SYS_mq_open = 180;
187pub const SYS_mq_unlink = 181;
188pub const SYS_mq_timedsend = 182;
189pub const SYS_mq_timedreceive = 183;
190pub const SYS_mq_notify = 184;
191pub const SYS_mq_getsetattr = 185;
192pub const SYS_msgget = 186;
193pub const SYS_msgctl = 187;
194pub const SYS_msgrcv = 188;
195pub const SYS_msgsnd = 189;
196pub const SYS_semget = 190;
197pub const SYS_semctl = 191;
198pub const SYS_semtimedop = 192;
199pub const SYS_semop = 193;
200pub const SYS_shmget = 194;
201pub const SYS_shmctl = 195;
202pub const SYS_shmat = 196;
203pub const SYS_shmdt = 197;
204pub const SYS_socket = 198;
205pub const SYS_socketpair = 199;
206pub const SYS_bind = 200;
207pub const SYS_listen = 201;
208pub const SYS_accept = 202;
209pub const SYS_connect = 203;
210pub const SYS_getsockname = 204;
211pub const SYS_getpeername = 205;
212pub const SYS_sendto = 206;
213pub const SYS_recvfrom = 207;
214pub const SYS_setsockopt = 208;
215pub const SYS_getsockopt = 209;
216pub const SYS_shutdown = 210;
217pub const SYS_sendmsg = 211;
218pub const SYS_recvmsg = 212;
219pub const SYS_readahead = 213;
220pub const SYS_brk = 214;
221pub const SYS_munmap = 215;
222pub const SYS_mremap = 216;
223pub const SYS_add_key = 217;
224pub const SYS_request_key = 218;
225pub const SYS_keyctl = 219;
226pub const SYS_clone = 220;
227pub const SYS_execve = 221;
228pub const SYS_mmap = 222;
229pub const SYS_fadvise64 = 223;
230pub const SYS_swapon = 224;
231pub const SYS_swapoff = 225;
232pub const SYS_mprotect = 226;
233pub const SYS_msync = 227;
234pub const SYS_mlock = 228;
235pub const SYS_munlock = 229;
236pub const SYS_mlockall = 230;
237pub const SYS_munlockall = 231;
238pub const SYS_mincore = 232;
239pub const SYS_madvise = 233;
240pub const SYS_remap_file_pages = 234;
241pub const SYS_mbind = 235;
242pub const SYS_get_mempolicy = 236;
243pub const SYS_set_mempolicy = 237;
244pub const SYS_migrate_pages = 238;
245pub const SYS_move_pages = 239;
246pub const SYS_rt_tgsigqueueinfo = 240;
247pub const SYS_perf_event_open = 241;
248pub const SYS_accept4 = 242;
249pub const SYS_recvmmsg = 243;
250pub const SYS_arch_specific_syscall = 244;
251pub const SYS_wait4 = 260;
252pub const SYS_prlimit64 = 261;
253pub const SYS_fanotify_init = 262;
254pub const SYS_fanotify_mark = 263;
255pub const SYS_clock_adjtime = 266;
256pub const SYS_syncfs = 267;
257pub const SYS_setns = 268;
258pub const SYS_sendmmsg = 269;
259pub const SYS_process_vm_readv = 270;
260pub const SYS_process_vm_writev = 271;
261pub const SYS_kcmp = 272;
262pub const SYS_finit_module = 273;
263pub const SYS_sched_setattr = 274;
264pub const SYS_sched_getattr = 275;
265pub const SYS_renameat2 = 276;
266pub const SYS_seccomp = 277;
267pub const SYS_getrandom = 278;
268pub const SYS_memfd_create = 279;
269pub const SYS_bpf = 280;
270pub const SYS_execveat = 281;
271pub const SYS_userfaultfd = 282;
272pub const SYS_membarrier = 283;
273pub const SYS_mlock2 = 284;
274pub const SYS_copy_file_range = 285;
275pub const SYS_preadv2 = 286;
276pub const SYS_pwritev2 = 287;
277pub const SYS_pkey_mprotect = 288;
278pub const SYS_pkey_alloc = 289;
279pub const SYS_pkey_free = 290;
280pub const SYS_statx = 291;
281pub const SYS_io_pgetevents = 292;
282pub const SYS_syscalls = 293;
283
284pub const O_CREAT = 0o100;
285pub const O_EXCL = 0o200;
286pub const O_NOCTTY = 0o400;
287pub const O_TRUNC = 0o1000;
288pub const O_APPEND = 0o2000;
289pub const O_NONBLOCK = 0o4000;
290pub const O_DSYNC = 0o10000;
291pub const O_SYNC = 0o4010000;
292pub const O_RSYNC = 0o4010000;
293pub const O_DIRECTORY = 0o200000;
294pub const O_NOFOLLOW = 0o400000;
295pub const O_CLOEXEC = 0o2000000;
296
297pub const O_ASYNC = 0o20000;
298pub const O_DIRECT = 0o40000;
299pub const O_LARGEFILE = 0;
300pub const O_NOATIME = 0o1000000;
301pub const O_PATH = 0o10000000;
302pub const O_TMPFILE = 0o20200000;
303pub const O_NDELAY = O_NONBLOCK;
304
305pub const F_DUPFD = 0;
306pub const F_GETFD = 1;
307pub const F_SETFD = 2;
308pub const F_GETFL = 3;
309pub const F_SETFL = 4;
310
311pub const F_SETOWN = 8;
312pub const F_GETOWN = 9;
313pub const F_SETSIG = 10;
314pub const F_GETSIG = 11;
315
316pub const F_GETLK = 5;
317pub const F_SETLK = 6;
318pub const F_SETLKW = 7;
319
320pub const F_SETOWN_EX = 15;
321pub const F_GETOWN_EX = 16;
322
323pub const F_GETOWNER_UIDS = 17;
324
325pub const AT_FDCWD = -100;
326pub const AT_SYMLINK_NOFOLLOW = 0x100;
327pub const AT_REMOVEDIR = 0x200;
328pub const AT_SYMLINK_FOLLOW = 0x400;
329pub const AT_NO_AUTOMOUNT = 0x800;
330pub const AT_EMPTY_PATH = 0x1000;
331
332pub const VDSO_USEFUL = true;
333pub const VDSO_CGT_SYM = "__kernel_clock_gettime";
334pub const VDSO_CGT_VER = "LINUX_2.6.39";
335
336pub fn syscall0(number: usize) usize {
337 return asm volatile ("svc #0"
338 : [ret] "={x0}" (-> usize)
339 : [number] "{x8}" (number)
340 );
341}
342
343pub fn syscall1(number: usize, arg1: usize) usize {
344 return asm volatile ("svc #0"
345 : [ret] "={x0}" (-> usize)
346 : [number] "{x8}" (number),
347 [arg1] "{x0}" (arg1)
348 );
349}
350
351pub fn syscall2(number: usize, arg1: usize, arg2: usize) usize {
352 return asm volatile ("svc #0"
353 : [ret] "={x0}" (-> usize)
354 : [number] "{x8}" (number),
355 [arg1] "{x0}" (arg1),
356 [arg2] "{x1}" (arg2)
357 );
358}
359
360pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
361 return asm volatile ("svc #0"
362 : [ret] "={x0}" (-> usize)
363 : [number] "{x8}" (number),
364 [arg1] "{x0}" (arg1),
365 [arg2] "{x1}" (arg2),
366 [arg3] "{x2}" (arg3)
367 );
368}
369
370pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
371 return asm volatile ("svc #0"
372 : [ret] "={x0}" (-> usize)
373 : [number] "{x8}" (number),
374 [arg1] "{x0}" (arg1),
375 [arg2] "{x1}" (arg2),
376 [arg3] "{x2}" (arg3),
377 [arg4] "{x3}" (arg4)
378 );
379}
380
381pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
382 return asm volatile ("svc #0"
383 : [ret] "={x0}" (-> usize)
384 : [number] "{x8}" (number),
385 [arg1] "{x0}" (arg1),
386 [arg2] "{x1}" (arg2),
387 [arg3] "{x2}" (arg3),
388 [arg4] "{x3}" (arg4),
389 [arg5] "{x4}" (arg5)
390 );
391}
392
393pub fn syscall6(
394 number: usize,
395 arg1: usize,
396 arg2: usize,
397 arg3: usize,
398 arg4: usize,
399 arg5: usize,
400 arg6: usize,
401) usize {
402 return asm volatile ("svc #0"
403 : [ret] "={x0}" (-> usize)
404 : [number] "{x8}" (number),
405 [arg1] "{x0}" (arg1),
406 [arg2] "{x1}" (arg2),
407 [arg3] "{x2}" (arg3),
408 [arg4] "{x3}" (arg4),
409 [arg5] "{x4}" (arg5),
410 [arg6] "{x5}" (arg6)
411 );
412}
413
414/// This matches the libc clone function.
415pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
416
417pub const msghdr = extern struct {
418 msg_name: *u8,
419 msg_namelen: socklen_t,
420 msg_iov: *iovec,
421 msg_iovlen: i32,
422 __pad1: i32,
423 msg_control: *u8,
424 msg_controllen: socklen_t,
425 __pad2: socklen_t,
426 msg_flags: i32,
427};
428
429/// Renamed to Stat to not conflict with the stat function.
430pub const Stat = extern struct {
431 dev: u64,
432 ino: u64,
433 nlink: usize,
434
435 mode: u32,
436 uid: u32,
437 gid: u32,
438 __pad0: u32,
439 rdev: u64,
440 size: i64,
441 blksize: isize,
442 blocks: i64,
443
444 atim: timespec,
445 mtim: timespec,
446 ctim: timespec,
447 __unused: [3]isize,
448};
449
450pub const timespec = extern struct {
451 tv_sec: isize,
452 tv_nsec: isize,
453};
454
455pub const timeval = extern struct {
456 tv_sec: isize,
457 tv_usec: isize,
458};
459
460pub const timezone = extern struct {
461 tz_minuteswest: i32,
462 tz_dsttime: i32,
463};
464
465pub const Elf_Symndx = u32;
std/os/linux/index.zig+82-23
......@@ -5,6 +5,7 @@ const vdso = @import("vdso.zig");
55pub use switch (builtin.arch) {
66 builtin.Arch.x86_64 => @import("x86_64.zig"),
77 builtin.Arch.i386 => @import("i386.zig"),
8 builtin.Arch.aarch64v8 => @import("arm64.zig"),
89 else => @compileError("unsupported arch"),
910};
1011pub use @import("errno.zig");
......@@ -697,7 +698,11 @@ pub fn getErrno(r: usize) usize {
697698}
698699
699700pub fn dup2(old: i32, new: i32) usize {
700 return syscall2(SYS_dup2, @intCast(usize, old), @intCast(usize, new));
701 return dup3(old, new, 0);
702}
703
704pub fn dup3(old: i32, new: i32, flags: u32) usize {
705 return syscall3(SYS_dup3, @intCast(usize, old), @intCast(usize, new), flags);
701706}
702707
703708// TODO https://github.com/ziglang/zig/issues/265
......@@ -716,7 +721,7 @@ pub fn execve(path: [*]const u8, argv: [*]const ?[*]const u8, envp: [*]const ?[*
716721}
717722
718723pub fn fork() usize {
719 return syscall0(SYS_fork);
724 return clone2(SIGCHLD, 0);
720725}
721726
722727/// This must be inline, and inline call the syscall function, because if the
......@@ -740,8 +745,8 @@ pub fn getcwd(buf: [*]u8, size: usize) usize {
740745 return syscall2(SYS_getcwd, @ptrToInt(buf), size);
741746}
742747
743pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize {
744 return syscall3(SYS_getdents, @intCast(usize, fd), @ptrToInt(dirp), count);
748pub fn getdents64(fd: i32, dirp: [*]u8, count: usize) usize {
749 return syscall3(SYS_getdents64, @intCast(usize, fd), @ptrToInt(dirp), count);
745750}
746751
747752pub fn inotify_init1(flags: u32) usize {
......@@ -763,16 +768,26 @@ pub fn isatty(fd: i32) bool {
763768
764769// TODO https://github.com/ziglang/zig/issues/265
765770pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize {
766 return syscall3(SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
771 return readlinkat(AT_FDCWD, path, buf_ptr, buf_len);
772}
773
774// TODO https://github.com/ziglang/zig/issues/265
775pub fn readlinkat(dirfd: i32, noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize {
776 return syscall4(SYS_readlinkat, @intCast(usize, dirfd), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
767777}
768778
769779// TODO https://github.com/ziglang/zig/issues/265
770780pub fn mkdir(path: [*]const u8, mode: u32) usize {
771 return syscall2(SYS_mkdir, @ptrToInt(path), mode);
781 return mkdirat(AT_FDCWD, path, mode);
782}
783
784// TODO https://github.com/ziglang/zig/issues/265
785pub fn mkdirat(dirfd: i32, path: [*]const u8, mode: u32) usize {
786 return syscall3(SYS_mkdirat, @intCast(usize, dirfd), @ptrToInt(path), mode);
772787}
773788
774789// TODO https://github.com/ziglang/zig/issues/265
775pub fn mount(special: [*]const u8, dir: [*]const u8, fstype: [*]const u8, flags: usize, data: usize) usize {
790pub fn mount(special: [*]const u8, dir: [*]const u8, fstype: [*]const u8, flags: u32, data: usize) usize {
776791 return syscall5(SYS_mount, @ptrToInt(special), @ptrToInt(dir), @ptrToInt(fstype), flags, data);
777792}
778793
......@@ -816,28 +831,38 @@ pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) us
816831
817832// TODO https://github.com/ziglang/zig/issues/265
818833pub fn rmdir(path: [*]const u8) usize {
819 return syscall1(SYS_rmdir, @ptrToInt(path));
834 return unlinkat(AT_FDCWD, path, AT_REMOVEDIR);
820835}
821836
822837// TODO https://github.com/ziglang/zig/issues/265
823838pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {
824 return syscall2(SYS_symlink, @ptrToInt(existing), @ptrToInt(new));
839 return symlinkat(existing, AT_FDCWD, new);
840}
841
842// TODO https://github.com/ziglang/zig/issues/265
843pub fn symlinkat(existing: [*]const u8, newfd: i32, newpath: [*]const u8) usize {
844 return syscall3(SYS_symlinkat, @ptrToInt(existing), @intCast(usize, newfd), @ptrToInt(newpath));
825845}
826846
847// TODO https://github.com/ziglang/zig/issues/265
827848pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {
828849 return syscall4(SYS_pread, @intCast(usize, fd), @ptrToInt(buf), count, offset);
829850}
830851
831852// TODO https://github.com/ziglang/zig/issues/265
832853pub fn access(path: [*]const u8, mode: u32) usize {
833 return syscall2(SYS_access, @ptrToInt(path), mode);
854 return faccessat(AT_FDCWD, path, mode);
855}
856
857pub fn faccessat(dirfd: i32, path: [*]const u8, mode: u32) usize {
858 return syscall3(SYS_faccessat, @intCast(usize, dirfd), @ptrToInt(path), mode);
834859}
835860
836861pub fn pipe(fd: *[2]i32) usize {
837862 return pipe2(fd, 0);
838863}
839864
840pub fn pipe2(fd: *[2]i32, flags: usize) usize {
865pub fn pipe2(fd: *[2]i32, flags: u32) usize {
841866 return syscall2(SYS_pipe2, @ptrToInt(fd), flags);
842867}
843868
......@@ -851,12 +876,17 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {
851876
852877// TODO https://github.com/ziglang/zig/issues/265
853878pub fn rename(old: [*]const u8, new: [*]const u8) usize {
854 return syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new));
879 return renameat2(AT_FDCWD, old, AT_FDCWD, new, 0);
880}
881
882// TODO https://github.com/ziglang/zig/issues/265
883pub fn renameat2(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const u8, flags: u32) usize {
884 return syscall5(SYS_renameat2, @intCast(usize, oldfd), @ptrToInt(oldpath), @intCast(usize, newfd), @ptrToInt(newpath), flags);
855885}
856886
857887// TODO https://github.com/ziglang/zig/issues/265
858888pub fn open(path: [*]const u8, flags: u32, perm: usize) usize {
859 return syscall3(SYS_open, @ptrToInt(path), flags, perm);
889 return openat(AT_FDCWD, path, flags, perm);
860890}
861891
862892// TODO https://github.com/ziglang/zig/issues/265
......@@ -865,7 +895,7 @@ pub fn create(path: [*]const u8, perm: usize) usize {
865895}
866896
867897// TODO https://github.com/ziglang/zig/issues/265
868pub fn openat(dirfd: i32, path: [*]const u8, flags: usize, mode: usize) usize {
898pub fn openat(dirfd: i32, path: [*]const u8, flags: u32, mode: usize) usize {
869899 return syscall4(SYS_openat, @intCast(usize, dirfd), @ptrToInt(path), flags, mode);
870900}
871901
......@@ -875,7 +905,7 @@ pub fn clone5(flags: usize, child_stack_ptr: usize, parent_tid: *i32, child_tid:
875905}
876906
877907/// See also `clone` (from the arch-specific include)
878pub fn clone2(flags: usize, child_stack_ptr: usize) usize {
908pub fn clone2(flags: u32, child_stack_ptr: usize) usize {
879909 return syscall2(SYS_clone, flags, child_stack_ptr);
880910}
881911
......@@ -898,7 +928,7 @@ pub fn exit_group(status: i32) noreturn {
898928}
899929
900930pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize {
901 return syscall3(SYS_getrandom, @ptrToInt(buf), count, @intCast(usize, flags));
931 return syscall3(SYS_getrandom, @ptrToInt(buf), count, flags);
902932}
903933
904934pub fn kill(pid: i32, sig: i32) usize {
......@@ -907,7 +937,12 @@ pub fn kill(pid: i32, sig: i32) usize {
907937
908938// TODO https://github.com/ziglang/zig/issues/265
909939pub fn unlink(path: [*]const u8) usize {
910 return syscall1(SYS_unlink, @ptrToInt(path));
940 return unlinkat(AT_FDCWD, path, 0);
941}
942
943// TODO https://github.com/ziglang/zig/issues/265
944pub fn unlinkat(dirfd: i32, path: [*]const u8, flags: u32) usize {
945 return syscall3(SYS_unlinkat, @intCast(usize, dirfd), @ptrToInt(path), flags);
911946}
912947
913948pub fn waitpid(pid: i32, status: *i32, options: i32) usize {
......@@ -1222,12 +1257,17 @@ pub fn fstat(fd: i32, stat_buf: *Stat) usize {
12221257
12231258// TODO https://github.com/ziglang/zig/issues/265
12241259pub fn stat(pathname: [*]const u8, statbuf: *Stat) usize {
1225 return syscall2(SYS_stat, @ptrToInt(pathname), @ptrToInt(statbuf));
1260 return fstatat(AT_FDCWD, pathname, statbuf, AT_NO_AUTOMOUNT);
12261261}
12271262
12281263// TODO https://github.com/ziglang/zig/issues/265
12291264pub fn lstat(pathname: [*]const u8, statbuf: *Stat) usize {
1230 return syscall2(SYS_lstat, @ptrToInt(pathname), @ptrToInt(statbuf));
1265 return fstatat(AF_FDCWD, pathname, statbuf, AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT);
1266}
1267
1268// TODO https://github.com/ziglang/zig/issues/265
1269pub fn fstatat(dirfd: i32, path: [*]const u8, stat_buf: *Stat, flags: u32) usize {
1270 return syscall4(SYS_fstatat, @intCast(usize, dirfd), @ptrToInt(path), @ptrToInt(stat_buf), flags);
12311271}
12321272
12331273// TODO https://github.com/ziglang/zig/issues/265
......@@ -1318,7 +1358,18 @@ pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: *epoll_event) usize {
13181358}
13191359
13201360pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize {
1321 return syscall4(SYS_epoll_wait, @intCast(usize, epoll_fd), @ptrToInt(events), @intCast(usize, maxevents), @intCast(usize, timeout));
1361 return epoll_pwait(epoll_fd, events, maxevents, timeout, null);
1362}
1363
1364pub fn epoll_pwait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32, sigmask: ?*sigset_t) usize {
1365 return syscall6(SYS_epoll_pwait,
1366 @intCast(usize, epoll_fd),
1367 @ptrToInt(events),
1368 @intCast(usize, maxevents),
1369 @intCast(usize, timeout),
1370 @ptrToInt(sigmask),
1371 @sizeOf(sigset_t)
1372 );
13221373}
13231374
13241375pub fn eventfd(count: u32, flags: u32) usize {
......@@ -1326,7 +1377,7 @@ pub fn eventfd(count: u32, flags: u32) usize {
13261377}
13271378
13281379pub fn timerfd_create(clockid: i32, flags: u32) usize {
1329 return syscall2(SYS_timerfd_create, @intCast(usize, clockid), @intCast(usize, flags));
1380 return syscall2(SYS_timerfd_create, @intCast(usize, clockid), flags);
13301381}
13311382
13321383pub const itimerspec = extern struct {
......@@ -1339,7 +1390,7 @@ pub fn timerfd_gettime(fd: i32, curr_value: *itimerspec) usize {
13391390}
13401391
13411392pub fn timerfd_settime(fd: i32, flags: u32, new_value: *const itimerspec, old_value: ?*itimerspec) usize {
1342 return syscall4(SYS_timerfd_settime, @intCast(usize, fd), @intCast(usize, flags), @ptrToInt(new_value), @ptrToInt(old_value));
1393 return syscall4(SYS_timerfd_settime, @intCast(usize, fd), flags, @ptrToInt(new_value), @ptrToInt(old_value));
13431394}
13441395
13451396pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330;
......@@ -1449,7 +1500,7 @@ pub const cap_user_data_t = extern struct {
14491500};
14501501
14511502pub fn unshare(flags: usize) usize {
1452 return syscall1(SYS_unshare, @intCast(usize, flags));
1503 return syscall1(SYS_unshare, flags);
14531504}
14541505
14551506pub fn capget(hdrp: *cap_user_header_t, datap: *cap_user_data_t) usize {
......@@ -1468,6 +1519,14 @@ pub const inotify_event = extern struct {
14681519 //name: [?]u8,
14691520};
14701521
1522pub const dirent64 = extern struct {
1523 d_ino: u64,
1524 d_off: u64,
1525 d_reclen: u16,
1526 d_type: u8,
1527 d_name: u8, // field address is the address of first byte of name https://github.com/ziglang/zig/issues/173
1528};
1529
14711530test "import" {
14721531 if (builtin.os == builtin.Os.linux) {
14731532 _ = @import("test.zig");
std/os/linux/vdso.zig+1-1
......@@ -5,7 +5,7 @@ const cstr = std.cstr;
55const mem = std.mem;
66
77pub fn lookup(vername: []const u8, name: []const u8) usize {
8 const vdso_addr = std.os.linux_aux_raw[std.elf.AT_SYSINFO_EHDR];
8 const vdso_addr = std.os.linuxGetAuxVal(std.elf.AT_SYSINFO_EHDR);
99 if (vdso_addr == 0) return 0;
1010
1111 const eh = @intToPtr(*elf.Ehdr, vdso_addr);
std/os/linux/x86_64.zig+9-7
......@@ -266,6 +266,8 @@ pub const SYS_mknodat = 259;
266266pub const SYS_fchownat = 260;
267267pub const SYS_futimesat = 261;
268268pub const SYS_newfstatat = 262;
269// https://github.com/ziglang/zig/issues/1439
270pub const SYS_fstatat = 262;
269271pub const SYS_unlinkat = 263;
270272pub const SYS_renameat = 264;
271273pub const SYS_linkat = 265;
......@@ -371,6 +373,13 @@ pub const F_GETOWN_EX = 16;
371373
372374pub const F_GETOWNER_UIDS = 17;
373375
376pub const AT_FDCWD = -100;
377pub const AT_SYMLINK_NOFOLLOW = 0x100;
378pub const AT_REMOVEDIR = 0x200;
379pub const AT_SYMLINK_FOLLOW = 0x400;
380pub const AT_NO_AUTOMOUNT = 0x800;
381pub const AT_EMPTY_PATH = 0x1000;
382
374383pub const VDSO_USEFUL = true;
375384pub const VDSO_CGT_SYM = "__vdso_clock_gettime";
376385pub const VDSO_CGT_VER = "LINUX_2.6";
......@@ -521,11 +530,4 @@ pub const timezone = extern struct {
521530 tz_dsttime: i32,
522531};
523532
524pub const dirent = extern struct {
525 d_ino: usize,
526 d_off: usize,
527 d_reclen: u16,
528 d_name: u8, // field address is the address of first byte of name
529};
530
531533pub const Elf_Symndx = u32;
std/special/bootstrap.zig+7-5
......@@ -30,6 +30,11 @@ nakedcc fn _start() noreturn {
3030 : [argc] "=r" (-> [*]usize)
3131 );
3232 },
33 builtin.Arch.aarch64v8 => {
34 argc_ptr = asm ("mov %[argc], sp"
35 : [argc] "=r" (-> [*]usize)
36 );
37 },
3338 else => @compileError("unsupported arch"),
3439 }
3540 // If LLVM inlines stack variables into _start, they will overwrite
......@@ -54,11 +59,8 @@ fn posixCallMainAndExit() noreturn {
5459 const envp = @ptrCast([*][*]u8, envp_optional)[0..envp_count];
5560 if (builtin.os == builtin.Os.linux) {
5661 const auxv = @ptrCast([*]usize, envp.ptr + envp_count + 1);
57 var i: usize = 0;
58 while (auxv[i] != 0) : (i += 2) {
59 if (auxv[i] < std.os.linux_aux_raw.len) std.os.linux_aux_raw[auxv[i]] = auxv[i + 1];
60 }
61 std.debug.assert(std.os.linux_aux_raw[std.elf.AT_PAGESZ] == std.os.page_size);
62 std.os.linux_elf_aux_maybe = @ptrCast([*]std.elf.Auxv, auxv);
63 std.debug.assert(std.os.linuxGetAuxVal(std.elf.AT_PAGESZ) == std.os.page_size);
6264 }
6365
6466 std.os.posix.exit(callMainWithArgs(argc, argv, envp));
std/special/builtin.zig+59-27
......@@ -60,7 +60,7 @@ comptime {
6060 {
6161 @export("__stack_chk_fail", __stack_chk_fail, builtin.GlobalLinkage.Strong);
6262 }
63 if (builtin.os == builtin.Os.linux and builtin.arch == builtin.Arch.x86_64) {
63 if (builtin.os == builtin.Os.linux) {
6464 @export("clone", clone, builtin.GlobalLinkage.Strong);
6565 }
6666}
......@@ -72,32 +72,64 @@ extern fn __stack_chk_fail() noreturn {
7272// it causes a segfault in release mode. this is a workaround of calling it
7373// across .o file boundaries. fix comptime @ptrCast of nakedcc functions.
7474nakedcc fn clone() void {
75 asm volatile (
76 \\ xor %%eax,%%eax
77 \\ mov $56,%%al
78 \\ mov %%rdi,%%r11
79 \\ mov %%rdx,%%rdi
80 \\ mov %%r8,%%rdx
81 \\ mov %%r9,%%r8
82 \\ mov 8(%%rsp),%%r10
83 \\ mov %%r11,%%r9
84 \\ and $-16,%%rsi
85 \\ sub $8,%%rsi
86 \\ mov %%rcx,(%%rsi)
87 \\ syscall
88 \\ test %%eax,%%eax
89 \\ jnz 1f
90 \\ xor %%ebp,%%ebp
91 \\ pop %%rdi
92 \\ call *%%r9
93 \\ mov %%eax,%%edi
94 \\ xor %%eax,%%eax
95 \\ mov $60,%%al
96 \\ syscall
97 \\ hlt
98 \\1: ret
99 \\
100 );
75 if (builtin.arch == builtin.Arch.x86_64) {
76 asm volatile (
77 \\ xor %%eax,%%eax
78 \\ mov $56,%%al // SYS_clone
79 \\ mov %%rdi,%%r11
80 \\ mov %%rdx,%%rdi
81 \\ mov %%r8,%%rdx
82 \\ mov %%r9,%%r8
83 \\ mov 8(%%rsp),%%r10
84 \\ mov %%r11,%%r9
85 \\ and $-16,%%rsi
86 \\ sub $8,%%rsi
87 \\ mov %%rcx,(%%rsi)
88 \\ syscall
89 \\ test %%eax,%%eax
90 \\ jnz 1f
91 \\ xor %%ebp,%%ebp
92 \\ pop %%rdi
93 \\ call *%%r9
94 \\ mov %%eax,%%edi
95 \\ xor %%eax,%%eax
96 \\ mov $60,%%al // SYS_exit
97 \\ syscall
98 \\ hlt
99 \\1: ret
100 \\
101 );
102 } else if (builtin.arch == builtin.Arch.aarch64v8) {
103 // __clone(func, stack, flags, arg, ptid, tls, ctid)
104 // x0, x1, w2, x3, x4, x5, x6
105
106 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
107 // x8, x0, x1, x2, x3, x4
108 asm volatile (
109 \\ // align stack and save func,arg
110 \\ and x1,x1,#-16
111 \\ stp x0,x3,[x1,#-16]!
112 \\
113 \\ // syscall
114 \\ uxtw x0,w2
115 \\ mov x2,x4
116 \\ mov x3,x5
117 \\ mov x4,x6
118 \\ mov x8,#220 // SYS_clone
119 \\ svc #0
120 \\
121 \\ cbz x0,1f
122 \\ // parent
123 \\ ret
124 \\ // child
125 \\1: ldp x1,x0,[sp],#16
126 \\ blr x1
127 \\ mov x8,#93 // SYS_exit
128 \\ svc #0
129 );
130 } else {
131 @compileError("Implement clone() for this arch.");
132 }
101133}
102134
103135const math = @import("../math/index.zig");