authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-30 22:00:00-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-11-30 22:00:00-05:00
log951dc451d6d49fca499e9a722a3f543d6e8bf7c1
tree766ef5f8c68186d3622b00f2e5e9546214e4fc48
parent11b8d3ce9d7bc8e3ab16813fd5415c9d45dbb232
parentcdeafe777a2fe707674cb44e4aa7b5a1b8319ec5
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #3808 from LemonBoy/i386-for-ya

linux-i386 support

14 files changed, 940 insertions(+), 10 deletions(-)

lib/std/debug.zig+6
...@@ -2417,6 +2417,12 @@ extern fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *con...@@ -2417,6 +2417,12 @@ extern fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *con
2417 std.debug.warn("Segmentation fault at address 0x{x}\n", addr);2417 std.debug.warn("Segmentation fault at address 0x{x}\n", addr);
24182418
2419 switch (builtin.arch) {2419 switch (builtin.arch) {
2420 .i386 => {
2421 const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
2422 const ip = @intCast(usize, ctx.mcontext.gregs[os.REG_EIP]);
2423 const bp = @intCast(usize, ctx.mcontext.gregs[os.REG_EBP]);
2424 dumpStackTraceFromBase(bp, ip);
2425 },
2420 .x86_64 => {2426 .x86_64 => {
2421 const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));2427 const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
2422 const ip = @intCast(usize, ctx.mcontext.gregs[os.REG_RIP]);2428 const ip = @intCast(usize, ctx.mcontext.gregs[os.REG_RIP]);
lib/std/os/bits/linux.zig+1
...@@ -9,6 +9,7 @@ pub usingnamespace switch (builtin.arch) {...@@ -9,6 +9,7 @@ pub usingnamespace switch (builtin.arch) {
9};9};
1010
11pub usingnamespace switch (builtin.arch) {11pub usingnamespace switch (builtin.arch) {
12 .i386 => @import("linux/i386.zig"),
12 .x86_64 => @import("linux/x86_64.zig"),13 .x86_64 => @import("linux/x86_64.zig"),
13 .aarch64 => @import("linux/arm64.zig"),14 .aarch64 => @import("linux/arm64.zig"),
14 .arm => @import("linux/arm-eabi.zig"),15 .arm => @import("linux/arm-eabi.zig"),
lib/std/os/bits/linux/arm-eabi.zig-1
...@@ -466,7 +466,6 @@ pub const MAP_LOCKED = 0x2000;...@@ -466,7 +466,6 @@ pub const MAP_LOCKED = 0x2000;
466/// don't check for reservations466/// don't check for reservations
467pub const MAP_NORESERVE = 0x4000;467pub const MAP_NORESERVE = 0x4000;
468468
469pub const VDSO_USEFUL = true;
470pub const VDSO_CGT_SYM = "__vdso_clock_gettime";469pub const VDSO_CGT_SYM = "__vdso_clock_gettime";
471pub const VDSO_CGT_VER = "LINUX_2.6";470pub const VDSO_CGT_VER = "LINUX_2.6";
472471
lib/std/os/bits/linux/arm64.zig-1
...@@ -358,7 +358,6 @@ pub const MAP_LOCKED = 0x2000;...@@ -358,7 +358,6 @@ pub const MAP_LOCKED = 0x2000;
358/// don't check for reservations358/// don't check for reservations
359pub const MAP_NORESERVE = 0x4000;359pub const MAP_NORESERVE = 0x4000;
360360
361pub const VDSO_USEFUL = true;
362pub const VDSO_CGT_SYM = "__kernel_clock_gettime";361pub const VDSO_CGT_SYM = "__kernel_clock_gettime";
363pub const VDSO_CGT_VER = "LINUX_2.6.39";362pub const VDSO_CGT_VER = "LINUX_2.6.39";
364363
lib/std/os/bits/linux/i386.zig created+642
...@@ -0,0 +1,642 @@
1// i386-specific declarations that are intended to be imported into the POSIX namespace.
2// This does include Linux-only APIs.
3
4const std = @import("../../../std.zig");
5const linux = std.os.linux;
6const socklen_t = linux.socklen_t;
7const iovec = linux.iovec;
8const iovec_const = linux.iovec_const;
9const uid_t = linux.uid_t;
10const gid_t = linux.gid_t;
11const stack_t = linux.stack_t;
12const sigset_t = linux.sigset_t;
13
14pub const SYS_restart_syscall = 0;
15pub const SYS_exit = 1;
16pub const SYS_fork = 2;
17pub const SYS_read = 3;
18pub const SYS_write = 4;
19pub const SYS_open = 5;
20pub const SYS_close = 6;
21pub const SYS_waitpid = 7;
22pub const SYS_creat = 8;
23pub const SYS_link = 9;
24pub const SYS_unlink = 10;
25pub const SYS_execve = 11;
26pub const SYS_chdir = 12;
27pub const SYS_time = 13;
28pub const SYS_mknod = 14;
29pub const SYS_chmod = 15;
30pub const SYS_lchown = 16;
31pub const SYS_break = 17;
32pub const SYS_oldstat = 18;
33pub const SYS_lseek = 19;
34pub const SYS_getpid = 20;
35pub const SYS_mount = 21;
36pub const SYS_umount = 22;
37pub const SYS_setuid = 23;
38pub const SYS_getuid = 24;
39pub const SYS_stime = 25;
40pub const SYS_ptrace = 26;
41pub const SYS_alarm = 27;
42pub const SYS_oldfstat = 28;
43pub const SYS_pause = 29;
44pub const SYS_utime = 30;
45pub const SYS_stty = 31;
46pub const SYS_gtty = 32;
47pub const SYS_access = 33;
48pub const SYS_nice = 34;
49pub const SYS_ftime = 35;
50pub const SYS_sync = 36;
51pub const SYS_kill = 37;
52pub const SYS_rename = 38;
53pub const SYS_mkdir = 39;
54pub const SYS_rmdir = 40;
55pub const SYS_dup = 41;
56pub const SYS_pipe = 42;
57pub const SYS_times = 43;
58pub const SYS_prof = 44;
59pub const SYS_brk = 45;
60pub const SYS_setgid = 46;
61pub const SYS_getgid = 47;
62pub const SYS_signal = 48;
63pub const SYS_geteuid = 49;
64pub const SYS_getegid = 50;
65pub const SYS_acct = 51;
66pub const SYS_umount2 = 52;
67pub const SYS_lock = 53;
68pub const SYS_ioctl = 54;
69pub const SYS_fcntl = 55;
70pub const SYS_mpx = 56;
71pub const SYS_setpgid = 57;
72pub const SYS_ulimit = 58;
73pub const SYS_oldolduname = 59;
74pub const SYS_umask = 60;
75pub const SYS_chroot = 61;
76pub const SYS_ustat = 62;
77pub const SYS_dup2 = 63;
78pub const SYS_getppid = 64;
79pub const SYS_getpgrp = 65;
80pub const SYS_setsid = 66;
81pub const SYS_sigaction = 67;
82pub const SYS_sgetmask = 68;
83pub const SYS_ssetmask = 69;
84pub const SYS_setreuid = 70;
85pub const SYS_setregid = 71;
86pub const SYS_sigsuspend = 72;
87pub const SYS_sigpending = 73;
88pub const SYS_sethostname = 74;
89pub const SYS_setrlimit = 75;
90pub const SYS_getrlimit = 76;
91pub const SYS_getrusage = 77;
92pub const SYS_gettimeofday = 78;
93pub const SYS_settimeofday = 79;
94pub const SYS_getgroups = 80;
95pub const SYS_setgroups = 81;
96pub const SYS_select = 82;
97pub const SYS_symlink = 83;
98pub const SYS_oldlstat = 84;
99pub const SYS_readlink = 85;
100pub const SYS_uselib = 86;
101pub const SYS_swapon = 87;
102pub const SYS_reboot = 88;
103pub const SYS_readdir = 89;
104pub const SYS_mmap = 90;
105pub const SYS_munmap = 91;
106pub const SYS_truncate = 92;
107pub const SYS_ftruncate = 93;
108pub const SYS_fchmod = 94;
109pub const SYS_fchown = 95;
110pub const SYS_getpriority = 96;
111pub const SYS_setpriority = 97;
112pub const SYS_profil = 98;
113pub const SYS_statfs = 99;
114pub const SYS_fstatfs = 100;
115pub const SYS_ioperm = 101;
116pub const SYS_socketcall = 102;
117pub const SYS_syslog = 103;
118pub const SYS_setitimer = 104;
119pub const SYS_getitimer = 105;
120pub const SYS_stat = 106;
121pub const SYS_lstat = 107;
122pub const SYS_fstat = 108;
123pub const SYS_olduname = 109;
124pub const SYS_iopl = 110;
125pub const SYS_vhangup = 111;
126pub const SYS_idle = 112;
127pub const SYS_vm86old = 113;
128pub const SYS_wait4 = 114;
129pub const SYS_swapoff = 115;
130pub const SYS_sysinfo = 116;
131pub const SYS_ipc = 117;
132pub const SYS_fsync = 118;
133pub const SYS_sigreturn = 119;
134pub const SYS_clone = 120;
135pub const SYS_setdomainname = 121;
136pub const SYS_uname = 122;
137pub const SYS_modify_ldt = 123;
138pub const SYS_adjtimex = 124;
139pub const SYS_mprotect = 125;
140pub const SYS_sigprocmask = 126;
141pub const SYS_create_module = 127;
142pub const SYS_init_module = 128;
143pub const SYS_delete_module = 129;
144pub const SYS_get_kernel_syms = 130;
145pub const SYS_quotactl = 131;
146pub const SYS_getpgid = 132;
147pub const SYS_fchdir = 133;
148pub const SYS_bdflush = 134;
149pub const SYS_sysfs = 135;
150pub const SYS_personality = 136;
151pub const SYS_afs_syscall = 137;
152pub const SYS_setfsuid = 138;
153pub const SYS_setfsgid = 139;
154pub const SYS__llseek = 140;
155pub const SYS_getdents = 141;
156pub const SYS__newselect = 142;
157pub const SYS_flock = 143;
158pub const SYS_msync = 144;
159pub const SYS_readv = 145;
160pub const SYS_writev = 146;
161pub const SYS_getsid = 147;
162pub const SYS_fdatasync = 148;
163pub const SYS__sysctl = 149;
164pub const SYS_mlock = 150;
165pub const SYS_munlock = 151;
166pub const SYS_mlockall = 152;
167pub const SYS_munlockall = 153;
168pub const SYS_sched_setparam = 154;
169pub const SYS_sched_getparam = 155;
170pub const SYS_sched_setscheduler = 156;
171pub const SYS_sched_getscheduler = 157;
172pub const SYS_sched_yield = 158;
173pub const SYS_sched_get_priority_max = 159;
174pub const SYS_sched_get_priority_min = 160;
175pub const SYS_sched_rr_get_interval = 161;
176pub const SYS_nanosleep = 162;
177pub const SYS_mremap = 163;
178pub const SYS_setresuid = 164;
179pub const SYS_getresuid = 165;
180pub const SYS_vm86 = 166;
181pub const SYS_query_module = 167;
182pub const SYS_poll = 168;
183pub const SYS_nfsservctl = 169;
184pub const SYS_setresgid = 170;
185pub const SYS_getresgid = 171;
186pub const SYS_prctl = 172;
187pub const SYS_rt_sigreturn = 173;
188pub const SYS_rt_sigaction = 174;
189pub const SYS_rt_sigprocmask = 175;
190pub const SYS_rt_sigpending = 176;
191pub const SYS_rt_sigtimedwait = 177;
192pub const SYS_rt_sigqueueinfo = 178;
193pub const SYS_rt_sigsuspend = 179;
194pub const SYS_pread64 = 180;
195pub const SYS_pwrite64 = 181;
196pub const SYS_chown = 182;
197pub const SYS_getcwd = 183;
198pub const SYS_capget = 184;
199pub const SYS_capset = 185;
200pub const SYS_sigaltstack = 186;
201pub const SYS_sendfile = 187;
202pub const SYS_getpmsg = 188;
203pub const SYS_putpmsg = 189;
204pub const SYS_vfork = 190;
205pub const SYS_ugetrlimit = 191;
206pub const SYS_mmap2 = 192;
207pub const SYS_truncate64 = 193;
208pub const SYS_ftruncate64 = 194;
209pub const SYS_stat64 = 195;
210pub const SYS_lstat64 = 196;
211pub const SYS_fstat64 = 197;
212pub const SYS_lchown32 = 198;
213pub const SYS_getuid32 = 199;
214pub const SYS_getgid32 = 200;
215pub const SYS_geteuid32 = 201;
216pub const SYS_getegid32 = 202;
217pub const SYS_setreuid32 = 203;
218pub const SYS_setregid32 = 204;
219pub const SYS_getgroups32 = 205;
220pub const SYS_setgroups32 = 206;
221pub const SYS_fchown32 = 207;
222pub const SYS_setresuid32 = 208;
223pub const SYS_getresuid32 = 209;
224pub const SYS_setresgid32 = 210;
225pub const SYS_getresgid32 = 211;
226pub const SYS_chown32 = 212;
227pub const SYS_setuid32 = 213;
228pub const SYS_setgid32 = 214;
229pub const SYS_setfsuid32 = 215;
230pub const SYS_setfsgid32 = 216;
231pub const SYS_pivot_root = 217;
232pub const SYS_mincore = 218;
233pub const SYS_madvise = 219;
234pub const SYS_getdents64 = 220;
235pub const SYS_fcntl64 = 221;
236pub const SYS_gettid = 224;
237pub const SYS_readahead = 225;
238pub const SYS_setxattr = 226;
239pub const SYS_lsetxattr = 227;
240pub const SYS_fsetxattr = 228;
241pub const SYS_getxattr = 229;
242pub const SYS_lgetxattr = 230;
243pub const SYS_fgetxattr = 231;
244pub const SYS_listxattr = 232;
245pub const SYS_llistxattr = 233;
246pub const SYS_flistxattr = 234;
247pub const SYS_removexattr = 235;
248pub const SYS_lremovexattr = 236;
249pub const SYS_fremovexattr = 237;
250pub const SYS_tkill = 238;
251pub const SYS_sendfile64 = 239;
252pub const SYS_futex = 240;
253pub const SYS_sched_setaffinity = 241;
254pub const SYS_sched_getaffinity = 242;
255pub const SYS_set_thread_area = 243;
256pub const SYS_get_thread_area = 244;
257pub const SYS_io_setup = 245;
258pub const SYS_io_destroy = 246;
259pub const SYS_io_getevents = 247;
260pub const SYS_io_submit = 248;
261pub const SYS_io_cancel = 249;
262pub const SYS_fadvise64 = 250;
263pub const SYS_exit_group = 252;
264pub const SYS_lookup_dcookie = 253;
265pub const SYS_epoll_create = 254;
266pub const SYS_epoll_ctl = 255;
267pub const SYS_epoll_wait = 256;
268pub const SYS_remap_file_pages = 257;
269pub const SYS_set_tid_address = 258;
270pub const SYS_timer_create = 259;
271pub const SYS_timer_settime = SYS_timer_create + 1;
272pub const SYS_timer_gettime = SYS_timer_create + 2;
273pub const SYS_timer_getoverrun = SYS_timer_create + 3;
274pub const SYS_timer_delete = SYS_timer_create + 4;
275pub const SYS_clock_settime = SYS_timer_create + 5;
276pub const SYS_clock_gettime = SYS_timer_create + 6;
277pub const SYS_clock_getres = SYS_timer_create + 7;
278pub const SYS_clock_nanosleep = SYS_timer_create + 8;
279pub const SYS_statfs64 = 268;
280pub const SYS_fstatfs64 = 269;
281pub const SYS_tgkill = 270;
282pub const SYS_utimes = 271;
283pub const SYS_fadvise64_64 = 272;
284pub const SYS_vserver = 273;
285pub const SYS_mbind = 274;
286pub const SYS_get_mempolicy = 275;
287pub const SYS_set_mempolicy = 276;
288pub const SYS_mq_open = 277;
289pub const SYS_mq_unlink = SYS_mq_open + 1;
290pub const SYS_mq_timedsend = SYS_mq_open + 2;
291pub const SYS_mq_timedreceive = SYS_mq_open + 3;
292pub const SYS_mq_notify = SYS_mq_open + 4;
293pub const SYS_mq_getsetattr = SYS_mq_open + 5;
294pub const SYS_kexec_load = 283;
295pub const SYS_waitid = 284;
296pub const SYS_add_key = 286;
297pub const SYS_request_key = 287;
298pub const SYS_keyctl = 288;
299pub const SYS_ioprio_set = 289;
300pub const SYS_ioprio_get = 290;
301pub const SYS_inotify_init = 291;
302pub const SYS_inotify_add_watch = 292;
303pub const SYS_inotify_rm_watch = 293;
304pub const SYS_migrate_pages = 294;
305pub const SYS_openat = 295;
306pub const SYS_mkdirat = 296;
307pub const SYS_mknodat = 297;
308pub const SYS_fchownat = 298;
309pub const SYS_futimesat = 299;
310pub const SYS_fstatat64 = 300;
311pub const SYS_unlinkat = 301;
312pub const SYS_renameat = 302;
313pub const SYS_linkat = 303;
314pub const SYS_symlinkat = 304;
315pub const SYS_readlinkat = 305;
316pub const SYS_fchmodat = 306;
317pub const SYS_faccessat = 307;
318pub const SYS_pselect6 = 308;
319pub const SYS_ppoll = 309;
320pub const SYS_unshare = 310;
321pub const SYS_set_robust_list = 311;
322pub const SYS_get_robust_list = 312;
323pub const SYS_splice = 313;
324pub const SYS_sync_file_range = 314;
325pub const SYS_tee = 315;
326pub const SYS_vmsplice = 316;
327pub const SYS_move_pages = 317;
328pub const SYS_getcpu = 318;
329pub const SYS_epoll_pwait = 319;
330pub const SYS_utimensat = 320;
331pub const SYS_signalfd = 321;
332pub const SYS_timerfd_create = 322;
333pub const SYS_eventfd = 323;
334pub const SYS_fallocate = 324;
335pub const SYS_timerfd_settime = 325;
336pub const SYS_timerfd_gettime = 326;
337pub const SYS_signalfd4 = 327;
338pub const SYS_eventfd2 = 328;
339pub const SYS_epoll_create1 = 329;
340pub const SYS_dup3 = 330;
341pub const SYS_pipe2 = 331;
342pub const SYS_inotify_init1 = 332;
343pub const SYS_preadv = 333;
344pub const SYS_pwritev = 334;
345pub const SYS_rt_tgsigqueueinfo = 335;
346pub const SYS_perf_event_open = 336;
347pub const SYS_recvmmsg = 337;
348pub const SYS_fanotify_init = 338;
349pub const SYS_fanotify_mark = 339;
350pub const SYS_prlimit64 = 340;
351pub const SYS_name_to_handle_at = 341;
352pub const SYS_open_by_handle_at = 342;
353pub const SYS_clock_adjtime = 343;
354pub const SYS_syncfs = 344;
355pub const SYS_sendmmsg = 345;
356pub const SYS_setns = 346;
357pub const SYS_process_vm_readv = 347;
358pub const SYS_process_vm_writev = 348;
359pub const SYS_kcmp = 349;
360pub const SYS_finit_module = 350;
361pub const SYS_sched_setattr = 351;
362pub const SYS_sched_getattr = 352;
363pub const SYS_renameat2 = 353;
364pub const SYS_seccomp = 354;
365pub const SYS_getrandom = 355;
366pub const SYS_memfd_create = 356;
367pub const SYS_bpf = 357;
368pub const SYS_execveat = 358;
369pub const SYS_socket = 359;
370pub const SYS_socketpair = 360;
371pub const SYS_bind = 361;
372pub const SYS_connect = 362;
373pub const SYS_listen = 363;
374pub const SYS_accept4 = 364;
375pub const SYS_getsockopt = 365;
376pub const SYS_setsockopt = 366;
377pub const SYS_getsockname = 367;
378pub const SYS_getpeername = 368;
379pub const SYS_sendto = 369;
380pub const SYS_sendmsg = 370;
381pub const SYS_recvfrom = 371;
382pub const SYS_recvmsg = 372;
383pub const SYS_shutdown = 373;
384pub const SYS_userfaultfd = 374;
385pub const SYS_membarrier = 375;
386pub const SYS_mlock2 = 376;
387pub const SYS_copy_file_range = 377;
388pub const SYS_preadv2 = 378;
389pub const SYS_pwritev2 = 379;
390pub const SYS_pkey_mprotect = 380;
391pub const SYS_pkey_alloc = 381;
392pub const SYS_pkey_free = 382;
393pub const SYS_statx = 383;
394pub const SYS_arch_prctl = 384;
395pub const SYS_io_pgetevents = 385;
396pub const SYS_rseq = 386;
397pub const SYS_semget = 393;
398pub const SYS_semctl = 394;
399pub const SYS_shmget = 395;
400pub const SYS_shmctl = 396;
401pub const SYS_shmat = 397;
402pub const SYS_shmdt = 398;
403pub const SYS_msgget = 399;
404pub const SYS_msgsnd = 400;
405pub const SYS_msgrcv = 401;
406pub const SYS_msgctl = 402;
407pub const SYS_clock_gettime64 = 403;
408pub const SYS_clock_settime64 = 404;
409pub const SYS_clock_adjtime64 = 405;
410pub const SYS_clock_getres_time64 = 406;
411pub const SYS_clock_nanosleep_time64 = 407;
412pub const SYS_timer_gettime64 = 408;
413pub const SYS_timer_settime64 = 409;
414pub const SYS_timerfd_gettime64 = 410;
415pub const SYS_timerfd_settime64 = 411;
416pub const SYS_utimensat_time64 = 412;
417pub const SYS_pselect6_time64 = 413;
418pub const SYS_ppoll_time64 = 414;
419pub const SYS_io_pgetevents_time64 = 416;
420pub const SYS_recvmmsg_time64 = 417;
421pub const SYS_mq_timedsend_time64 = 418;
422pub const SYS_mq_timedreceive_time64 = 419;
423pub const SYS_semtimedop_time64 = 420;
424pub const SYS_rt_sigtimedwait_time64 = 421;
425pub const SYS_futex_time64 = 422;
426pub const SYS_sched_rr_get_interval_time64 = 423;
427pub const SYS_pidfd_send_signal = 424;
428pub const SYS_io_uring_setup = 425;
429pub const SYS_io_uring_enter = 426;
430pub const SYS_io_uring_register = 427;
431pub const SYS_open_tree = 428;
432pub const SYS_move_mount = 429;
433pub const SYS_fsopen = 430;
434pub const SYS_fsconfig = 431;
435pub const SYS_fsmount = 432;
436pub const SYS_fspick = 433;
437
438pub const O_CREAT = 0o100;
439pub const O_EXCL = 0o200;
440pub const O_NOCTTY = 0o400;
441pub const O_TRUNC = 0o1000;
442pub const O_APPEND = 0o2000;
443pub const O_NONBLOCK = 0o4000;
444pub const O_DSYNC = 0o10000;
445pub const O_SYNC = 0o4010000;
446pub const O_RSYNC = 0o4010000;
447pub const O_DIRECTORY = 0o200000;
448pub const O_NOFOLLOW = 0o400000;
449pub const O_CLOEXEC = 0o2000000;
450
451pub const O_ASYNC = 0o20000;
452pub const O_DIRECT = 0o40000;
453pub const O_LARGEFILE = 0o100000;
454pub const O_NOATIME = 0o1000000;
455pub const O_PATH = 0o10000000;
456pub const O_TMPFILE = 0o20200000;
457pub const O_NDELAY = O_NONBLOCK;
458
459pub const F_DUPFD = 0;
460pub const F_GETFD = 1;
461pub const F_SETFD = 2;
462pub const F_GETFL = 3;
463pub const F_SETFL = 4;
464
465pub const F_SETOWN = 8;
466pub const F_GETOWN = 9;
467pub const F_SETSIG = 10;
468pub const F_GETSIG = 11;
469
470pub const F_GETLK = 12;
471pub const F_SETLK = 13;
472pub const F_SETLKW = 14;
473
474pub const F_SETOWN_EX = 15;
475pub const F_GETOWN_EX = 16;
476
477pub const F_GETOWNER_UIDS = 17;
478
479pub const MAP_NORESERVE = 0x4000;
480pub const MAP_GROWSDOWN = 0x0100;
481pub const MAP_DENYWRITE = 0x0800;
482pub const MAP_EXECUTABLE = 0x1000;
483pub const MAP_LOCKED = 0x2000;
484pub const MAP_32BIT = 0x40;
485
486pub const MMAP2_UNIT = 4096;
487
488pub const VDSO_CGT_SYM = "__vdso_clock_gettime";
489pub const VDSO_CGT_VER = "LINUX_2.6";
490
491pub const msghdr = extern struct {
492 msg_name: ?*sockaddr,
493 msg_namelen: socklen_t,
494 msg_iov: [*]iovec,
495 msg_iovlen: i32,
496 msg_control: ?*c_void,
497 msg_controllen: socklen_t,
498 msg_flags: i32,
499};
500
501pub const msghdr_const = extern struct {
502 msg_name: ?*const sockaddr,
503 msg_namelen: socklen_t,
504 msg_iov: [*]iovec_const,
505 msg_iovlen: i32,
506 msg_control: ?*c_void,
507 msg_controllen: socklen_t,
508 msg_flags: i32,
509};
510
511pub const blksize_t = i32;
512pub const nlink_t = u32;
513pub const time_t = isize;
514pub const mode_t = u32;
515pub const off_t = i64;
516pub const ino_t = u64;
517pub const dev_t = u64;
518pub const blkcnt_t = i64;
519
520/// Renamed to Stat to not conflict with the stat function.
521/// atime, mtime, and ctime have functions to return `timespec`,
522/// because although this is a POSIX API, the layout and names of
523/// the structs are inconsistent across operating systems, and
524/// in C, macros are used to hide the differences. Here we use
525/// methods to accomplish this.
526pub const Stat = extern struct {
527 dev: dev_t,
528 __dev_padding: u32,
529 __ino_truncated: u32,
530 mode: mode_t,
531 nlink: nlink_t,
532 uid: uid_t,
533 gid: gid_t,
534 rdev: dev_t,
535 __rdev_padding: u32,
536 size: off_t,
537 blksize: blksize_t,
538 blocks: blkcnt_t,
539 atim: timespec,
540 mtim: timespec,
541 ctim: timespec,
542 ino: ino_t,
543
544 pub fn atime(self: Stat) timespec {
545 return self.atim;
546 }
547
548 pub fn mtime(self: Stat) timespec {
549 return self.mtim;
550 }
551
552 pub fn ctime(self: Stat) timespec {
553 return self.ctim;
554 }
555};
556
557pub const timespec = extern struct {
558 tv_sec: i32,
559 tv_nsec: i32,
560};
561
562pub const timeval = extern struct {
563 tv_sec: i32,
564 tv_usec: i32,
565};
566
567pub const timezone = extern struct {
568 tz_minuteswest: i32,
569 tz_dsttime: i32,
570};
571
572pub const mcontext_t = extern struct {
573 gregs: [19]usize,
574 fpregs: [*]u8,
575 oldmask: usize,
576 cr2: usize,
577};
578
579pub const REG_GS = 0;
580pub const REG_FS = 1;
581pub const REG_ES = 2;
582pub const REG_DS = 3;
583pub const REG_EDI = 4;
584pub const REG_ESI = 5;
585pub const REG_EBP = 6;
586pub const REG_ESP = 7;
587pub const REG_EBX = 8;
588pub const REG_EDX = 9;
589pub const REG_ECX = 10;
590pub const REG_EAX = 11;
591pub const REG_TRAPNO = 12;
592pub const REG_ERR = 13;
593pub const REG_EIP = 14;
594pub const REG_CS = 15;
595pub const REG_EFL = 16;
596pub const REG_UESP = 17;
597pub const REG_SS = 18;
598
599pub const ucontext_t = extern struct {
600 flags: usize,
601 link: *ucontext_t,
602 stack: stack_t,
603 mcontext: mcontext_t,
604 sigmask: sigset_t,
605 regspace: [64]u64,
606};
607
608pub const Elf_Symndx = u32;
609
610pub const user_desc = packed struct {
611 entry_number: u32,
612 base_addr: u32,
613 limit: u32,
614 seg_32bit: u1,
615 contents: u2,
616 read_exec_only: u1,
617 limit_in_pages: u1,
618 seg_not_present: u1,
619 useable: u1,
620};
621
622// socketcall() call numbers
623pub const SC_socket = 1;
624pub const SC_bind = 2;
625pub const SC_connect = 3;
626pub const SC_listen = 4;
627pub const SC_accept = 5;
628pub const SC_getsockname = 6;
629pub const SC_getpeername = 7;
630pub const SC_socketpair = 8;
631pub const SC_send = 9;
632pub const SC_recv = 10;
633pub const SC_sendto = 11;
634pub const SC_recvfrom = 12;
635pub const SC_shutdown = 13;
636pub const SC_setsockopt = 14;
637pub const SC_getsockopt = 15;
638pub const SC_sendmsg = 16;
639pub const SC_recvmsg = 17;
640pub const SC_accept4 = 18;
641pub const SC_recvmmsg = 19;
642pub const SC_sendmmsg = 20;
lib/std/os/bits/linux/mipsel.zig-1
...@@ -454,7 +454,6 @@ pub const SO_PEERSEC = 30;...@@ -454,7 +454,6 @@ pub const SO_PEERSEC = 30;
454pub const SO_SNDBUFFORCE = 31;454pub const SO_SNDBUFFORCE = 31;
455pub const SO_RCVBUFFORCE = 33;455pub const SO_RCVBUFFORCE = 33;
456456
457pub const VDSO_USEFUL = true;
458pub const VDSO_CGT_SYM = "__kernel_clock_gettime";457pub const VDSO_CGT_SYM = "__kernel_clock_gettime";
459pub const VDSO_CGT_VER = "LINUX_2.6.39";458pub const VDSO_CGT_VER = "LINUX_2.6.39";
460459
lib/std/os/bits/linux/x86_64.zig-1
...@@ -420,7 +420,6 @@ pub const MAP_LOCKED = 0x2000;...@@ -420,7 +420,6 @@ pub const MAP_LOCKED = 0x2000;
420/// don't check for reservations420/// don't check for reservations
421pub const MAP_NORESERVE = 0x4000;421pub const MAP_NORESERVE = 0x4000;
422422
423pub const VDSO_USEFUL = true;
424pub const VDSO_CGT_SYM = "__vdso_clock_gettime";423pub const VDSO_CGT_SYM = "__vdso_clock_gettime";
425pub const VDSO_CGT_VER = "LINUX_2.6";424pub const VDSO_CGT_VER = "LINUX_2.6";
426pub const VDSO_GETCPU_SYM = "__vdso_getcpu";425pub const VDSO_GETCPU_SYM = "__vdso_getcpu";
lib/std/os/linux.zig+49
...@@ -14,6 +14,7 @@ const vdso = @import("linux/vdso.zig");...@@ -14,6 +14,7 @@ const vdso = @import("linux/vdso.zig");
14const dl = @import("../dynamic_library.zig");14const dl = @import("../dynamic_library.zig");
1515
16pub usingnamespace switch (builtin.arch) {16pub usingnamespace switch (builtin.arch) {
17 .i386 => @import("linux/i386.zig"),
17 .x86_64 => @import("linux/x86_64.zig"),18 .x86_64 => @import("linux/x86_64.zig"),
18 .aarch64 => @import("linux/arm64.zig"),19 .aarch64 => @import("linux/arm64.zig"),
19 .arm => @import("linux/arm-eabi.zig"),20 .arm => @import("linux/arm-eabi.zig"),
...@@ -743,26 +744,44 @@ pub fn sigismember(set: *const sigset_t, sig: u6) bool {...@@ -743,26 +744,44 @@ pub fn sigismember(set: *const sigset_t, sig: u6) bool {
743}744}
744745
745pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {746pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
747 if (builtin.arch == .i386) {
748 return socketcall(SC_getsockname, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len) });
749 }
746 return syscall3(SYS_getsockname, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len));750 return syscall3(SYS_getsockname, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len));
747}751}
748752
749pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {753pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
754 if (builtin.arch == .i386) {
755 return socketcall(SC_getpeername, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len) });
756 }
750 return syscall3(SYS_getpeername, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len));757 return syscall3(SYS_getpeername, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len));
751}758}
752759
753pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {760pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {
761 if (builtin.arch == .i386) {
762 return socketcall(SC_socket, &[3]usize{ domain, socket_type, protocol });
763 }
754 return syscall3(SYS_socket, domain, socket_type, protocol);764 return syscall3(SYS_socket, domain, socket_type, protocol);
755}765}
756766
757pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize {767pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize {
768 if (builtin.arch == .i386) {
769 return socketcall(SC_setsockopt, &[5]usize{ @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @intCast(usize, optlen) });
770 }
758 return syscall5(SYS_setsockopt, @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @intCast(usize, optlen));771 return syscall5(SYS_setsockopt, @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @intCast(usize, optlen));
759}772}
760773
761pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize {774pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize {
775 if (builtin.arch == .i386) {
776 return socketcall(SC_getsockopt, &[5]usize{ @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen) });
777 }
762 return syscall5(SYS_getsockopt, @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen));778 return syscall5(SYS_getsockopt, @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen));
763}779}
764780
765pub fn sendmsg(fd: i32, msg: *msghdr_const, flags: u32) usize {781pub fn sendmsg(fd: i32, msg: *msghdr_const, flags: u32) usize {
782 if (builtin.arch == .i386) {
783 return socketcall(SC_sendmsg, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), flags });
784 }
766 return syscall3(SYS_sendmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), flags);785 return syscall3(SYS_sendmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), flags);
767}786}
768787
...@@ -807,42 +826,72 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize...@@ -807,42 +826,72 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize
807}826}
808827
809pub fn connect(fd: i32, addr: *const c_void, len: socklen_t) usize {828pub fn connect(fd: i32, addr: *const c_void, len: socklen_t) usize {
829 if (builtin.arch == .i386) {
830 return socketcall(SC_connect, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), len });
831 }
810 return syscall3(SYS_connect, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), len);832 return syscall3(SYS_connect, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), len);
811}833}
812834
813pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize {835pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize {
836 if (builtin.arch == .i386) {
837 return socketcall(SC_recvmsg, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), flags });
838 }
814 return syscall3(SYS_recvmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), flags);839 return syscall3(SYS_recvmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), flags);
815}840}
816841
817pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize {842pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize {
843 if (builtin.arch == .i386) {
844 return socketcall(SC_recvfrom, &[6]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen) });
845 }
818 return syscall6(SYS_recvfrom, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));846 return syscall6(SYS_recvfrom, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
819}847}
820848
821pub fn shutdown(fd: i32, how: i32) usize {849pub fn shutdown(fd: i32, how: i32) usize {
850 if (builtin.arch == .i386) {
851 return socketcall(SC_shutdown, &[2]usize{ @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, how)) });
852 }
822 return syscall2(SYS_shutdown, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, how)));853 return syscall2(SYS_shutdown, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, how)));
823}854}
824855
825pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize {856pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize {
857 if (builtin.arch == .i386) {
858 return socketcall(SC_bind, &[3]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @intCast(usize, len) });
859 }
826 return syscall3(SYS_bind, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @intCast(usize, len));860 return syscall3(SYS_bind, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @intCast(usize, len));
827}861}
828862
829pub fn listen(fd: i32, backlog: u32) usize {863pub fn listen(fd: i32, backlog: u32) usize {
864 if (builtin.arch == .i386) {
865 return socketcall(SC_listen, &[2]usize{ @bitCast(usize, @as(isize, fd)), backlog });
866 }
830 return syscall2(SYS_listen, @bitCast(usize, @as(isize, fd)), backlog);867 return syscall2(SYS_listen, @bitCast(usize, @as(isize, fd)), backlog);
831}868}
832869
833pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize {870pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize {
871 if (builtin.arch == .i386) {
872 return socketcall(SC_sendto, &[6]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen) });
873 }
834 return syscall6(SYS_sendto, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen));874 return syscall6(SYS_sendto, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen));
835}875}
836876
837pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize {877pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize {
878 if (builtin.arch == .i386) {
879 return socketcall(SC_socketpair, &[4]usize{ @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(&fd[0]) });
880 }
838 return syscall4(SYS_socketpair, @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(&fd[0]));881 return syscall4(SYS_socketpair, @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(&fd[0]));
839}882}
840883
841pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {884pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
885 if (builtin.arch == .i386) {
886 return socketcall(SC_accept, &[4]usize{ fd, addr, len, 0 });
887 }
842 return accept4(fd, addr, len, 0);888 return accept4(fd, addr, len, 0);
843}889}
844890
845pub fn accept4(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t, flags: u32) usize {891pub fn accept4(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t, flags: u32) usize {
892 if (builtin.arch == .i386) {
893 return socketcall(SC_accept4, &[4]usize{ @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len), flags });
894 }
846 return syscall4(SYS_accept4, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len), flags);895 return syscall4(SYS_accept4, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len), flags);
847}896}
848897
lib/std/os/linux/i386.zig created+119
...@@ -0,0 +1,119 @@
1usingnamespace @import("../bits.zig");
2
3pub fn syscall0(number: usize) usize {
4 return asm volatile ("int $0x80"
5 : [ret] "={eax}" (-> usize)
6 : [number] "{eax}" (number)
7 : "memory"
8 );
9}
10
11pub fn syscall1(number: usize, arg1: usize) usize {
12 return asm volatile ("int $0x80"
13 : [ret] "={eax}" (-> usize)
14 : [number] "{eax}" (number),
15 [arg1] "{ebx}" (arg1)
16 : "memory"
17 );
18}
19
20pub fn syscall2(number: usize, arg1: usize, arg2: usize) usize {
21 return asm volatile ("int $0x80"
22 : [ret] "={eax}" (-> usize)
23 : [number] "{eax}" (number),
24 [arg1] "{ebx}" (arg1),
25 [arg2] "{ecx}" (arg2)
26 : "memory"
27 );
28}
29
30pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
31 return asm volatile ("int $0x80"
32 : [ret] "={eax}" (-> usize)
33 : [number] "{eax}" (number),
34 [arg1] "{ebx}" (arg1),
35 [arg2] "{ecx}" (arg2),
36 [arg3] "{edx}" (arg3)
37 : "memory"
38 );
39}
40
41pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
42 return asm volatile ("int $0x80"
43 : [ret] "={eax}" (-> usize)
44 : [number] "{eax}" (number),
45 [arg1] "{ebx}" (arg1),
46 [arg2] "{ecx}" (arg2),
47 [arg3] "{edx}" (arg3),
48 [arg4] "{esi}" (arg4)
49 : "memory"
50 );
51}
52
53pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
54 return asm volatile ("int $0x80"
55 : [ret] "={eax}" (-> usize)
56 : [number] "{eax}" (number),
57 [arg1] "{ebx}" (arg1),
58 [arg2] "{ecx}" (arg2),
59 [arg3] "{edx}" (arg3),
60 [arg4] "{esi}" (arg4),
61 [arg5] "{edi}" (arg5)
62 : "memory"
63 );
64}
65
66pub fn syscall6(
67 number: usize,
68 arg1: usize,
69 arg2: usize,
70 arg3: usize,
71 arg4: usize,
72 arg5: usize,
73 arg6: usize,
74) usize {
75 return asm volatile (
76 \\ push %%ebp
77 \\ mov %[arg6], %%ebp
78 \\ int $0x80
79 \\ pop %%ebp
80 : [ret] "={eax}" (-> usize)
81 : [number] "{eax}" (number),
82 [arg1] "{ebx}" (arg1),
83 [arg2] "{ecx}" (arg2),
84 [arg3] "{edx}" (arg3),
85 [arg4] "{esi}" (arg4),
86 [arg5] "{edi}" (arg5),
87 [arg6] "rm" (arg6)
88 : "memory"
89 );
90}
91
92pub fn socketcall(call: usize, args: [*]usize) usize {
93 return asm volatile ("int $0x80"
94 : [ret] "={eax}" (-> usize)
95 : [number] "{eax}" (@as(usize, SYS_socketcall)),
96 [arg1] "{ebx}" (call),
97 [arg2] "{ecx}" (@ptrToInt(args))
98 : "memory"
99 );
100}
101
102/// This matches the libc clone function.
103pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
104
105pub nakedcc fn restore() void {
106 return asm volatile ("int $0x80"
107 :
108 : [number] "{eax}" (@as(usize, SYS_sigreturn))
109 : "memory"
110 );
111}
112
113pub nakedcc fn restore_rt() void {
114 return asm volatile ("int $0x80"
115 :
116 : [number] "{eax}" (@as(usize, SYS_rt_sigreturn))
117 : "memory"
118 );
119}
lib/std/os/linux/tls.zig+27
...@@ -109,12 +109,38 @@ const TLSImage = struct {...@@ -109,12 +109,38 @@ const TLSImage = struct {
109 tcb_offset: usize,109 tcb_offset: usize,
110 dtv_offset: usize,110 dtv_offset: usize,
111 data_offset: usize,111 data_offset: usize,
112 // Only used on the i386 architecture
113 gdt_entry_number: usize,
112};114};
113115
114pub var tls_image: ?TLSImage = null;116pub var tls_image: ?TLSImage = null;
115117
116pub fn setThreadPointer(addr: usize) void {118pub fn setThreadPointer(addr: usize) void {
117 switch (builtin.arch) {119 switch (builtin.arch) {
120 .i386 => {
121 var user_desc = std.os.linux.user_desc{
122 .entry_number = tls_image.?.gdt_entry_number,
123 .base_addr = addr,
124 .limit = 0xfffff,
125 .seg_32bit = 1,
126 .contents = 0, // Data
127 .read_exec_only = 0,
128 .limit_in_pages = 1,
129 .seg_not_present = 0,
130 .useable = 1,
131 };
132 const rc = std.os.linux.syscall1(std.os.linux.SYS_set_thread_area, @ptrToInt(&user_desc));
133 assert(rc == 0);
134
135 const gdt_entry_number = user_desc.entry_number;
136 // We have to keep track of our slot as it's also needed for clone()
137 tls_image.?.gdt_entry_number = gdt_entry_number;
138 // Update the %gs selector
139 asm volatile ("movl %[gs_val], %%gs"
140 :
141 : [gs_val] "r" (gdt_entry_number << 3 | 3)
142 );
143 },
118 .x86_64 => {144 .x86_64 => {
119 const rc = std.os.linux.syscall2(std.os.linux.SYS_arch_prctl, std.os.linux.ARCH_SET_FS, addr);145 const rc = std.os.linux.syscall2(std.os.linux.SYS_arch_prctl, std.os.linux.ARCH_SET_FS, addr);
120 assert(rc == 0);146 assert(rc == 0);
...@@ -238,6 +264,7 @@ pub fn initTLS() ?*elf.Phdr {...@@ -238,6 +264,7 @@ pub fn initTLS() ?*elf.Phdr {
238 .tcb_offset = tcb_offset,264 .tcb_offset = tcb_offset,
239 .dtv_offset = dtv_offset,265 .dtv_offset = dtv_offset,
240 .data_offset = data_offset,266 .data_offset = data_offset,
267 .gdt_entry_number = @bitCast(usize, @as(isize, -1)),
241 };268 };
242 }269 }
243270
lib/std/os/wasi.zig+2-2
...@@ -12,8 +12,8 @@ comptime {...@@ -12,8 +12,8 @@ comptime {
12 assert(@alignOf(u16) == 2);12 assert(@alignOf(u16) == 2);
13 assert(@alignOf(i32) == 4);13 assert(@alignOf(i32) == 4);
14 assert(@alignOf(u32) == 4);14 assert(@alignOf(u32) == 4);
15 assert(@alignOf(i64) == 8);15 // assert(@alignOf(i64) == 8);
16 assert(@alignOf(u64) == 8);16 // assert(@alignOf(u64) == 8);
17}17}
1818
19pub const iovec_t = iovec;19pub const iovec_t = iovec;
lib/std/special/c.zig+43
...@@ -197,6 +197,49 @@ extern fn __stack_chk_fail() noreturn {...@@ -197,6 +197,49 @@ extern fn __stack_chk_fail() noreturn {
197// across .o file boundaries. fix comptime @ptrCast of nakedcc functions.197// across .o file boundaries. fix comptime @ptrCast of nakedcc functions.
198nakedcc fn clone() void {198nakedcc fn clone() void {
199 switch (builtin.arch) {199 switch (builtin.arch) {
200 .i386 => {
201 // __clone(func, stack, flags, arg, ptid, tls, ctid)
202 // +8, +12, +16, +20, +24, +28, +32
203 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
204 // eax, ebx, ecx, edx, esi, edi
205 asm volatile (
206 \\ push %%ebp
207 \\ mov %%esp,%%ebp
208 \\ push %%ebx
209 \\ push %%esi
210 \\ push %%edi
211 \\ // Setup the arguments
212 \\ mov 16(%%ebp),%%ebx
213 \\ mov 12(%%ebp),%%ecx
214 \\ and $-16,%%ecx
215 \\ sub $20,%%ecx
216 \\ mov 20(%%ebp),%%eax
217 \\ mov %%eax,4(%%ecx)
218 \\ mov 8(%%ebp),%%eax
219 \\ mov %%eax,0(%%ecx)
220 \\ mov 24(%%ebp),%%edx
221 \\ mov 28(%%ebp),%%esi
222 \\ mov 32(%%ebp),%%edi
223 \\ mov $120,%%eax
224 \\ int $128
225 \\ test %%eax,%%eax
226 \\ jnz 1f
227 \\ pop %%eax
228 \\ xor %%ebp,%%ebp
229 \\ call *%%eax
230 \\ mov %%eax,%%ebx
231 \\ xor %%eax,%%eax
232 \\ inc %%eax
233 \\ int $128
234 \\ hlt
235 \\1:
236 \\ pop %%edi
237 \\ pop %%esi
238 \\ pop %%ebx
239 \\ pop %%ebp
240 \\ ret
241 );
242 },
200 .x86_64 => {243 .x86_64 => {
201 asm volatile (244 asm volatile (
202 \\ xor %%eax,%%eax245 \\ xor %%eax,%%eax
lib/std/thread.zig+29-2
...@@ -314,11 +314,38 @@ pub const Thread = struct {...@@ -314,11 +314,38 @@ pub const Thread = struct {
314 os.CLONE_THREAD | os.CLONE_SYSVSEM | os.CLONE_PARENT_SETTID | os.CLONE_CHILD_CLEARTID |314 os.CLONE_THREAD | os.CLONE_SYSVSEM | os.CLONE_PARENT_SETTID | os.CLONE_CHILD_CLEARTID |
315 os.CLONE_DETACHED;315 os.CLONE_DETACHED;
316 var newtls: usize = undefined;316 var newtls: usize = undefined;
317 // This structure is only needed when targeting i386
318 var user_desc: if (builtin.arch == .i386) os.linux.user_desc else void = undefined;
319
317 if (os.linux.tls.tls_image) |tls_img| {320 if (os.linux.tls.tls_image) |tls_img| {
318 newtls = os.linux.tls.copyTLS(mmap_addr + tls_start_offset);321 if (builtin.arch == .i386) {
322 user_desc = os.linux.user_desc{
323 .entry_number = tls_img.gdt_entry_number,
324 .base_addr = os.linux.tls.copyTLS(mmap_addr + tls_start_offset),
325 .limit = 0xfffff,
326 .seg_32bit = 1,
327 .contents = 0, // Data
328 .read_exec_only = 0,
329 .limit_in_pages = 1,
330 .seg_not_present = 0,
331 .useable = 1,
332 };
333 newtls = @ptrToInt(&user_desc);
334 } else {
335 newtls = os.linux.tls.copyTLS(mmap_addr + tls_start_offset);
336 }
319 flags |= os.CLONE_SETTLS;337 flags |= os.CLONE_SETTLS;
320 }338 }
321 const rc = os.linux.clone(MainFuncs.linuxThreadMain, mmap_addr + stack_end_offset, flags, arg, &thread_ptr.data.handle, newtls, &thread_ptr.data.handle);339
340 const rc = os.linux.clone(
341 MainFuncs.linuxThreadMain,
342 mmap_addr + stack_end_offset,
343 flags,
344 arg,
345 &thread_ptr.data.handle,
346 newtls,
347 &thread_ptr.data.handle,
348 );
322 switch (os.errno(rc)) {349 switch (os.errno(rc)) {
323 0 => return thread_ptr,350 0 => return thread_ptr,
324 os.EAGAIN => return error.ThreadQuotaExceeded,351 os.EAGAIN => return error.ThreadQuotaExceeded,
test/tests.zig+22-2
...@@ -70,6 +70,26 @@ const test_targets = [_]TestTarget{...@@ -70,6 +70,26 @@ const test_targets = [_]TestTarget{
70 .link_libc = true,70 .link_libc = true,
71 },71 },
7272
73 TestTarget{
74 .target = Target{
75 .Cross = CrossTarget{
76 .os = .linux,
77 .arch = .i386,
78 .abi = .none,
79 },
80 },
81 },
82 TestTarget{
83 .target = Target{
84 .Cross = CrossTarget{
85 .os = .linux,
86 .arch = .i386,
87 .abi = .musl,
88 },
89 },
90 .link_libc = true,
91 },
92
73 TestTarget{93 TestTarget{
74 .target = Target{94 .target = Target{
75 .Cross = CrossTarget{95 .Cross = CrossTarget{
...@@ -411,7 +431,7 @@ pub fn addPkgTests(...@@ -411,7 +431,7 @@ pub fn addPkgTests(
411 const ArchTag = @TagType(builtin.Arch);431 const ArchTag = @TagType(builtin.Arch);
412 if (test_target.disable_native and432 if (test_target.disable_native and
413 test_target.target.getOs() == builtin.os and433 test_target.target.getOs() == builtin.os and
414 @as(ArchTag,test_target.target.getArch()) == @as(ArchTag,builtin.arch))434 @as(ArchTag, test_target.target.getArch()) == @as(ArchTag, builtin.arch))
415 {435 {
416 continue;436 continue;
417 }437 }
...@@ -429,7 +449,7 @@ pub fn addPkgTests(...@@ -429,7 +449,7 @@ pub fn addPkgTests(
429 "bare";449 "bare";
430450
431 const triple_prefix = if (test_target.target == .Native)451 const triple_prefix = if (test_target.target == .Native)
432 @as([]const u8,"native")452 @as([]const u8, "native")
433 else453 else
434 test_target.target.zigTripleNoSubArch(b.allocator) catch unreachable;454 test_target.target.zigTripleNoSubArch(b.allocator) catch unreachable;
435455