From 666b153144eeb160c5b2279d406f8e0b23613857 Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Mon, 17 Dec 2018 17:48:34 -0200 Subject: [PATCH 01/34] freebsd: remove syscall files --- CMakeLists.txt | 2 - std/c/freebsd.zig | 39 ++- std/os/freebsd/index.zig | 4 +- std/os/freebsd/syscall.zig | 493 ------------------------------------- std/os/freebsd/x86_64.zig | 136 ---------- 5 files changed, 39 insertions(+), 635 deletions(-) delete mode 100644 std/os/freebsd/syscall.zig delete mode 100644 std/os/freebsd/x86_64.zig diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b64bcca81..a9a4d8faa7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -586,8 +586,6 @@ set(ZIG_STD_FILES "os/linux/arm64.zig" "os/freebsd/errno.zig" "os/freebsd/index.zig" - "os/freebsd/syscall.zig" - "os/freebsd/x86_64.zig" "os/path.zig" "os/time.zig" "os/windows/advapi32.zig" diff --git a/std/c/freebsd.zig b/std/c/freebsd.zig index 421e964827..a97cf52eb9 100644 --- a/std/c/freebsd.zig +++ b/std/c/freebsd.zig @@ -1,5 +1,3 @@ -const timespec = @import("../os/freebsd/index.zig").timespec; - extern "c" fn __error() *c_int; pub const _errno = __error; @@ -31,3 +29,40 @@ pub const pthread_attr_t = extern struct { __size: [56]u8, __align: c_long, }; + +pub const msghdr = extern struct { + msg_name: *u8, + msg_namelen: socklen_t, + msg_iov: *iovec, + msg_iovlen: i32, + __pad1: i32, + msg_control: *u8, + msg_controllen: socklen_t, + __pad2: socklen_t, + msg_flags: i32, +}; + +pub const Stat = extern struct { + dev: u64, + ino: u64, + nlink: usize, + + mode: u32, + uid: u32, + gid: u32, + __pad0: u32, + rdev: u64, + size: i64, + blksize: isize, + blocks: i64, + + atim: timespec, + mtim: timespec, + ctim: timespec, + __unused: [3]isize, +}; + +pub const timespec = extern struct { + tv_sec: isize, + tv_nsec: isize, +}; diff --git a/std/os/freebsd/index.zig b/std/os/freebsd/index.zig index 34a3414a48..975479c1e0 100644 --- a/std/os/freebsd/index.zig +++ b/std/os/freebsd/index.zig @@ -742,8 +742,8 @@ pub fn raise(sig: i32) usize { return arch.syscall2(SYS_thr_kill, id, @bitCast(usize, isize(sig))); } -pub const Stat = arch.Stat; -pub const timespec = arch.timespec; +pub const Stat = c.Stat; +pub const timespec = c.timespec; pub fn fstat(fd: i32, stat_buf: *Stat) usize { return arch.syscall2(SYS_fstat, @bitCast(usize, isize(fd)), @ptrToInt(stat_buf)); diff --git a/std/os/freebsd/syscall.zig b/std/os/freebsd/syscall.zig deleted file mode 100644 index 6cdd71de3b..0000000000 --- a/std/os/freebsd/syscall.zig +++ /dev/null @@ -1,493 +0,0 @@ -pub const SYS_syscall = 0; -pub const SYS_exit = 1; -pub const SYS_fork = 2; -pub const SYS_read = 3; -pub const SYS_write = 4; -pub const SYS_open = 5; -pub const SYS_close = 6; -pub const SYS_wait4 = 7; -// 8 is old creat -pub const SYS_link = 9; -pub const SYS_unlink = 10; -// 11 is obsolete execv -pub const SYS_chdir = 12; -pub const SYS_fchdir = 13; -pub const SYS_freebsd11_mknod = 14; -pub const SYS_chmod = 15; -pub const SYS_chown = 16; -pub const SYS_break = 17; -// 18 is freebsd4 getfsstat -// 19 is old lseek -pub const SYS_getpid = 20; -pub const SYS_mount = 21; -pub const SYS_unmount = 22; -pub const SYS_setuid = 23; -pub const SYS_getuid = 24; -pub const SYS_geteuid = 25; -pub const SYS_ptrace = 26; -pub const SYS_recvmsg = 27; -pub const SYS_sendmsg = 28; -pub const SYS_recvfrom = 29; -pub const SYS_accept = 30; -pub const SYS_getpeername = 31; -pub const SYS_getsockname = 32; -pub const SYS_access = 33; -pub const SYS_chflags = 34; -pub const SYS_fchflags = 35; -pub const SYS_sync = 36; -pub const SYS_kill = 37; -// 38 is old stat -pub const SYS_getppid = 39; -// 40 is old lstat -pub const SYS_dup = 41; -pub const SYS_freebsd10_pipe = 42; -pub const SYS_getegid = 43; -pub const SYS_profil = 44; -pub const SYS_ktrace = 45; -// 46 is old sigaction -pub const SYS_getgid = 47; -// 48 is old sigprocmask -pub const SYS_getlogin = 49; -pub const SYS_setlogin = 50; -pub const SYS_acct = 51; -// 52 is old sigpending -pub const SYS_sigaltstack = 53; -pub const SYS_ioctl = 54; -pub const SYS_reboot = 55; -pub const SYS_revoke = 56; -pub const SYS_symlink = 57; -pub const SYS_readlink = 58; -pub const SYS_execve = 59; -pub const SYS_umask = 60; -pub const SYS_chroot = 61; -// 62 is old fstat -// 63 is old getkerninfo -// 64 is old getpagesize -pub const SYS_msync = 65; -pub const SYS_vfork = 66; -// 67 is obsolete vread -// 68 is obsolete vwrite -// 69 is obsolete sbrk (still present on some platforms) -pub const SYS_sstk = 70; -// 71 is old mmap -pub const SYS_vadvise = 72; -pub const SYS_munmap = 73; -pub const SYS_mprotect = 74; -pub const SYS_madvise = 75; -// 76 is obsolete vhangup -// 77 is obsolete vlimit -pub const SYS_mincore = 78; -pub const SYS_getgroups = 79; -pub const SYS_setgroups = 80; -pub const SYS_getpgrp = 81; -pub const SYS_setpgid = 82; -pub const SYS_setitimer = 83; -// 84 is old wait -pub const SYS_swapon = 85; -pub const SYS_getitimer = 86; -// 87 is old gethostname -// 88 is old sethostname -pub const SYS_getdtablesize = 89; -pub const SYS_dup2 = 90; -pub const SYS_fcntl = 92; -pub const SYS_select = 93; -pub const SYS_fsync = 95; -pub const SYS_setpriority = 96; -pub const SYS_socket = 97; -pub const SYS_connect = 98; -// 99 is old accept -pub const SYS_getpriority = 100; -// 101 is old send -// 102 is old recv -// 103 is old sigreturn -pub const SYS_bind = 104; -pub const SYS_setsockopt = 105; -pub const SYS_listen = 106; -// 107 is obsolete vtimes -// 108 is old sigvec -// 109 is old sigblock -// 110 is old sigsetmask -// 111 is old sigsuspend -// 112 is old sigstack -// 113 is old recvmsg -// 114 is old sendmsg -// 115 is obsolete vtrace -pub const SYS_gettimeofday = 116; -pub const SYS_getrusage = 117; -pub const SYS_getsockopt = 118; -pub const SYS_readv = 120; -pub const SYS_writev = 121; -pub const SYS_settimeofday = 122; -pub const SYS_fchown = 123; -pub const SYS_fchmod = 124; -// 125 is old recvfrom -pub const SYS_setreuid = 126; -pub const SYS_setregid = 127; -pub const SYS_rename = 128; -// 129 is old truncate -// 130 is old ftruncate -pub const SYS_flock = 131; -pub const SYS_mkfifo = 132; -pub const SYS_sendto = 133; -pub const SYS_shutdown = 134; -pub const SYS_socketpair = 135; -pub const SYS_mkdir = 136; -pub const SYS_rmdir = 137; -pub const SYS_utimes = 138; -// 139 is obsolete 4.2 sigreturn -pub const SYS_adjtime = 140; -// 141 is old getpeername -// 142 is old gethostid -// 143 is old sethostid -// 144 is old getrlimit -// 145 is old setrlimit -// 146 is old killpg -pub const SYS_setsid = 147; -pub const SYS_quotactl = 148; -// 149 is old quota -// 150 is old getsockname -pub const SYS_nlm_syscall = 154; -pub const SYS_nfssvc = 155; -// 156 is old getdirentries -// 157 is freebsd4 statfs -// 158 is freebsd4 fstatfs -pub const SYS_lgetfh = 160; -pub const SYS_getfh = 161; -// 162 is freebsd4 getdomainname -// 163 is freebsd4 setdomainname -// 164 is freebsd4 uname -pub const SYS_sysarch = 165; -pub const SYS_rtprio = 166; -pub const SYS_semsys = 169; -pub const SYS_msgsys = 170; -pub const SYS_shmsys = 171; -// 173 is freebsd6 pread -// 174 is freebsd6 pwrite -pub const SYS_setfib = 175; -pub const SYS_ntp_adjtime = 176; -pub const SYS_setgid = 181; -pub const SYS_setegid = 182; -pub const SYS_seteuid = 183; -// 184 is obsolete lfs_bmapv -// 185 is obsolete lfs_markv -// 186 is obsolete lfs_segclean -// 187 is obsolete lfs_segwait -pub const SYS_freebsd11_stat = 188; -pub const SYS_freebsd11_fstat = 189; -pub const SYS_freebsd11_lstat = 190; -pub const SYS_pathconf = 191; -pub const SYS_fpathconf = 192; -pub const SYS_getrlimit = 194; -pub const SYS_setrlimit = 195; -pub const SYS_freebsd11_getdirentries = 196; -// 197 is freebsd6 mmap -pub const SYS___syscall = 198; -// 199 is freebsd6 lseek -// 200 is freebsd6 truncate -// 201 is freebsd6 ftruncate -pub const SYS___sysctl = 202; -pub const SYS_mlock = 203; -pub const SYS_munlock = 204; -pub const SYS_undelete = 205; -pub const SYS_futimes = 206; -pub const SYS_getpgid = 207; -pub const SYS_poll = 209; -pub const SYS_freebsd7___semctl = 220; -pub const SYS_semget = 221; -pub const SYS_semop = 222; -pub const SYS_freebsd7_msgctl = 224; -pub const SYS_msgget = 225; -pub const SYS_msgsnd = 226; -pub const SYS_msgrcv = 227; -pub const SYS_shmat = 228; -pub const SYS_freebsd7_shmctl = 229; -pub const SYS_shmdt = 230; -pub const SYS_shmget = 231; -pub const SYS_clock_gettime = 232; -pub const SYS_clock_settime = 233; -pub const SYS_clock_getres = 234; -pub const SYS_ktimer_create = 235; -pub const SYS_ktimer_delete = 236; -pub const SYS_ktimer_settime = 237; -pub const SYS_ktimer_gettime = 238; -pub const SYS_ktimer_getoverrun = 239; -pub const SYS_nanosleep = 240; -pub const SYS_ffclock_getcounter = 241; -pub const SYS_ffclock_setestimate = 242; -pub const SYS_ffclock_getestimate = 243; -pub const SYS_clock_nanosleep = 244; -pub const SYS_clock_getcpuclockid2 = 247; -pub const SYS_ntp_gettime = 248; -pub const SYS_minherit = 250; -pub const SYS_rfork = 251; -// 252 is obsolete openbsd_poll -pub const SYS_issetugid = 253; -pub const SYS_lchown = 254; -pub const SYS_aio_read = 255; -pub const SYS_aio_write = 256; -pub const SYS_lio_listio = 257; -pub const SYS_freebsd11_getdents = 272; -pub const SYS_lchmod = 274; -// 275 is obsolete netbsd_lchown -pub const SYS_lutimes = 276; -// 277 is obsolete netbsd_msync -pub const SYS_freebsd11_nstat = 278; -pub const SYS_freebsd11_nfstat = 279; -pub const SYS_freebsd11_nlstat = 280; -pub const SYS_preadv = 289; -pub const SYS_pwritev = 290; -// 297 is freebsd4 fhstatfs -pub const SYS_fhopen = 298; -pub const SYS_freebsd11_fhstat = 299; -pub const SYS_modnext = 300; -pub const SYS_modstat = 301; -pub const SYS_modfnext = 302; -pub const SYS_modfind = 303; -pub const SYS_kldload = 304; -pub const SYS_kldunload = 305; -pub const SYS_kldfind = 306; -pub const SYS_kldnext = 307; -pub const SYS_kldstat = 308; -pub const SYS_kldfirstmod = 309; -pub const SYS_getsid = 310; -pub const SYS_setresuid = 311; -pub const SYS_setresgid = 312; -// 313 is obsolete signanosleep -pub const SYS_aio_return = 314; -pub const SYS_aio_suspend = 315; -pub const SYS_aio_cancel = 316; -pub const SYS_aio_error = 317; -// 318 is freebsd6 aio_read -// 319 is freebsd6 aio_write -// 320 is freebsd6 lio_listio -pub const SYS_yield = 321; -// 322 is obsolete thr_sleep -// 323 is obsolete thr_wakeup -pub const SYS_mlockall = 324; -pub const SYS_munlockall = 325; -pub const SYS___getcwd = 326; -pub const SYS_sched_setparam = 327; -pub const SYS_sched_getparam = 328; -pub const SYS_sched_setscheduler = 329; -pub const SYS_sched_getscheduler = 330; -pub const SYS_sched_yield = 331; -pub const SYS_sched_get_priority_max = 332; -pub const SYS_sched_get_priority_min = 333; -pub const SYS_sched_rr_get_interval = 334; -pub const SYS_utrace = 335; -// 336 is freebsd4 sendfile -pub const SYS_kldsym = 337; -pub const SYS_jail = 338; -pub const SYS_nnpfs_syscall = 339; -pub const SYS_sigprocmask = 340; -pub const SYS_sigsuspend = 341; -// 342 is freebsd4 sigaction -pub const SYS_sigpending = 343; -// 344 is freebsd4 sigreturn -pub const SYS_sigtimedwait = 345; -pub const SYS_sigwaitinfo = 346; -pub const SYS___acl_get_file = 347; -pub const SYS___acl_set_file = 348; -pub const SYS___acl_get_fd = 349; -pub const SYS___acl_set_fd = 350; -pub const SYS___acl_delete_file = 351; -pub const SYS___acl_delete_fd = 352; -pub const SYS___acl_aclcheck_file = 353; -pub const SYS___acl_aclcheck_fd = 354; -pub const SYS_extattrctl = 355; -pub const SYS_extattr_set_file = 356; -pub const SYS_extattr_get_file = 357; -pub const SYS_extattr_delete_file = 358; -pub const SYS_aio_waitcomplete = 359; -pub const SYS_getresuid = 360; -pub const SYS_getresgid = 361; -pub const SYS_kqueue = 362; -pub const SYS_freebsd11_kevent = 363; -// 364 is obsolete __cap_get_proc -// 365 is obsolete __cap_set_proc -// 366 is obsolete __cap_get_fd -// 367 is obsolete __cap_get_file -// 368 is obsolete __cap_set_fd -// 369 is obsolete __cap_set_file -pub const SYS_extattr_set_fd = 371; -pub const SYS_extattr_get_fd = 372; -pub const SYS_extattr_delete_fd = 373; -pub const SYS___setugid = 374; -pub const SYS_eaccess = 376; -pub const SYS_afs3_syscall = 377; -pub const SYS_nmount = 378; -// 379 is obsolete kse_exit -// 380 is obsolete kse_wakeup -// 381 is obsolete kse_create -// 382 is obsolete kse_thr_interrupt -// 383 is obsolete kse_release -pub const SYS___mac_get_proc = 384; -pub const SYS___mac_set_proc = 385; -pub const SYS___mac_get_fd = 386; -pub const SYS___mac_get_file = 387; -pub const SYS___mac_set_fd = 388; -pub const SYS___mac_set_file = 389; -pub const SYS_kenv = 390; -pub const SYS_lchflags = 391; -pub const SYS_uuidgen = 392; -pub const SYS_sendfile = 393; -pub const SYS_mac_syscall = 394; -pub const SYS_freebsd11_getfsstat = 395; -pub const SYS_freebsd11_statfs = 396; -pub const SYS_freebsd11_fstatfs = 397; -pub const SYS_freebsd11_fhstatfs = 398; -pub const SYS_ksem_close = 400; -pub const SYS_ksem_post = 401; -pub const SYS_ksem_wait = 402; -pub const SYS_ksem_trywait = 403; -pub const SYS_ksem_init = 404; -pub const SYS_ksem_open = 405; -pub const SYS_ksem_unlink = 406; -pub const SYS_ksem_getvalue = 407; -pub const SYS_ksem_destroy = 408; -pub const SYS___mac_get_pid = 409; -pub const SYS___mac_get_link = 410; -pub const SYS___mac_set_link = 411; -pub const SYS_extattr_set_link = 412; -pub const SYS_extattr_get_link = 413; -pub const SYS_extattr_delete_link = 414; -pub const SYS___mac_execve = 415; -pub const SYS_sigaction = 416; -pub const SYS_sigreturn = 417; -pub const SYS_getcontext = 421; -pub const SYS_setcontext = 422; -pub const SYS_swapcontext = 423; -pub const SYS_swapoff = 424; -pub const SYS___acl_get_link = 425; -pub const SYS___acl_set_link = 426; -pub const SYS___acl_delete_link = 427; -pub const SYS___acl_aclcheck_link = 428; -pub const SYS_sigwait = 429; -pub const SYS_thr_create = 430; -pub const SYS_thr_exit = 431; -pub const SYS_thr_self = 432; -pub const SYS_thr_kill = 433; -pub const SYS_jail_attach = 436; -pub const SYS_extattr_list_fd = 437; -pub const SYS_extattr_list_file = 438; -pub const SYS_extattr_list_link = 439; -// 440 is obsolete kse_switchin -pub const SYS_ksem_timedwait = 441; -pub const SYS_thr_suspend = 442; -pub const SYS_thr_wake = 443; -pub const SYS_kldunloadf = 444; -pub const SYS_audit = 445; -pub const SYS_auditon = 446; -pub const SYS_getauid = 447; -pub const SYS_setauid = 448; -pub const SYS_getaudit = 449; -pub const SYS_setaudit = 450; -pub const SYS_getaudit_addr = 451; -pub const SYS_setaudit_addr = 452; -pub const SYS_auditctl = 453; -pub const SYS__umtx_op = 454; -pub const SYS_thr_new = 455; -pub const SYS_sigqueue = 456; -pub const SYS_kmq_open = 457; -pub const SYS_kmq_setattr = 458; -pub const SYS_kmq_timedreceive = 459; -pub const SYS_kmq_timedsend = 460; -pub const SYS_kmq_notify = 461; -pub const SYS_kmq_unlink = 462; -pub const SYS_abort2 = 463; -pub const SYS_thr_set_name = 464; -pub const SYS_aio_fsync = 465; -pub const SYS_rtprio_thread = 466; -pub const SYS_sctp_peeloff = 471; -pub const SYS_sctp_generic_sendmsg = 472; -pub const SYS_sctp_generic_sendmsg_iov = 473; -pub const SYS_sctp_generic_recvmsg = 474; -pub const SYS_pread = 475; -pub const SYS_pwrite = 476; -pub const SYS_mmap = 477; -pub const SYS_lseek = 478; -pub const SYS_truncate = 479; -pub const SYS_ftruncate = 480; -pub const SYS_thr_kill2 = 481; -pub const SYS_shm_open = 482; -pub const SYS_shm_unlink = 483; -pub const SYS_cpuset = 484; -pub const SYS_cpuset_setid = 485; -pub const SYS_cpuset_getid = 486; -pub const SYS_cpuset_getaffinity = 487; -pub const SYS_cpuset_setaffinity = 488; -pub const SYS_faccessat = 489; -pub const SYS_fchmodat = 490; -pub const SYS_fchownat = 491; -pub const SYS_fexecve = 492; -pub const SYS_freebsd11_fstatat = 493; -pub const SYS_futimesat = 494; -pub const SYS_linkat = 495; -pub const SYS_mkdirat = 496; -pub const SYS_mkfifoat = 497; -pub const SYS_freebsd11_mknodat = 498; -pub const SYS_openat = 499; -pub const SYS_readlinkat = 500; -pub const SYS_renameat = 501; -pub const SYS_symlinkat = 502; -pub const SYS_unlinkat = 503; -pub const SYS_posix_openpt = 504; -pub const SYS_gssd_syscall = 505; -pub const SYS_jail_get = 506; -pub const SYS_jail_set = 507; -pub const SYS_jail_remove = 508; -pub const SYS_closefrom = 509; -pub const SYS___semctl = 510; -pub const SYS_msgctl = 511; -pub const SYS_shmctl = 512; -pub const SYS_lpathconf = 513; -// 514 is obsolete cap_new -pub const SYS___cap_rights_get = 515; -pub const SYS_cap_enter = 516; -pub const SYS_cap_getmode = 517; -pub const SYS_pdfork = 518; -pub const SYS_pdkill = 519; -pub const SYS_pdgetpid = 520; -pub const SYS_pselect = 522; -pub const SYS_getloginclass = 523; -pub const SYS_setloginclass = 524; -pub const SYS_rctl_get_racct = 525; -pub const SYS_rctl_get_rules = 526; -pub const SYS_rctl_get_limits = 527; -pub const SYS_rctl_add_rule = 528; -pub const SYS_rctl_remove_rule = 529; -pub const SYS_posix_fallocate = 530; -pub const SYS_posix_fadvise = 531; -pub const SYS_wait6 = 532; -pub const SYS_cap_rights_limit = 533; -pub const SYS_cap_ioctls_limit = 534; -pub const SYS_cap_ioctls_get = 535; -pub const SYS_cap_fcntls_limit = 536; -pub const SYS_cap_fcntls_get = 537; -pub const SYS_bindat = 538; -pub const SYS_connectat = 539; -pub const SYS_chflagsat = 540; -pub const SYS_accept4 = 541; -pub const SYS_pipe2 = 542; -pub const SYS_aio_mlock = 543; -pub const SYS_procctl = 544; -pub const SYS_ppoll = 545; -pub const SYS_futimens = 546; -pub const SYS_utimensat = 547; -// 548 is obsolete numa_getaffinity -// 549 is obsolete numa_setaffinity -pub const SYS_fdatasync = 550; -pub const SYS_fstat = 551; -pub const SYS_fstatat = 552; -pub const SYS_fhstat = 553; -pub const SYS_getdirentries = 554; -pub const SYS_statfs = 555; -pub const SYS_fstatfs = 556; -pub const SYS_getfsstat = 557; -pub const SYS_fhstatfs = 558; -pub const SYS_mknodat = 559; -pub const SYS_kevent = 560; -pub const SYS_cpuset_getdomain = 561; -pub const SYS_cpuset_setdomain = 562; -pub const SYS_getrandom = 563; -pub const SYS_MAXSYSCALL = 564; diff --git a/std/os/freebsd/x86_64.zig b/std/os/freebsd/x86_64.zig deleted file mode 100644 index 509075386f..0000000000 --- a/std/os/freebsd/x86_64.zig +++ /dev/null @@ -1,136 +0,0 @@ -const freebsd = @import("index.zig"); -const socklen_t = freebsd.socklen_t; -const iovec = freebsd.iovec; - -pub const SYS_sbrk = 69; - -pub fn syscall0(number: usize) usize { - return asm volatile ("syscall" - : [ret] "={rax}" (-> usize) - : [number] "{rax}" (number) - : "rcx", "r11" - ); -} - -pub fn syscall1(number: usize, arg1: usize) usize { - return asm volatile ("syscall" - : [ret] "={rax}" (-> usize) - : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1) - : "rcx", "r11" - ); -} - -pub fn syscall2(number: usize, arg1: usize, arg2: usize) usize { - return asm volatile ("syscall" - : [ret] "={rax}" (-> usize) - : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1), - [arg2] "{rsi}" (arg2) - : "rcx", "r11" - ); -} - -pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize { - return asm volatile ("syscall" - : [ret] "={rax}" (-> usize) - : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1), - [arg2] "{rsi}" (arg2), - [arg3] "{rdx}" (arg3) - : "rcx", "r11" - ); -} - -pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { - return asm volatile ("syscall" - : [ret] "={rax}" (-> usize) - : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1), - [arg2] "{rsi}" (arg2), - [arg3] "{rdx}" (arg3), - [arg4] "{r10}" (arg4) - : "rcx", "r11" - ); -} - -pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { - return asm volatile ("syscall" - : [ret] "={rax}" (-> usize) - : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1), - [arg2] "{rsi}" (arg2), - [arg3] "{rdx}" (arg3), - [arg4] "{r10}" (arg4), - [arg5] "{r8}" (arg5) - : "rcx", "r11" - ); -} - -pub fn syscall6( - number: usize, - arg1: usize, - arg2: usize, - arg3: usize, - arg4: usize, - arg5: usize, - arg6: usize, -) usize { - return asm volatile ("syscall" - : [ret] "={rax}" (-> usize) - : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1), - [arg2] "{rsi}" (arg2), - [arg3] "{rdx}" (arg3), - [arg4] "{r10}" (arg4), - [arg5] "{r8}" (arg5), - [arg6] "{r9}" (arg6) - : "rcx", "r11" - ); -} - -pub nakedcc fn restore_rt() void { - asm volatile ("syscall" - : - : [number] "{rax}" (usize(SYS_rt_sigreturn)) - : "rcx", "r11" - ); -} - -pub const msghdr = extern struct { - msg_name: *u8, - msg_namelen: socklen_t, - msg_iov: *iovec, - msg_iovlen: i32, - __pad1: i32, - msg_control: *u8, - msg_controllen: socklen_t, - __pad2: socklen_t, - msg_flags: i32, -}; - -/// Renamed to Stat to not conflict with the stat function. -pub const Stat = extern struct { - dev: u64, - ino: u64, - nlink: usize, - - mode: u32, - uid: u32, - gid: u32, - __pad0: u32, - rdev: u64, - size: i64, - blksize: isize, - blocks: i64, - - atim: timespec, - mtim: timespec, - ctim: timespec, - __unused: [3]isize, -}; - -pub const timespec = extern struct { - tv_sec: isize, - tv_nsec: isize, -}; From 5ea37f6e8c9226ec02fbc95cc5c6d06a8e9ee6f7 Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Mon, 17 Dec 2018 22:06:28 -0200 Subject: [PATCH 02/34] freebsd: add getdirentries --- std/c/freebsd.zig | 12 +++++++++ std/os/freebsd/index.zig | 5 ++++ std/os/index.zig | 53 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/std/c/freebsd.zig b/std/c/freebsd.zig index a97cf52eb9..fbcd6236f0 100644 --- a/std/c/freebsd.zig +++ b/std/c/freebsd.zig @@ -13,6 +13,7 @@ pub extern "c" fn kevent( pub extern "c" fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int; pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int; pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int; +pub extern "c" fn getdirentries(fd: c_int, buf_ptr: [*]u8, nbytes: usize, basep: *i64) usize; /// Renamed from `kevent` to `Kevent` to avoid conflict with function name. pub const Kevent = extern struct { @@ -66,3 +67,14 @@ pub const timespec = extern struct { tv_sec: isize, tv_nsec: isize, }; + +pub const dirent = extern struct { + d_fileno: usize, + d_off: i64, + d_reclen: u64, + d_type: u8, + d_pad0: u8, + d_namlen: u16, + d_pad1: u16, + d_name: [256]u8, +}; diff --git a/std/os/freebsd/index.zig b/std/os/freebsd/index.zig index 975479c1e0..880a49b4a8 100644 --- a/std/os/freebsd/index.zig +++ b/std/os/freebsd/index.zig @@ -562,6 +562,10 @@ pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize { return arch.syscall3(SYS_getdents, @bitCast(usize, isize(fd)), @ptrToInt(dirp), count); } +pub fn getdirentries(fd: i32, buf_ptr: [*]u8, buf_len: usize, basep: *i64) usize { + return errnoWrap(@bitCast(isize, c.getdirentries(fd, buf_ptr, buf_len, basep))); +} + pub fn isatty(fd: i32) bool { var wsz: winsize = undefined; return arch.syscall3(SYS_ioctl, @bitCast(usize, isize(fd)), TIOCGWINSZ, @ptrToInt(&wsz)) == 0; @@ -743,6 +747,7 @@ pub fn raise(sig: i32) usize { } pub const Stat = c.Stat; +pub const dirent = c.dirent; pub const timespec = c.timespec; pub fn fstat(fd: i32, stat_buf: *Stat) usize { diff --git a/std/os/index.zig b/std/os/index.zig index be82ad4716..778ab156b0 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -1753,8 +1753,57 @@ pub const Dir = struct { } fn nextFreebsd(self: *Dir) !?Entry { - //self.handle.buf = try self.allocator.alloc(u8, page_size); - @compileError("TODO implement dirs for FreeBSD"); + start_over: while (true) { + if (self.handle.index >= self.handle.end_index) { + if (self.handle.buf.len == 0) { + self.handle.buf = try self.allocator.alloc(u8, page_size); + } + + while (true) { + const result = posix.getdirentries(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len, &self.handle.seek); + const err = posix.getErrno(result); + if (err > 0) { + switch (err) { + posix.EBADF, posix.EFAULT, posix.ENOTDIR => unreachable, + posix.EINVAL => { + self.handle.buf = try self.allocator.realloc(u8, self.handle.buf, self.handle.buf.len * 2); + continue; + }, + else => return unexpectedErrorPosix(err), + } + } + if (result == 0) return null; + self.handle.index = 0; + self.handle.end_index = result; + break; + } + } + const freebsd_entry = @ptrCast(*align(1) posix.dirent, &self.handle.buf[self.handle.index]); + const next_index = self.handle.index + freebsd_entry.d_reclen; + self.handle.index = next_index; + + const name = @ptrCast([*]u8, &freebsd_entry.d_name)[0..freebsd_entry.d_namlen]; + + if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..")) { + continue :start_over; + } + + const entry_kind = switch (freebsd_entry.d_type) { + posix.DT_BLK => Entry.Kind.BlockDevice, + posix.DT_CHR => Entry.Kind.CharacterDevice, + posix.DT_DIR => Entry.Kind.Directory, + posix.DT_FIFO => Entry.Kind.NamedPipe, + posix.DT_LNK => Entry.Kind.SymLink, + posix.DT_REG => Entry.Kind.File, + posix.DT_SOCK => Entry.Kind.UnixDomainSocket, + posix.DT_WHT => Entry.Kind.Whiteout, + else => Entry.Kind.Unknown, + }; + return Entry{ + .name = name, + .kind = entry_kind, + }; + } } }; From 0273fbf710f98854f3331c0810cd2f31f20d2fb5 Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Mon, 17 Dec 2018 22:07:21 -0200 Subject: [PATCH 03/34] freebsd: add access --- std/os/freebsd/index.zig | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/std/os/freebsd/index.zig b/std/os/freebsd/index.zig index 880a49b4a8..73573d1d21 100644 --- a/std/os/freebsd/index.zig +++ b/std/os/freebsd/index.zig @@ -95,6 +95,13 @@ pub const SIGLIBRT = 33; pub const SIGRTMIN = 65; pub const SIGRTMAX = 126; +// access function +pub const F_OK = 0; // test for existence of file +pub const X_OK = 1; // test for execute or search permission +pub const W_OK = 2; // test for write permission +pub const R_OK = 4; // test for read permission + + pub const O_RDONLY = 0o0; pub const O_WRONLY = 0o1; pub const O_RDWR = 0o2; @@ -554,6 +561,10 @@ pub fn fork() usize { return arch.syscall0(SYS_fork); } +pub fn access(path: [*]const u8, mode: u32) usize { + return errnoWrap(c.access(path, mode)); +} + pub fn getcwd(buf: [*]u8, size: usize) usize { return arch.syscall2(SYS___getcwd, @ptrToInt(buf), size); } From 1fc56b82ad6f1060ec4b2074c16accfe0327a4b7 Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Tue, 18 Dec 2018 00:19:20 -0200 Subject: [PATCH 04/34] freebsd: link against libc Since the stable kernel ABI is through libc #1759 --- src/analyze.cpp | 2 +- src/codegen.cpp | 3 ++- std/special/bootstrap.zig | 15 ++++----------- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index 46686ce772..064cf11cc1 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -6366,7 +6366,7 @@ LinkLib *add_link_lib(CodeGen *g, Buf *name) { if (is_libc && g->libc_link_lib != nullptr) return g->libc_link_lib; - if (g->enable_cache && is_libc && g->zig_target.os != OsMacOSX && g->zig_target.os != OsIOS) { + if (g->enable_cache && is_libc && g->zig_target.os != OsMacOSX && g->zig_target.os != OsIOS && g->zig_target.os != OsFreeBSD) { fprintf(stderr, "TODO linking against libc is currently incompatible with `--cache on`.\n" "Zig is not yet capable of determining whether the libc installation has changed on subsequent builds.\n"); exit(1); diff --git a/src/codegen.cpp b/src/codegen.cpp index e37703d5f0..e2d23513ff 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -178,7 +178,8 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out // On Darwin/MacOS/iOS, we always link libSystem which contains libc. if (g->zig_target.os == OsMacOSX || - g->zig_target.os == OsIOS) + g->zig_target.os == OsIOS || + g->zig_target.os == OsFreeBSD) { g->libc_link_lib = create_link_lib(buf_create_from_str("c")); g->link_libs_list.append(g->libc_link_lib); diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig index a15be317ab..129bde913f 100644 --- a/std/special/bootstrap.zig +++ b/std/special/bootstrap.zig @@ -20,17 +20,10 @@ comptime { nakedcc fn _start() noreturn { switch (builtin.arch) { - builtin.Arch.x86_64 => switch (builtin.os) { - builtin.Os.freebsd => { - argc_ptr = asm ("lea (%%rdi), %[argc]" - : [argc] "=r" (-> [*]usize) - ); - }, - else => { - argc_ptr = asm ("lea (%%rsp), %[argc]" - : [argc] "=r" (-> [*]usize) - ); - }, + builtin.Arch.x86_64 => { + argc_ptr = asm ("lea (%%rsp), %[argc]" + : [argc] "=r" (-> [*]usize) + ); }, builtin.Arch.i386 => { argc_ptr = asm ("lea (%%esp), %[argc]" From 6cfcdbde2b902476863cb912190f20ce5e02277c Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Tue, 18 Dec 2018 00:19:52 -0200 Subject: [PATCH 05/34] freebsd: link against libc++ All supported versions of FreeBSD have libc++ in the base system. --- build.zig | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/build.zig b/build.zig index e411ae8b21..2a51203ff7 100644 --- a/build.zig +++ b/build.zig @@ -293,11 +293,17 @@ fn configureStage2(b: *Builder, exe: var, ctx: Context) !void { try addCxxKnownPath(b, ctx, exe, "libstdc++.a", \\Unable to determine path to libstdc++.a \\On Fedora, install libstdc++-static and try again. - \\ ); exe.linkSystemLibrary("pthread"); - } else if (exe.target.isDarwin() or exe.target.isFreeBSD()) { + } else if (exe.target.isFreeBSD()) { + try addCxxKnownPath(b, ctx, exe, "libc++.a", null); + exe.linkSystemLibrary("pthread"); + // TODO LLD cannot perform this link. + // See https://github.com/ziglang/zig/issues/1535 + exe.enableSystemLinkerHack(); + } + else if (exe.target.isDarwin()) { if (addCxxKnownPath(b, ctx, exe, "libgcc_eh.a", "")) { // Compiler is GCC. try addCxxKnownPath(b, ctx, exe, "libstdc++.a", null); From 11ced4f99d95ec144d9dbb79ead335b571f714fe Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Tue, 18 Dec 2018 01:32:35 -0200 Subject: [PATCH 06/34] freebsd: use libc interface instead system calls Remove all syscalls references * dup2() * chdir() * execve() * fork() * getcwd() * isatty() * readlink() * mkdir() * mmap() * munmap() * read() * rmdir() * symlink() * pread() * write() * pwrite() * rename() * open() * close() * lseek() * exit() * unlink() * waitpid() * nanosleep() * setreuid() * setregid() * raise() * fstat() * pipe() * added pipe2() extern c fn --- std/c/freebsd.zig | 2 + std/os/freebsd/index.zig | 114 +++++++++++++++++++-------------------- 2 files changed, 57 insertions(+), 59 deletions(-) diff --git a/std/c/freebsd.zig b/std/c/freebsd.zig index fbcd6236f0..32cd48748c 100644 --- a/std/c/freebsd.zig +++ b/std/c/freebsd.zig @@ -14,6 +14,8 @@ pub extern "c" fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlen pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int; pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int; pub extern "c" fn getdirentries(fd: c_int, buf_ptr: [*]u8, nbytes: usize, basep: *i64) usize; +pub extern "c" fn pipe2(arg0: *[2]c_int, arg1: u32) c_int; +pub extern "c" fn getrandom(buf: [*]u8, count: usize, flags: u32) c_int; /// Renamed from `kevent` to `Kevent` to avoid conflict with function name. pub const Kevent = extern struct { diff --git a/std/os/freebsd/index.zig b/std/os/freebsd/index.zig index 73573d1d21..9191dc3219 100644 --- a/std/os/freebsd/index.zig +++ b/std/os/freebsd/index.zig @@ -1,14 +1,11 @@ -const assert = @import("../debug.zig").assert; const builtin = @import("builtin"); -const arch = switch (builtin.arch) { - builtin.Arch.x86_64 => @import("x86_64.zig"), - else => @compileError("unsupported arch"), -}; -pub use @import("syscall.zig"); + pub use @import("errno.zig"); const std = @import("../../index.zig"); const c = std.c; + +const assert = std.debug.assert; const maxInt = std.math.maxInt; pub const Kevent = c.Kevent; @@ -546,19 +543,19 @@ pub fn getErrno(r: usize) usize { } pub fn dup2(old: i32, new: i32) usize { - return arch.syscall2(SYS_dup2, @bitCast(usize, isize(old)), @bitCast(usize, isize(new))); + return errnoWrap(c.dup2(old, new)); } pub fn chdir(path: [*]const u8) usize { - return arch.syscall1(SYS_chdir, @ptrToInt(path)); + return errnoWrap(c.chdir(path)); } pub fn execve(path: [*]const u8, argv: [*]const ?[*]const u8, envp: [*]const ?[*]const u8) usize { - return arch.syscall3(SYS_execve, @ptrToInt(path), @ptrToInt(argv), @ptrToInt(envp)); + return errnoWrap(c.execve(path, argv, envp)); } pub fn fork() usize { - return arch.syscall0(SYS_fork); + return errnoWrap(c.fork()); } pub fn access(path: [*]const u8, mode: u32) usize { @@ -566,7 +563,7 @@ pub fn access(path: [*]const u8, mode: u32) usize { } pub fn getcwd(buf: [*]u8, size: usize) usize { - return arch.syscall2(SYS___getcwd, @ptrToInt(buf), size); + return if (c.getcwd(buf, size) == null) @bitCast(usize, -isize(c._errno().*)) else 0; } pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize { @@ -578,40 +575,48 @@ pub fn getdirentries(fd: i32, buf_ptr: [*]u8, buf_len: usize, basep: *i64) usize } pub fn isatty(fd: i32) bool { - var wsz: winsize = undefined; - return arch.syscall3(SYS_ioctl, @bitCast(usize, isize(fd)), TIOCGWINSZ, @ptrToInt(&wsz)) == 0; + return c.isatty(fd) != 0; } pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize { - return arch.syscall3(SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len); + return errnoWrap(c.readlink(path, buf_ptr, buf_len)); } pub fn mkdir(path: [*]const u8, mode: u32) usize { - return arch.syscall2(SYS_mkdir, @ptrToInt(path), mode); + return errnoWrap(c.mkdir(path, mode)); } -pub fn mmap(address: ?*u8, length: usize, prot: usize, flags: usize, fd: i32, offset: isize) usize { - return arch.syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, @bitCast(usize, isize(fd)), @bitCast(usize, offset)); +pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize { + const ptr_result = c.mmap( + @ptrCast(*c_void, address), + length, + @bitCast(c_int, @intCast(c_uint, prot)), + @bitCast(c_int, c_uint(flags)), + fd, + offset, + ); + const isize_result = @bitCast(isize, @ptrToInt(ptr_result)); + return errnoWrap(isize_result); } pub fn munmap(address: usize, length: usize) usize { - return arch.syscall2(SYS_munmap, address, length); + return errnoWrap(c.munmap(@intToPtr(*c_void, address), length)); } -pub fn read(fd: i32, buf: [*]u8, count: usize) usize { - return arch.syscall3(SYS_read, @bitCast(usize, isize(fd)), @ptrToInt(buf), count); +pub fn read(fd: i32, buf: [*]u8, nbyte: usize) usize { + return errnoWrap(c.read(fd, @ptrCast(*c_void, buf), nbyte)); } pub fn rmdir(path: [*]const u8) usize { - return arch.syscall1(SYS_rmdir, @ptrToInt(path)); + return errnoWrap(c.rmdir(path)); } pub fn symlink(existing: [*]const u8, new: [*]const u8) usize { - return arch.syscall2(SYS_symlink, @ptrToInt(existing), @ptrToInt(new)); + return errnoWrap(c.symlink(existing, new)); } -pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize { - return arch.syscall4(SYS_pread, @bitCast(usize, isize(fd)), @ptrToInt(buf), count, offset); +pub fn pread(fd: i32, buf: [*]u8, nbyte: usize, offset: u64) usize { + return errnoWrap(c.pread(fd, @ptrCast(*c_void, buf), nbyte, offset)); } pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: usize) usize { @@ -622,16 +627,17 @@ pub fn pipe(fd: *[2]i32) usize { return pipe2(fd, 0); } -pub fn pipe2(fd: *[2]i32, flags: usize) usize { - return arch.syscall2(SYS_pipe2, @ptrToInt(fd), flags); +pub fn pipe2(fd: *[2]i32, flags: u32) usize { + comptime assert(i32.bit_count == c_int.bit_count); + return errnoWrap(c.pipe2(@ptrCast(*[2]c_int, fd), flags)); } -pub fn write(fd: i32, buf: [*]const u8, count: usize) usize { - return arch.syscall3(SYS_write, @bitCast(usize, isize(fd)), @ptrToInt(buf), count); +pub fn write(fd: i32, buf: [*]const u8, nbyte: usize) usize { + return errnoWrap(c.write(fd, @ptrCast(*const c_void, buf), nbyte)); } -pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize { - return arch.syscall4(SYS_pwrite, @bitCast(usize, isize(fd)), @ptrToInt(buf), count, offset); +pub fn pwrite(fd: i32, buf: [*]const u8, nbyte: usize, offset: u64) usize { + return errnoWrap(c.pwrite(fd, @ptrCast(*const c_void, buf), nbyte, offset)); } pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: usize) usize { @@ -639,11 +645,11 @@ pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: usize) } pub fn rename(old: [*]const u8, new: [*]const u8) usize { - return arch.syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new)); + return errnoWrap(c.rename(old, new)); } -pub fn open(path: [*]const u8, flags: u32, perm: usize) usize { - return arch.syscall3(SYS_open, @ptrToInt(path), flags, perm); +pub fn open(path: [*]const u8, flags: u32, mode: usize) usize { + return errnoWrap(c.open(path, @bitCast(c_int, flags), mode)); } pub fn create(path: [*]const u8, perm: usize) usize { @@ -655,20 +661,19 @@ pub fn openat(dirfd: i32, path: [*]const u8, flags: usize, mode: usize) usize { } pub fn close(fd: i32) usize { - return arch.syscall1(SYS_close, @bitCast(usize, isize(fd))); + return errnoWrap(c.close(fd)); } -pub fn lseek(fd: i32, offset: isize, ref_pos: usize) usize { - return arch.syscall3(SYS_lseek, @bitCast(usize, isize(fd)), @bitCast(usize, offset), ref_pos); +pub fn lseek(fd: i32, offset: isize, whence: c_int) usize { + return errnoWrap(c.lseek(fd, offset, whence)); } -pub fn exit(status: i32) noreturn { - _ = arch.syscall1(SYS_exit, @bitCast(usize, isize(status))); - unreachable; +pub fn exit(code: i32) noreturn { + c.exit(code); } pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize { - return arch.syscall3(SYS_getrandom, @ptrToInt(buf), count, usize(flags)); + return errnoWrap(c.getrandom(buf, count, flags)); } pub fn kill(pid: i32, sig: i32) usize { @@ -676,15 +681,16 @@ pub fn kill(pid: i32, sig: i32) usize { } pub fn unlink(path: [*]const u8) usize { - return arch.syscall1(SYS_unlink, @ptrToInt(path)); + return errnoWrap(c.unlink(path)); } -pub fn waitpid(pid: i32, status: *i32, options: i32) usize { - return arch.syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0); +pub fn waitpid(pid: i32, status: *i32, options: u32) usize { + comptime assert(i32.bit_count == c_int.bit_count); + return errnoWrap(c.waitpid(pid, @ptrCast(*c_int, status), @bitCast(c_int, options))); } pub fn nanosleep(req: *const timespec, rem: ?*timespec) usize { - return arch.syscall2(SYS_nanosleep, @ptrToInt(req), @ptrToInt(rem)); + return errnoWrap(c.nanosleep(req, rem)); } pub fn setuid(uid: u32) usize { @@ -696,11 +702,11 @@ pub fn setgid(gid: u32) usize { } pub fn setreuid(ruid: u32, euid: u32) usize { - return arch.syscall2(SYS_setreuid, ruid, euid); + return errnoWrap(c.setreuid(ruid, euid)); } pub fn setregid(rgid: u32, egid: u32) usize { - return arch.syscall2(SYS_setregid, rgid, egid); + return errnoWrap(c.setregid(rgid, egid)); } const NSIG = 32; @@ -745,26 +751,16 @@ pub const sigset_t = extern struct { }; pub fn raise(sig: i32) usize { - // TODO have a chat with the freebsd folks and make sure there's no bug in - // their libc. musl-libc blocks signals in between these calls because - // if a signal handler runs and forks between the gettid and sending the - // signal, the parent will get 2 signals, one from itself and one from the child - // if the protection does not belong here, then it belongs in abort(), - // like it does in freebsd's libc. - var id: usize = undefined; - const rc = arch.syscall1(SYS_thr_self, @ptrToInt(&id)); - if (getErrno(rc) != 0) return rc; - return arch.syscall2(SYS_thr_kill, id, @bitCast(usize, isize(sig))); + return errnoWrap(c.raise(sig)); } pub const Stat = c.Stat; pub const dirent = c.dirent; pub const timespec = c.timespec; -pub fn fstat(fd: i32, stat_buf: *Stat) usize { - return arch.syscall2(SYS_fstat, @bitCast(usize, isize(fd)), @ptrToInt(stat_buf)); +pub fn fstat(fd: i32, buf: *c.Stat) usize { + return errnoWrap(c.fstat(fd, buf)); } - pub const iovec = extern struct { iov_base: [*]u8, iov_len: usize, From 1811e7e6c96844a8381e6a69017948cae0b8b261 Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Tue, 18 Dec 2018 02:42:54 -0200 Subject: [PATCH 07/34] freebsd: remove getrandom dependency from libc The system call getrandom(2) just landed on FreeBSD 12, so if we want to support some earlier version or at least FreeBSD 11, we can't depend on the system call. --- std/c/freebsd.zig | 1 - std/os/freebsd/index.zig | 4 ---- std/os/index.zig | 4 ++-- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/std/c/freebsd.zig b/std/c/freebsd.zig index 32cd48748c..86213ee1b3 100644 --- a/std/c/freebsd.zig +++ b/std/c/freebsd.zig @@ -15,7 +15,6 @@ pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usi pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int; pub extern "c" fn getdirentries(fd: c_int, buf_ptr: [*]u8, nbytes: usize, basep: *i64) usize; pub extern "c" fn pipe2(arg0: *[2]c_int, arg1: u32) c_int; -pub extern "c" fn getrandom(buf: [*]u8, count: usize, flags: u32) c_int; /// Renamed from `kevent` to `Kevent` to avoid conflict with function name. pub const Kevent = extern struct { diff --git a/std/os/freebsd/index.zig b/std/os/freebsd/index.zig index 9191dc3219..9f9f7f9de0 100644 --- a/std/os/freebsd/index.zig +++ b/std/os/freebsd/index.zig @@ -672,10 +672,6 @@ pub fn exit(code: i32) noreturn { c.exit(code); } -pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize { - return errnoWrap(c.getrandom(buf, count, flags)); -} - pub fn kill(pid: i32, sig: i32) usize { return arch.syscall2(SYS_kill, @bitCast(usize, isize(pid)), @bitCast(usize, isize(sig))); } diff --git a/std/os/index.zig b/std/os/index.zig index 778ab156b0..b49b46e8e5 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -103,7 +103,7 @@ const math = std.math; /// library implementation. pub fn getRandomBytes(buf: []u8) !void { switch (builtin.os) { - Os.linux, Os.freebsd => while (true) { + Os.linux => while (true) { // TODO check libc version and potentially call c.getrandom. // See #397 const errno = posix.getErrno(posix.getrandom(buf.ptr, buf.len, 0)); @@ -116,7 +116,7 @@ pub fn getRandomBytes(buf: []u8) !void { else => return unexpectedErrorPosix(errno), } }, - Os.macosx, Os.ios => return getRandomBytesDevURandom(buf), + Os.macosx, Os.ios, Os.freebsd => return getRandomBytesDevURandom(buf), Os.windows => { // Call RtlGenRandom() instead of CryptGetRandom() on Windows // https://github.com/rust-lang-nursery/rand/issues/111 From 9900f94afe5556db048b4b147bbf75ff0e0c9974 Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Tue, 18 Dec 2018 16:22:20 -0200 Subject: [PATCH 08/34] freebsd: use sysctl to get the current executable path FreeBSD doesn't mount procfs as default on the base system, so we can't depend on it to get the current path, In this case, we use sysctl(3) to retrieves the system information and get the same information. - CTL_KERN: High kernel limits - KERN_PROC: Return selected information about specific running processes. - KERN_PROC_PATHNAME: The path of the process - Process ID: a process ID of -1 implies the current process. --- std/os/freebsd/index.zig | 6 ++++++ std/os/index.zig | 15 ++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/std/os/freebsd/index.zig b/std/os/freebsd/index.zig index 9f9f7f9de0..47f4e8e267 100644 --- a/std/os/freebsd/index.zig +++ b/std/os/freebsd/index.zig @@ -9,6 +9,12 @@ const assert = std.debug.assert; const maxInt = std.math.maxInt; pub const Kevent = c.Kevent; +pub const CTL_KERN = 1; +pub const CTL_DEBUG = 5; + +pub const KERN_PROC = 14; // struct: process entries +pub const KERN_PROC_PATHNAME = 12; // path to executable + pub const PATH_MAX = 1024; pub const STDIN_FILENO = 0; diff --git a/std/os/index.zig b/std/os/index.zig index b49b46e8e5..817f11493c 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -2291,7 +2291,20 @@ pub fn selfExePathW(out_buffer: *[windows_util.PATH_MAX_WIDE]u16) ![]u16 { pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) ![]u8 { switch (builtin.os) { Os.linux => return readLink(out_buffer, "/proc/self/exe"), - Os.freebsd => return readLink(out_buffer, "/proc/curproc/file"), + Os.freebsd => { + var mib = [4]c_int{ posix.CTL_KERN, posix.KERN_PROC, posix.KERN_PROC_PATHNAME, -1}; + var out_len: usize = out_buffer.len; + const err = posix.getErrno(posix.sysctl(&mib, 4, out_buffer, &out_len, null, 0)); + + if (err == 0 ) return mem.toSlice(u8, out_buffer); + + return switch (err) { + posix.EFAULT => error.BadAdress, + posix.EPERM => error.PermissionDenied, + else => unexpectedErrorPosix(err), + }; + + }, Os.windows => { var utf16le_buf: [windows_util.PATH_MAX_WIDE]u16 = undefined; const utf16le_slice = try selfExePathW(&utf16le_buf); From e5b4748101ca40f5dc4082ce2cb46df0c8607417 Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Tue, 18 Dec 2018 16:34:51 -0200 Subject: [PATCH 09/34] freebsd: initial stack trace Stack trace is partially working, with only a few symbols missing. Uses the same functions that we use in Linux to get the necessary debug info. --- std/debug/index.zig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/std/debug/index.zig b/std/debug/index.zig index 73c6ea7b56..2f0c55cb3d 100644 --- a/std/debug/index.zig +++ b/std/debug/index.zig @@ -264,7 +264,7 @@ pub fn writeCurrentStackTraceWindows( pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void { switch (builtin.os) { builtin.Os.macosx => return printSourceAtAddressMacOs(debug_info, out_stream, address, tty_color), - builtin.Os.linux => return printSourceAtAddressLinux(debug_info, out_stream, address, tty_color), + builtin.Os.linux, builtin.Os.freebsd => return printSourceAtAddressLinux(debug_info, out_stream, address, tty_color), builtin.Os.windows => return printSourceAtAddressWindows(debug_info, out_stream, address, tty_color), else => return error.UnsupportedOperatingSystem, } @@ -717,7 +717,7 @@ pub const OpenSelfDebugInfoError = error{ pub fn openSelfDebugInfo(allocator: *mem.Allocator) !DebugInfo { switch (builtin.os) { - builtin.Os.linux => return openSelfDebugInfoLinux(allocator), + builtin.Os.linux, builtin.Os.freebsd => return openSelfDebugInfoLinux(allocator), builtin.Os.macosx, builtin.Os.ios => return openSelfDebugInfoMacOs(allocator), builtin.Os.windows => return openSelfDebugInfoWindows(allocator), else => return error.UnsupportedOperatingSystem, @@ -1141,8 +1141,7 @@ pub const DebugInfo = switch (builtin.os) { sect_contribs: []pdb.SectionContribEntry, modules: []Module, }, - builtin.Os.linux => DwarfInfo, - builtin.Os.freebsd => struct {}, + builtin.Os.linux, builtin.Os.freebsd => DwarfInfo, else => @compileError("Unsupported OS"), }; From 054c7ab18a8c9527414164bf68aa3564c29e8931 Mon Sep 17 00:00:00 2001 From: Greg V Date: Thu, 20 Dec 2018 23:54:09 +0300 Subject: [PATCH 10/34] Fix stat/timespec definitions for FreeBSD --- std/c/freebsd.zig | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/std/c/freebsd.zig b/std/c/freebsd.zig index 86213ee1b3..72969fa826 100644 --- a/std/c/freebsd.zig +++ b/std/c/freebsd.zig @@ -50,18 +50,23 @@ pub const Stat = extern struct { nlink: usize, mode: u32, + __pad0: u16, uid: u32, gid: u32, - __pad0: u32, + __pad1: u32, rdev: u64, - size: i64, - blksize: isize, - blocks: i64, atim: timespec, mtim: timespec, ctim: timespec, - __unused: [3]isize, + birthtim: timespec, + + size: i64, + blocks: i64, + blksize: isize, + flags: u32, + gen: u64, + __spare: [10]u64, }; pub const timespec = extern struct { @@ -72,7 +77,7 @@ pub const timespec = extern struct { pub const dirent = extern struct { d_fileno: usize, d_off: i64, - d_reclen: u64, + d_reclen: u16, d_type: u8, d_pad0: u8, d_namlen: u16, From 76efc462e7ea90be02fd28254f8c452ba994ea8a Mon Sep 17 00:00:00 2001 From: Greg V Date: Thu, 20 Dec 2018 23:55:44 +0300 Subject: [PATCH 11/34] Add preadv/pwritev on FreeBSD --- std/c/freebsd.zig | 2 ++ std/os/freebsd/index.zig | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/std/c/freebsd.zig b/std/c/freebsd.zig index 72969fa826..f30d57da3b 100644 --- a/std/c/freebsd.zig +++ b/std/c/freebsd.zig @@ -15,6 +15,8 @@ pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usi pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int; pub extern "c" fn getdirentries(fd: c_int, buf_ptr: [*]u8, nbytes: usize, basep: *i64) usize; pub extern "c" fn pipe2(arg0: *[2]c_int, arg1: u32) c_int; +pub extern "c" fn preadv(fd: c_int, iov: *const c_void, iovcnt: c_int, offset: usize) isize; +pub extern "c" fn pwritev(fd: c_int, iov: *const c_void, iovcnt: c_int, offset: usize) isize; /// Renamed from `kevent` to `Kevent` to avoid conflict with function name. pub const Kevent = extern struct { diff --git a/std/os/freebsd/index.zig b/std/os/freebsd/index.zig index 47f4e8e267..1e08afe26d 100644 --- a/std/os/freebsd/index.zig +++ b/std/os/freebsd/index.zig @@ -626,7 +626,7 @@ pub fn pread(fd: i32, buf: [*]u8, nbyte: usize, offset: u64) usize { } pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: usize) usize { - return arch.syscall4(SYS_preadv, @bitCast(usize, isize(fd)), @ptrToInt(iov), count, offset); + return errnoWrap(c.preadv(fd, @ptrCast(*const c_void, iov), @intCast(c_int, count), offset)); } pub fn pipe(fd: *[2]i32) usize { @@ -647,7 +647,7 @@ pub fn pwrite(fd: i32, buf: [*]const u8, nbyte: usize, offset: u64) usize { } pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: usize) usize { - return arch.syscall4(SYS_pwritev, @bitCast(usize, isize(fd)), @ptrToInt(iov), count, offset); + return errnoWrap(c.pwritev(fd, @ptrCast(*const c_void, iov), @intCast(c_int, count), offset)); } pub fn rename(old: [*]const u8, new: [*]const u8) usize { From 46a0f60e4c0c91f840982cb98066d60301624548 Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Thu, 20 Dec 2018 20:57:58 -0200 Subject: [PATCH 12/34] freebsd: use realpath() to resolve symbolic links --- std/os/path.zig | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/std/os/path.zig b/std/os/path.zig index af767b0dca..ff70bc039e 100644 --- a/std/os/path.zig +++ b/std/os/path.zig @@ -1161,7 +1161,7 @@ pub fn realC(out_buffer: *[os.MAX_PATH_BYTES]u8, pathname: [*]const u8) RealErro const pathname_w = try windows_util.cStrToPrefixedFileW(pathname); return realW(out_buffer, pathname_w); }, - Os.macosx, Os.ios => { + Os.freebsd, Os.macosx, Os.ios => { // TODO instead of calling the libc function here, port the implementation to Zig const err = posix.getErrno(posix.realpath(pathname, out_buffer)); switch (err) { @@ -1188,15 +1188,6 @@ pub fn realC(out_buffer: *[os.MAX_PATH_BYTES]u8, pathname: [*]const u8) RealErro return os.readLinkC(out_buffer, proc_path.ptr); }, - Os.freebsd => { // XXX requires fdescfs - const fd = try os.posixOpenC(pathname, posix.O_PATH | posix.O_NONBLOCK | posix.O_CLOEXEC, 0); - defer os.close(fd); - - var buf: ["/dev/fd/-2147483648\x00".len]u8 = undefined; - const proc_path = fmt.bufPrint(buf[0..], "/dev/fd/{}\x00", fd) catch unreachable; - - return os.readLinkC(out_buffer, proc_path.ptr); - }, else => @compileError("TODO implement os.path.real for " ++ @tagName(builtin.os)), } } From a6f33e3dc56eab57ee148c2ec7592540470d582c Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Thu, 20 Dec 2018 21:05:31 -0200 Subject: [PATCH 13/34] freebsd: add realpath to freebsd/index.zig --- std/os/freebsd/index.zig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/std/os/freebsd/index.zig b/std/os/freebsd/index.zig index 1e08afe26d..f1533ec098 100644 --- a/std/os/freebsd/index.zig +++ b/std/os/freebsd/index.zig @@ -580,6 +580,10 @@ pub fn getdirentries(fd: i32, buf_ptr: [*]u8, buf_len: usize, basep: *i64) usize return errnoWrap(@bitCast(isize, c.getdirentries(fd, buf_ptr, buf_len, basep))); } +pub fn realpath(noalias filename: [*]const u8, noalias resolved_name: [*]u8) usize { + return if (c.realpath(filename, resolved_name) == null) @bitCast(usize, -isize(c._errno().*)) else 0; +} + pub fn isatty(fd: i32) bool { return c.isatty(fd) != 0; } From c156d51d555441b41f512d854529ea28db95dd50 Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Thu, 20 Dec 2018 21:44:18 -0200 Subject: [PATCH 14/34] freebsd: remove system linker hack --- build.zig | 3 --- 1 file changed, 3 deletions(-) diff --git a/build.zig b/build.zig index 2a51203ff7..16185eebf4 100644 --- a/build.zig +++ b/build.zig @@ -299,9 +299,6 @@ fn configureStage2(b: *Builder, exe: var, ctx: Context) !void { } else if (exe.target.isFreeBSD()) { try addCxxKnownPath(b, ctx, exe, "libc++.a", null); exe.linkSystemLibrary("pthread"); - // TODO LLD cannot perform this link. - // See https://github.com/ziglang/zig/issues/1535 - exe.enableSystemLinkerHack(); } else if (exe.target.isDarwin()) { if (addCxxKnownPath(b, ctx, exe, "libgcc_eh.a", "")) { From c26f543970771acba5484553e2c10ec90b3c39eb Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Fri, 21 Dec 2018 15:04:55 -0200 Subject: [PATCH 15/34] freebsd: fix Stat mode type --- std/c/freebsd.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/c/freebsd.zig b/std/c/freebsd.zig index f30d57da3b..9aa1859988 100644 --- a/std/c/freebsd.zig +++ b/std/c/freebsd.zig @@ -51,7 +51,7 @@ pub const Stat = extern struct { ino: u64, nlink: usize, - mode: u32, + mode: u16, __pad0: u16, uid: u32, gid: u32, From 280187031a68c577e84c72add037271153d27c62 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 23 Dec 2018 18:03:22 -0500 Subject: [PATCH 16/34] tests: make type info tests not depend on builtin.Os enum --- test/cases/type_info.zig | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/cases/type_info.zig b/test/cases/type_info.zig index 6f99268c08..cec532d5d3 100644 --- a/test/cases/type_info.zig +++ b/test/cases/type_info.zig @@ -144,15 +144,20 @@ test "type info: enum info" { } fn testEnum() void { - const Os = @import("builtin").Os; + const Os = enum { + Windows, + Macos, + Linux, + FreeBSD, + }; const os_info = @typeInfo(Os); assert(TypeId(os_info) == TypeId.Enum); assert(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto); - assert(os_info.Enum.fields.len == 32); - assert(mem.eql(u8, os_info.Enum.fields[1].name, "ananas")); - assert(os_info.Enum.fields[10].value == 10); - assert(os_info.Enum.tag_type == u5); + assert(os_info.Enum.fields.len == 4); + assert(mem.eql(u8, os_info.Enum.fields[1].name, "Macos")); + assert(os_info.Enum.fields[3].value == 3); + assert(os_info.Enum.tag_type == u2); assert(os_info.Enum.defs.len == 0); } From 682815f6e9df8fa7ec25f0b327b4eab7c3d52f2a Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Sun, 23 Dec 2018 23:30:31 -0200 Subject: [PATCH 17/34] freebsd: remove syscall and use libc Use libc interface for: - getdents - kill - openat - setgid - setuid --- std/c/freebsd.zig | 5 +++++ std/os/freebsd/index.zig | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/std/c/freebsd.zig b/std/c/freebsd.zig index 9aa1859988..eae5516db3 100644 --- a/std/c/freebsd.zig +++ b/std/c/freebsd.zig @@ -14,9 +14,14 @@ pub extern "c" fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlen pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int; pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int; pub extern "c" fn getdirentries(fd: c_int, buf_ptr: [*]u8, nbytes: usize, basep: *i64) usize; +pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; pub extern "c" fn pipe2(arg0: *[2]c_int, arg1: u32) c_int; pub extern "c" fn preadv(fd: c_int, iov: *const c_void, iovcnt: c_int, offset: usize) isize; pub extern "c" fn pwritev(fd: c_int, iov: *const c_void, iovcnt: c_int, offset: usize) isize; +pub extern "c" fn openat(fd: c_int, path: ?[*]const u8, flags: c_int) c_int; +pub extern "c" fn setgid(ruid: c_uint, euid: c_uint) c_int; +pub extern "c" fn setuid(uid: c_uint) c_int; +pub extern "c" fn kill(pid: c_int, sig: c_int) c_int; /// Renamed from `kevent` to `Kevent` to avoid conflict with function name. pub const Kevent = extern struct { diff --git a/std/os/freebsd/index.zig b/std/os/freebsd/index.zig index f1533ec098..ebea64fdf6 100644 --- a/std/os/freebsd/index.zig +++ b/std/os/freebsd/index.zig @@ -573,7 +573,7 @@ pub fn getcwd(buf: [*]u8, size: usize) usize { } pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize { - return arch.syscall3(SYS_getdents, @bitCast(usize, isize(fd)), @ptrToInt(dirp), count); + return errnoWrap(@bitCast(isize, c.getdents(fd, drip, count))); } pub fn getdirentries(fd: i32, buf_ptr: [*]u8, buf_len: usize, basep: *i64) usize { @@ -667,7 +667,7 @@ pub fn create(path: [*]const u8, perm: usize) usize { } pub fn openat(dirfd: i32, path: [*]const u8, flags: usize, mode: usize) usize { - return arch.syscall4(SYS_openat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags, mode); + return errnoWrap(c.openat(@bitCast(usize, isize(dirfd)), @ptrToInt(path), flags, mode)); } pub fn close(fd: i32) usize { @@ -683,7 +683,7 @@ pub fn exit(code: i32) noreturn { } pub fn kill(pid: i32, sig: i32) usize { - return arch.syscall2(SYS_kill, @bitCast(usize, isize(pid)), @bitCast(usize, isize(sig))); + return errnoWrap(c.kill(pid, sig)); } pub fn unlink(path: [*]const u8) usize { @@ -700,11 +700,11 @@ pub fn nanosleep(req: *const timespec, rem: ?*timespec) usize { } pub fn setuid(uid: u32) usize { - return arch.syscall1(SYS_setuid, uid); + return errnoWrap(c.setuid(uid)); } pub fn setgid(gid: u32) usize { - return arch.syscall1(SYS_setgid, gid); + return errnoWrap(c.setgid(gid)); } pub fn setreuid(ruid: u32, euid: u32) usize { From 39d32ee40a53deb99a3683fed4574adceca95afe Mon Sep 17 00:00:00 2001 From: nebulaeonline Date: Sun, 23 Dec 2018 22:21:32 -0500 Subject: [PATCH 18/34] Altered SUBSYSTEM option handling when linking in msvc mode; Added preliminary UEFI support. --- CMakeLists.txt | 1 + src-self-hosted/target.zig | 2 +- src/all_types.hpp | 3 +- src/analyze.cpp | 12 +++---- src/codegen.cpp | 11 ++---- src/codegen.hpp | 1 - src/ir.cpp | 8 ++++- src/link.cpp | 74 ++++++++++++++++++++++++++++---------- src/main.cpp | 34 +++++++++++++++--- src/target.cpp | 10 ++++-- src/target.hpp | 2 ++ src/translate_c.cpp | 6 ++-- src/zig_llvm.cpp | 9 ++++- src/zig_llvm.h | 18 ++++++++-- std/debug/index.zig | 2 +- std/os/index.zig | 7 ++++ std/os/uefi/index.zig | 0 std/special/panic.zig | 2 +- 18 files changed, 152 insertions(+), 50 deletions(-) create mode 100644 std/os/uefi/index.zig diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b64bcca81..7b31f96562 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -590,6 +590,7 @@ set(ZIG_STD_FILES "os/freebsd/x86_64.zig" "os/path.zig" "os/time.zig" + "os/uefi/index.zig" "os/windows/advapi32.zig" "os/windows/error.zig" "os/windows/index.zig" diff --git a/src-self-hosted/target.zig b/src-self-hosted/target.zig index 218353c9d7..36381b820d 100644 --- a/src-self-hosted/target.zig +++ b/src-self-hosted/target.zig @@ -520,7 +520,7 @@ pub const Target = union(enum) { => return 64, }, - builtin.Os.windows => switch (id) { + builtin.Os.windows, builtin.Os.uefi => switch (id) { CInt.Id.Short, CInt.Id.UShort, => return 16, diff --git a/src/all_types.hpp b/src/all_types.hpp index 11304e536d..26e9edbab4 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1754,8 +1754,7 @@ struct CodeGen { bool strip_debug_symbols; bool is_test_build; bool is_native_target; - bool windows_subsystem_windows; - bool windows_subsystem_console; + ZigLLVM_MSVCSubsystemType msvc_subsystem; bool linker_rdynamic; bool no_rosegment_workaround; bool each_lib_rpath; diff --git a/src/analyze.cpp b/src/analyze.cpp index 9c24f3cc8d..48d473fb37 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3203,24 +3203,25 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi if (ccc) { if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) { g->have_c_main = true; - g->windows_subsystem_windows = false; - g->windows_subsystem_console = true; + g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE; } else if (buf_eql_str(symbol_name, "WinMain") && g->zig_target.os == OsWindows) { g->have_winmain = true; - g->windows_subsystem_windows = true; - g->windows_subsystem_console = false; + g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS; } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") && g->zig_target.os == OsWindows) { g->have_winmain_crt_startup = true; + g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS; } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") && g->zig_target.os == OsWindows) { g->have_dllmain_crt_startup = true; + g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS; } } + FnExport *fn_export = fn_table_entry->export_list.add_one(); memset(fn_export, 0, sizeof(FnExport)); buf_init_from_buf(&fn_export->name, symbol_name); @@ -4376,8 +4377,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *r if (is_pub && ok_cc) { if (buf_eql_str(proto_name, "main")) { g->have_pub_main = true; - g->windows_subsystem_windows = false; - g->windows_subsystem_console = true; + g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE; } else if (buf_eql_str(proto_name, "panic")) { g->have_pub_panic = true; } diff --git a/src/codegen.cpp b/src/codegen.cpp index e37703d5f0..b76bbfb492 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -291,11 +291,6 @@ void codegen_add_framework(CodeGen *g, const char *framework) { g->darwin_frameworks.append(buf_create_from_str(framework)); } -void codegen_set_windows_subsystem(CodeGen *g, bool mwindows, bool mconsole) { - g->windows_subsystem_windows = mwindows; - g->windows_subsystem_console = mconsole; -} - void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min) { g->mmacosx_version_min = mmacosx_version_min; } @@ -7273,7 +7268,7 @@ static void init(CodeGen *g) { // LLVM creates invalid binaries on Windows sometimes. // See https://github.com/ziglang/zig/issues/508 // As a workaround we do not use target native features on Windows. - if (g->zig_target.os == OsWindows) { + if (g->zig_target.os == OsWindows || g->zig_target.os == OsUefi) { target_specific_cpu_args = ""; target_specific_features = ""; } else { @@ -7519,6 +7514,7 @@ static void gen_root_source(CodeGen *g) { report_errors_and_maybe_exit(g); if (!g->is_test_build && g->zig_target.os != OsFreestanding && + g->zig_target.os != OsZen && g->zig_target.os != OsUefi && !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) { @@ -8079,8 +8075,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_bool(ch, g->strip_debug_symbols); cache_bool(ch, g->is_test_build); cache_bool(ch, g->is_native_target); - cache_bool(ch, g->windows_subsystem_windows); - cache_bool(ch, g->windows_subsystem_console); + cache_int(ch, g->msvc_subsystem); cache_bool(ch, g->linker_rdynamic); cache_bool(ch, g->no_rosegment_workaround); cache_bool(ch, g->each_lib_rpath); diff --git a/src/codegen.hpp b/src/codegen.hpp index 1d39e4bf5e..6f1cdfb677 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -33,7 +33,6 @@ void codegen_set_libc_include_dir(CodeGen *codegen, Buf *libc_include_dir); void codegen_set_msvc_lib_dir(CodeGen *g, Buf *msvc_lib_dir); void codegen_set_kernel32_lib_dir(CodeGen *codegen, Buf *kernel32_lib_dir); void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker); -void codegen_set_windows_subsystem(CodeGen *g, bool mwindows, bool mconsole); void codegen_add_lib_dir(CodeGen *codegen, const char *dir); void codegen_add_forbidden_lib(CodeGen *codegen, Buf *lib); LinkLib *codegen_add_link_lib(CodeGen *codegen, Buf *lib); diff --git a/src/ir.cpp b/src/ir.cpp index 83960f2eee..a1432c7b11 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17872,7 +17872,13 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct if (type_is_invalid(cimport_result->value.type)) return ira->codegen->invalid_instruction; - find_libc_include_path(ira->codegen); + if (ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_APPLICATION && + ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER && + ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_ROM && + ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_RUNTIME_DRIVER) { + + find_libc_include_path(ira->codegen); + } ImportTableEntry *child_import = allocate(1); child_import->decls_scope = create_decls_scope(ira->codegen, node, nullptr, nullptr, child_import); diff --git a/src/link.cpp b/src/link.cpp index 188f976a86..52ca2f2cd9 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -455,7 +455,7 @@ static void construct_linker_job_coff(LinkJob *lj) { lj->args.append("-NOLOGO"); - if (!g->strip_debug_symbols) { + if (!g->strip_debug_symbols && g->zig_target.os != Os::OsUefi) { lj->args.append("-DEBUG"); } @@ -466,11 +466,6 @@ static void construct_linker_job_coff(LinkJob *lj) { coff_append_machine_arg(g, &lj->args); - if (g->windows_subsystem_windows) { - lj->args.append("/SUBSYSTEM:windows"); - } else if (g->windows_subsystem_console) { - lj->args.append("/SUBSYSTEM:console"); - } // The commented out stuff is from when we linked with MinGW // Now that we're linking with LLD it remains to be determined // how to handle --target-environ gnu @@ -499,18 +494,47 @@ static void construct_linker_job_coff(LinkJob *lj) { // } //} - lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); - if (g->libc_link_lib != nullptr) { - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->msvc_lib_dir)))); - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->kernel32_lib_dir)))); - - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_lib_dir)))); - if (g->libc_static_lib_dir != nullptr) { - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_static_lib_dir)))); - } + // These are n actual command lines from LINK.EXE UEFI builds (app & driver) to be used as guidance cleaning + // up a bit for building the COFF linker args: + // /OUT:"J:\coding\nebulae\k\x64\Release\k.efi" /LTCG:incremental /Driver /PDB:"J:\coding\nebulae\k\x64\Release\k.pdb" "UefiApplicationEntryPoint.lib" "UefiRuntimeLib.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\nebulae\k\x64\Release\k.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_APPLICATION /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" + // /OUT:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.efi" /LTCG:incremental /Driver /PDB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.pdb" "UefiDriverEntryPoint.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" + + // Sorry for the goto(s) :) + switch (g->msvc_subsystem) { + case ZigLLVM_MSVC_CONSOLE: + lj->args.append("/SUBSYSTEM:console"); + goto building_nt; + case ZigLLVM_MSVC_EFI_APPLICATION: + lj->args.append("/SUBSYSTEM:efi_application"); + goto building_uefi; + case ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER: + lj->args.append("/SUBSYSTEM:efi_boot_service_driver"); + goto building_uefi; + case ZigLLVM_MSVC_EFI_ROM: + lj->args.append("/SUBSYSTEM:efi_rom"); + goto building_uefi; + case ZigLLVM_MSVC_EFI_RUNTIME_DRIVER: + lj->args.append("/SUBSYSTEM:efi_runtime_driver"); + goto building_uefi; + case ZigLLVM_MSVC_NATIVE: + lj->args.append("/SUBSYSTEM:native"); + goto building_nt; + case ZigLLVM_MSVC_POSIX: + lj->args.append("/SUBSYSTEM:posix"); + goto building_nt; + case ZigLLVM_MSVC_WINDOWS: + lj->args.append("/SUBSYSTEM:windows"); + goto building_nt; + case ZigLLVM_MSVC_NONE: + goto continuing_build; } +building_uefi: + lj->args.append("/BASE:\"0\" /ENTRY:\"EfiMain\" /OPT:REF /SAFESEH:NO /MERGE:\".rdata=.data\" /ALIGN:32 /NODEFAULTLIB /SECTION:\".xdata,D\""); + goto continuing_build; + +building_nt: if (lj->link_in_crt) { const char *lib_str = g->is_static ? "lib" : ""; const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : ""; @@ -547,16 +571,30 @@ static void construct_linker_job_coff(LinkJob *lj) { // msvcrt depends on kernel32 lj->args.append("kernel32.lib"); } else { - lj->args.append("-NODEFAULTLIB"); + lj->args.append("/NODEFAULTLIB"); if (!is_library) { if (g->have_winmain) { - lj->args.append("-ENTRY:WinMain"); + lj->args.append("/ENTRY:WinMain"); } else { - lj->args.append("-ENTRY:WinMainCRTStartup"); + lj->args.append("/ENTRY:WinMainCRTStartup"); } } } +continuing_build: + + lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); + + if (g->libc_link_lib != nullptr) { + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->msvc_lib_dir)))); + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->kernel32_lib_dir)))); + + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_lib_dir)))); + if (g->libc_static_lib_dir != nullptr) { + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_static_lib_dir)))); + } + } + if (is_library && !g->is_static) { lj->args.append("-DLL"); } diff --git a/src/main.cpp b/src/main.cpp index 078dfb25f9..469ec448e8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -90,9 +90,7 @@ static int print_full_usage(const char *arg0) { " -rdynamic add all symbols to the dynamic symbol table\n" " -rpath [path] add directory to the runtime library search path\n" " --no-rosegment compromise security to workaround valgrind bug\n" - " -mconsole (windows) --subsystem console to the linker\n" - " -mwindows (windows) --subsystem windows to the linker\n" - " -framework [name] (darwin) link against framework\n" + " --msvc-subsystem [subsystem] (windows/uefi) /SUBSYSTEM: to the linker\n" " -framework [name] (darwin) link against framework\n" " -mios-version-min [ver] (darwin) set iOS deployment target\n" " -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target\n" " --ver-major [ver] dynamic library semver major version\n" @@ -395,6 +393,7 @@ int main(int argc, char **argv) { int runtime_args_start = -1; bool no_rosegment_workaround = false; bool system_linker_hack = false; + ZigLLVM_MSVCSubsystemType msvc_subsystem_type = ZigLLVM_MSVC_NONE; if (argc >= 2 && strcmp(argv[1], "build") == 0) { Buf zig_exe_path_buf = BUF_INIT; @@ -540,6 +539,32 @@ int main(int argc, char **argv) { verbose_llvm_ir = true; } else if (strcmp(arg, "--verbose-cimport") == 0) { verbose_cimport = true; + } else if (strcmp(arg, "--msvc-subsystem") == 0) { + if (i + 1 >= argc) { + fprintf(stderr, "Expected 1 argument after --msvc-subsystem\n"); + return print_error_usage(arg0); + } + i += 1; + if (stricmp(argv[i], "CONSOLE") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_CONSOLE; + } else if (stricmp(argv[i], "WINDOWS") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_WINDOWS; + } else if (stricmp(argv[i], "POSIX") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_POSIX; + } else if (stricmp(argv[i], "NATIVE") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_NATIVE; + } else if (stricmp(argv[i], "EFI_APPLICATION") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_EFI_APPLICATION; + } else if (stricmp(argv[i], "EFI_BOOT_SERVICE_DRIVER") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER; + } else if (stricmp(argv[i], "EFI_ROM") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_EFI_ROM; + } else if (stricmp(argv[i], "EFI_RUNTIME_DRIVER") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_EFI_RUNTIME_DRIVER; + } else { + fprintf(stderr, "Unknown format %s for --msvc-subsystem argument\n", argv[i]); + return EXIT_FAILURE; + } } else if (strcmp(arg, "-mwindows") == 0) { mwindows = true; } else if (strcmp(arg, "-mconsole") == 0) { @@ -849,6 +874,8 @@ int main(int argc, char **argv) { buf_out_name = buf_create_from_str("run"); } CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir()); + g->msvc_subsystem = msvc_subsystem_type; + if (disable_pic) { if (out_type != OutTypeLib || !is_static) { fprintf(stderr, "--disable-pic only applies to static libraries"); @@ -909,7 +936,6 @@ int main(int argc, char **argv) { codegen_add_rpath(g, rpath_list.at(i)); } - codegen_set_windows_subsystem(g, mwindows, mconsole); codegen_set_rdynamic(g, rdynamic); g->no_rosegment_workaround = no_rosegment_workaround; if (mmacosx_version_min && mios_version_min) { diff --git a/src/target.cpp b/src/target.cpp index 5a4b5252f1..6992f86cac 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -174,6 +174,7 @@ static const Os os_list[] = { OsContiki, OsAMDPAL, OsZen, + OsUefi, }; // Coordinate with zig_llvm.h @@ -315,6 +316,8 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type) { return ZigLLVM_Contiki; case OsAMDPAL: return ZigLLVM_AMDPAL; + case OsUefi: + return ZigLLVM_Uefi; } zig_unreachable(); } @@ -756,6 +759,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { case CIntTypeCount: zig_unreachable(); } + case OsUefi: case OsWindows: switch (id) { case CIntTypeShort: @@ -803,7 +807,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { } const char *target_o_file_ext(ZigTarget *target) { - if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows) { + if (target->env_type == ZigLLVM_MSVC || (target->os == OsWindows || target->os == OsUefi)) { return ".obj"; } else { return ".o"; @@ -821,13 +825,15 @@ const char *target_llvm_ir_file_ext(ZigTarget *target) { const char *target_exe_file_ext(ZigTarget *target) { if (target->os == OsWindows) { return ".exe"; + } else if (target->os == OsUefi) { + return ".efi"; } else { return ""; } } const char *target_lib_file_ext(ZigTarget *target, bool is_static, size_t version_major, size_t version_minor, size_t version_patch) { - if (target->os == OsWindows) { + if (target->os == OsWindows || target->os == OsUefi) { if (is_static) { return ".lib"; } else { diff --git a/src/target.hpp b/src/target.hpp index 04652179d2..62cc20711a 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -51,6 +51,7 @@ enum Os { OsContiki, OsAMDPAL, OsZen, + OsUefi, }; struct ZigTarget { @@ -59,6 +60,7 @@ struct ZigTarget { Os os; ZigLLVM_EnvironmentType env_type; ZigLLVM_ObjectFormatType oformat; + ZigLLVM_MSVCSubsystemType msvc_subsystem = ZigLLVM_MSVC_NONE; }; enum CIntType { diff --git a/src/translate_c.cpp b/src/translate_c.cpp index f6bc9cd683..0e56e29810 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -4749,8 +4749,10 @@ Error parse_h_file(ImportTableEntry *import, ZigList *errors, const clang_argv.append("-isystem"); clang_argv.append(buf_ptr(codegen->zig_c_headers_dir)); - clang_argv.append("-isystem"); - clang_argv.append(buf_ptr(codegen->libc_include_dir)); + if (codegen->libc_include_dir) { + clang_argv.append("-isystem"); + clang_argv.append(buf_ptr(codegen->libc_include_dir)); + } // windows c runtime requires -D_DEBUG if using debug libraries if (codegen->build_mode == BuildModeDebug) { diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index bda8fa0adc..e12ece919e 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -690,7 +690,14 @@ const char *ZigLLVMGetVendorTypeName(ZigLLVM_VendorType vendor) { } const char *ZigLLVMGetOSTypeName(ZigLLVM_OSType os) { - return (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin(); + switch (os) { + case ZigLLVM_Zen: + return "unknown"; + case ZigLLVM_Uefi: + return "windows"; + default: + return (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin(); + } } const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type) { diff --git a/src/zig_llvm.h b/src/zig_llvm.h index 551a4a7448..bb7cb5c5ff 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -357,8 +358,8 @@ enum ZigLLVM_OSType { ZigLLVM_Mesa3D, ZigLLVM_Contiki, ZigLLVM_AMDPAL, // AMD PAL Runtime - - ZigLLVM_LastOSType = ZigLLVM_AMDPAL + ZigLLVM_Uefi, + ZigLLVM_LastOSType = ZigLLVM_Uefi }; // Synchronize with target.cpp::environ_list @@ -397,6 +398,19 @@ enum ZigLLVM_ObjectFormatType { ZigLLVM_Wasm, }; +// For MSVC-supported subsystems +enum ZigLLVM_MSVCSubsystemType { + ZigLLVM_MSVC_NONE, + ZigLLVM_MSVC_CONSOLE, + ZigLLVM_MSVC_WINDOWS, + ZigLLVM_MSVC_POSIX, + ZigLLVM_MSVC_NATIVE, + ZigLLVM_MSVC_EFI_APPLICATION, + ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER, + ZigLLVM_MSVC_EFI_ROM, + ZigLLVM_MSVC_EFI_RUNTIME_DRIVER, +}; + ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch); ZIG_EXTERN_C const char *ZigLLVMGetSubArchTypeName(enum ZigLLVM_SubArchType sub_arch); ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor); diff --git a/std/debug/index.zig b/std/debug/index.zig index 73c6ea7b56..93d6a60a03 100644 --- a/std/debug/index.zig +++ b/std/debug/index.zig @@ -1135,7 +1135,7 @@ pub const DebugInfo = switch (builtin.os) { return self.ofiles.allocator; } }, - builtin.Os.windows => struct { + builtin.Os.uefi, builtin.Os.windows => struct { pdb: pdb.Pdb, coff: *coff.Coff, sect_contribs: []pdb.SectionContribEntry, diff --git a/std/os/index.zig b/std/os/index.zig index b19679c969..ce65667157 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -18,6 +18,7 @@ test "std.os" { _ = @import("test.zig"); _ = @import("time.zig"); _ = @import("windows/index.zig"); + _ = @import("uefi/index.zig"); _ = @import("get_app_data_dir.zig"); } @@ -26,6 +27,8 @@ pub const darwin = @import("darwin.zig"); pub const linux = @import("linux/index.zig"); pub const freebsd = @import("freebsd/index.zig"); pub const zen = @import("zen.zig"); +pub const uefi = @import("uefi/index.zig"); + pub const posix = switch (builtin.os) { Os.linux => linux, Os.macosx, Os.ios => darwin, @@ -33,6 +36,7 @@ pub const posix = switch (builtin.os) { Os.zen => zen, else => @compileError("Unsupported OS"), }; + pub const net = @import("net.zig"); pub const ChildProcess = @import("child_process.zig").ChildProcess; @@ -187,6 +191,9 @@ pub fn abort() noreturn { } windows.ExitProcess(3); }, + Os.uefi => { + while (true) {} + }, else => @compileError("Unsupported OS"), } } diff --git a/std/os/uefi/index.zig b/std/os/uefi/index.zig new file mode 100644 index 0000000000..e69de29bb2 diff --git a/std/special/panic.zig b/std/special/panic.zig index ca1caea73c..fe1e020604 100644 --- a/std/special/panic.zig +++ b/std/special/panic.zig @@ -10,7 +10,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn @setCold(true); switch (builtin.os) { // TODO: fix panic in zen. - builtin.Os.freestanding, builtin.Os.zen => { + builtin.Os.freestanding, builtin.Os.zen, builtin.Os.uefi => { while (true) {} }, else => { From fdea12b2d9deaea6a90c7b1451df425e84b98099 Mon Sep 17 00:00:00 2001 From: nebulaeonline Date: Sun, 23 Dec 2018 22:44:02 -0500 Subject: [PATCH 19/34] msvc subsystem option handling; added uefi os type --- CMakeLists.txt | 1 + src-self-hosted/target.zig | 2 +- src/all_types.hpp | 3 +- src/analyze.cpp | 12 +++---- src/codegen.cpp | 11 ++---- src/codegen.hpp | 1 - src/ir.cpp | 8 ++++- src/link.cpp | 74 ++++++++++++++++++++++++++++---------- src/main.cpp | 34 +++++++++++++++--- src/target.cpp | 10 ++++-- src/target.hpp | 2 ++ src/translate_c.cpp | 6 ++-- src/zig_llvm.cpp | 7 +++- src/zig_llvm.h | 18 ++++++++-- std/debug/index.zig | 2 +- std/os/index.zig | 7 ++++ std/os/uefi/index.zig | 0 std/special/panic.zig | 2 +- 18 files changed, 150 insertions(+), 50 deletions(-) create mode 100644 std/os/uefi/index.zig diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b64bcca81..7b31f96562 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -590,6 +590,7 @@ set(ZIG_STD_FILES "os/freebsd/x86_64.zig" "os/path.zig" "os/time.zig" + "os/uefi/index.zig" "os/windows/advapi32.zig" "os/windows/error.zig" "os/windows/index.zig" diff --git a/src-self-hosted/target.zig b/src-self-hosted/target.zig index 218353c9d7..36381b820d 100644 --- a/src-self-hosted/target.zig +++ b/src-self-hosted/target.zig @@ -520,7 +520,7 @@ pub const Target = union(enum) { => return 64, }, - builtin.Os.windows => switch (id) { + builtin.Os.windows, builtin.Os.uefi => switch (id) { CInt.Id.Short, CInt.Id.UShort, => return 16, diff --git a/src/all_types.hpp b/src/all_types.hpp index 11304e536d..26e9edbab4 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1754,8 +1754,7 @@ struct CodeGen { bool strip_debug_symbols; bool is_test_build; bool is_native_target; - bool windows_subsystem_windows; - bool windows_subsystem_console; + ZigLLVM_MSVCSubsystemType msvc_subsystem; bool linker_rdynamic; bool no_rosegment_workaround; bool each_lib_rpath; diff --git a/src/analyze.cpp b/src/analyze.cpp index 9c24f3cc8d..48d473fb37 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3203,24 +3203,25 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi if (ccc) { if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) { g->have_c_main = true; - g->windows_subsystem_windows = false; - g->windows_subsystem_console = true; + g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE; } else if (buf_eql_str(symbol_name, "WinMain") && g->zig_target.os == OsWindows) { g->have_winmain = true; - g->windows_subsystem_windows = true; - g->windows_subsystem_console = false; + g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS; } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") && g->zig_target.os == OsWindows) { g->have_winmain_crt_startup = true; + g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS; } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") && g->zig_target.os == OsWindows) { g->have_dllmain_crt_startup = true; + g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS; } } + FnExport *fn_export = fn_table_entry->export_list.add_one(); memset(fn_export, 0, sizeof(FnExport)); buf_init_from_buf(&fn_export->name, symbol_name); @@ -4376,8 +4377,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *r if (is_pub && ok_cc) { if (buf_eql_str(proto_name, "main")) { g->have_pub_main = true; - g->windows_subsystem_windows = false; - g->windows_subsystem_console = true; + g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE; } else if (buf_eql_str(proto_name, "panic")) { g->have_pub_panic = true; } diff --git a/src/codegen.cpp b/src/codegen.cpp index e37703d5f0..b76bbfb492 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -291,11 +291,6 @@ void codegen_add_framework(CodeGen *g, const char *framework) { g->darwin_frameworks.append(buf_create_from_str(framework)); } -void codegen_set_windows_subsystem(CodeGen *g, bool mwindows, bool mconsole) { - g->windows_subsystem_windows = mwindows; - g->windows_subsystem_console = mconsole; -} - void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min) { g->mmacosx_version_min = mmacosx_version_min; } @@ -7273,7 +7268,7 @@ static void init(CodeGen *g) { // LLVM creates invalid binaries on Windows sometimes. // See https://github.com/ziglang/zig/issues/508 // As a workaround we do not use target native features on Windows. - if (g->zig_target.os == OsWindows) { + if (g->zig_target.os == OsWindows || g->zig_target.os == OsUefi) { target_specific_cpu_args = ""; target_specific_features = ""; } else { @@ -7519,6 +7514,7 @@ static void gen_root_source(CodeGen *g) { report_errors_and_maybe_exit(g); if (!g->is_test_build && g->zig_target.os != OsFreestanding && + g->zig_target.os != OsZen && g->zig_target.os != OsUefi && !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) { @@ -8079,8 +8075,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_bool(ch, g->strip_debug_symbols); cache_bool(ch, g->is_test_build); cache_bool(ch, g->is_native_target); - cache_bool(ch, g->windows_subsystem_windows); - cache_bool(ch, g->windows_subsystem_console); + cache_int(ch, g->msvc_subsystem); cache_bool(ch, g->linker_rdynamic); cache_bool(ch, g->no_rosegment_workaround); cache_bool(ch, g->each_lib_rpath); diff --git a/src/codegen.hpp b/src/codegen.hpp index 1d39e4bf5e..6f1cdfb677 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -33,7 +33,6 @@ void codegen_set_libc_include_dir(CodeGen *codegen, Buf *libc_include_dir); void codegen_set_msvc_lib_dir(CodeGen *g, Buf *msvc_lib_dir); void codegen_set_kernel32_lib_dir(CodeGen *codegen, Buf *kernel32_lib_dir); void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker); -void codegen_set_windows_subsystem(CodeGen *g, bool mwindows, bool mconsole); void codegen_add_lib_dir(CodeGen *codegen, const char *dir); void codegen_add_forbidden_lib(CodeGen *codegen, Buf *lib); LinkLib *codegen_add_link_lib(CodeGen *codegen, Buf *lib); diff --git a/src/ir.cpp b/src/ir.cpp index 83960f2eee..a1432c7b11 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17872,7 +17872,13 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct if (type_is_invalid(cimport_result->value.type)) return ira->codegen->invalid_instruction; - find_libc_include_path(ira->codegen); + if (ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_APPLICATION && + ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER && + ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_ROM && + ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_RUNTIME_DRIVER) { + + find_libc_include_path(ira->codegen); + } ImportTableEntry *child_import = allocate(1); child_import->decls_scope = create_decls_scope(ira->codegen, node, nullptr, nullptr, child_import); diff --git a/src/link.cpp b/src/link.cpp index 188f976a86..52ca2f2cd9 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -455,7 +455,7 @@ static void construct_linker_job_coff(LinkJob *lj) { lj->args.append("-NOLOGO"); - if (!g->strip_debug_symbols) { + if (!g->strip_debug_symbols && g->zig_target.os != Os::OsUefi) { lj->args.append("-DEBUG"); } @@ -466,11 +466,6 @@ static void construct_linker_job_coff(LinkJob *lj) { coff_append_machine_arg(g, &lj->args); - if (g->windows_subsystem_windows) { - lj->args.append("/SUBSYSTEM:windows"); - } else if (g->windows_subsystem_console) { - lj->args.append("/SUBSYSTEM:console"); - } // The commented out stuff is from when we linked with MinGW // Now that we're linking with LLD it remains to be determined // how to handle --target-environ gnu @@ -499,18 +494,47 @@ static void construct_linker_job_coff(LinkJob *lj) { // } //} - lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); - if (g->libc_link_lib != nullptr) { - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->msvc_lib_dir)))); - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->kernel32_lib_dir)))); - - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_lib_dir)))); - if (g->libc_static_lib_dir != nullptr) { - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_static_lib_dir)))); - } + // These are n actual command lines from LINK.EXE UEFI builds (app & driver) to be used as guidance cleaning + // up a bit for building the COFF linker args: + // /OUT:"J:\coding\nebulae\k\x64\Release\k.efi" /LTCG:incremental /Driver /PDB:"J:\coding\nebulae\k\x64\Release\k.pdb" "UefiApplicationEntryPoint.lib" "UefiRuntimeLib.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\nebulae\k\x64\Release\k.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_APPLICATION /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" + // /OUT:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.efi" /LTCG:incremental /Driver /PDB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.pdb" "UefiDriverEntryPoint.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" + + // Sorry for the goto(s) :) + switch (g->msvc_subsystem) { + case ZigLLVM_MSVC_CONSOLE: + lj->args.append("/SUBSYSTEM:console"); + goto building_nt; + case ZigLLVM_MSVC_EFI_APPLICATION: + lj->args.append("/SUBSYSTEM:efi_application"); + goto building_uefi; + case ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER: + lj->args.append("/SUBSYSTEM:efi_boot_service_driver"); + goto building_uefi; + case ZigLLVM_MSVC_EFI_ROM: + lj->args.append("/SUBSYSTEM:efi_rom"); + goto building_uefi; + case ZigLLVM_MSVC_EFI_RUNTIME_DRIVER: + lj->args.append("/SUBSYSTEM:efi_runtime_driver"); + goto building_uefi; + case ZigLLVM_MSVC_NATIVE: + lj->args.append("/SUBSYSTEM:native"); + goto building_nt; + case ZigLLVM_MSVC_POSIX: + lj->args.append("/SUBSYSTEM:posix"); + goto building_nt; + case ZigLLVM_MSVC_WINDOWS: + lj->args.append("/SUBSYSTEM:windows"); + goto building_nt; + case ZigLLVM_MSVC_NONE: + goto continuing_build; } +building_uefi: + lj->args.append("/BASE:\"0\" /ENTRY:\"EfiMain\" /OPT:REF /SAFESEH:NO /MERGE:\".rdata=.data\" /ALIGN:32 /NODEFAULTLIB /SECTION:\".xdata,D\""); + goto continuing_build; + +building_nt: if (lj->link_in_crt) { const char *lib_str = g->is_static ? "lib" : ""; const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : ""; @@ -547,16 +571,30 @@ static void construct_linker_job_coff(LinkJob *lj) { // msvcrt depends on kernel32 lj->args.append("kernel32.lib"); } else { - lj->args.append("-NODEFAULTLIB"); + lj->args.append("/NODEFAULTLIB"); if (!is_library) { if (g->have_winmain) { - lj->args.append("-ENTRY:WinMain"); + lj->args.append("/ENTRY:WinMain"); } else { - lj->args.append("-ENTRY:WinMainCRTStartup"); + lj->args.append("/ENTRY:WinMainCRTStartup"); } } } +continuing_build: + + lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); + + if (g->libc_link_lib != nullptr) { + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->msvc_lib_dir)))); + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->kernel32_lib_dir)))); + + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_lib_dir)))); + if (g->libc_static_lib_dir != nullptr) { + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_static_lib_dir)))); + } + } + if (is_library && !g->is_static) { lj->args.append("-DLL"); } diff --git a/src/main.cpp b/src/main.cpp index 078dfb25f9..469ec448e8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -90,9 +90,7 @@ static int print_full_usage(const char *arg0) { " -rdynamic add all symbols to the dynamic symbol table\n" " -rpath [path] add directory to the runtime library search path\n" " --no-rosegment compromise security to workaround valgrind bug\n" - " -mconsole (windows) --subsystem console to the linker\n" - " -mwindows (windows) --subsystem windows to the linker\n" - " -framework [name] (darwin) link against framework\n" + " --msvc-subsystem [subsystem] (windows/uefi) /SUBSYSTEM: to the linker\n" " -framework [name] (darwin) link against framework\n" " -mios-version-min [ver] (darwin) set iOS deployment target\n" " -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target\n" " --ver-major [ver] dynamic library semver major version\n" @@ -395,6 +393,7 @@ int main(int argc, char **argv) { int runtime_args_start = -1; bool no_rosegment_workaround = false; bool system_linker_hack = false; + ZigLLVM_MSVCSubsystemType msvc_subsystem_type = ZigLLVM_MSVC_NONE; if (argc >= 2 && strcmp(argv[1], "build") == 0) { Buf zig_exe_path_buf = BUF_INIT; @@ -540,6 +539,32 @@ int main(int argc, char **argv) { verbose_llvm_ir = true; } else if (strcmp(arg, "--verbose-cimport") == 0) { verbose_cimport = true; + } else if (strcmp(arg, "--msvc-subsystem") == 0) { + if (i + 1 >= argc) { + fprintf(stderr, "Expected 1 argument after --msvc-subsystem\n"); + return print_error_usage(arg0); + } + i += 1; + if (stricmp(argv[i], "CONSOLE") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_CONSOLE; + } else if (stricmp(argv[i], "WINDOWS") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_WINDOWS; + } else if (stricmp(argv[i], "POSIX") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_POSIX; + } else if (stricmp(argv[i], "NATIVE") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_NATIVE; + } else if (stricmp(argv[i], "EFI_APPLICATION") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_EFI_APPLICATION; + } else if (stricmp(argv[i], "EFI_BOOT_SERVICE_DRIVER") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER; + } else if (stricmp(argv[i], "EFI_ROM") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_EFI_ROM; + } else if (stricmp(argv[i], "EFI_RUNTIME_DRIVER") == 0) { + msvc_subsystem_type = ZigLLVM_MSVC_EFI_RUNTIME_DRIVER; + } else { + fprintf(stderr, "Unknown format %s for --msvc-subsystem argument\n", argv[i]); + return EXIT_FAILURE; + } } else if (strcmp(arg, "-mwindows") == 0) { mwindows = true; } else if (strcmp(arg, "-mconsole") == 0) { @@ -849,6 +874,8 @@ int main(int argc, char **argv) { buf_out_name = buf_create_from_str("run"); } CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir()); + g->msvc_subsystem = msvc_subsystem_type; + if (disable_pic) { if (out_type != OutTypeLib || !is_static) { fprintf(stderr, "--disable-pic only applies to static libraries"); @@ -909,7 +936,6 @@ int main(int argc, char **argv) { codegen_add_rpath(g, rpath_list.at(i)); } - codegen_set_windows_subsystem(g, mwindows, mconsole); codegen_set_rdynamic(g, rdynamic); g->no_rosegment_workaround = no_rosegment_workaround; if (mmacosx_version_min && mios_version_min) { diff --git a/src/target.cpp b/src/target.cpp index 5a4b5252f1..6992f86cac 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -174,6 +174,7 @@ static const Os os_list[] = { OsContiki, OsAMDPAL, OsZen, + OsUefi, }; // Coordinate with zig_llvm.h @@ -315,6 +316,8 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type) { return ZigLLVM_Contiki; case OsAMDPAL: return ZigLLVM_AMDPAL; + case OsUefi: + return ZigLLVM_Uefi; } zig_unreachable(); } @@ -756,6 +759,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { case CIntTypeCount: zig_unreachable(); } + case OsUefi: case OsWindows: switch (id) { case CIntTypeShort: @@ -803,7 +807,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { } const char *target_o_file_ext(ZigTarget *target) { - if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows) { + if (target->env_type == ZigLLVM_MSVC || (target->os == OsWindows || target->os == OsUefi)) { return ".obj"; } else { return ".o"; @@ -821,13 +825,15 @@ const char *target_llvm_ir_file_ext(ZigTarget *target) { const char *target_exe_file_ext(ZigTarget *target) { if (target->os == OsWindows) { return ".exe"; + } else if (target->os == OsUefi) { + return ".efi"; } else { return ""; } } const char *target_lib_file_ext(ZigTarget *target, bool is_static, size_t version_major, size_t version_minor, size_t version_patch) { - if (target->os == OsWindows) { + if (target->os == OsWindows || target->os == OsUefi) { if (is_static) { return ".lib"; } else { diff --git a/src/target.hpp b/src/target.hpp index 04652179d2..62cc20711a 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -51,6 +51,7 @@ enum Os { OsContiki, OsAMDPAL, OsZen, + OsUefi, }; struct ZigTarget { @@ -59,6 +60,7 @@ struct ZigTarget { Os os; ZigLLVM_EnvironmentType env_type; ZigLLVM_ObjectFormatType oformat; + ZigLLVM_MSVCSubsystemType msvc_subsystem = ZigLLVM_MSVC_NONE; }; enum CIntType { diff --git a/src/translate_c.cpp b/src/translate_c.cpp index f6bc9cd683..0e56e29810 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -4749,8 +4749,10 @@ Error parse_h_file(ImportTableEntry *import, ZigList *errors, const clang_argv.append("-isystem"); clang_argv.append(buf_ptr(codegen->zig_c_headers_dir)); - clang_argv.append("-isystem"); - clang_argv.append(buf_ptr(codegen->libc_include_dir)); + if (codegen->libc_include_dir) { + clang_argv.append("-isystem"); + clang_argv.append(buf_ptr(codegen->libc_include_dir)); + } // windows c runtime requires -D_DEBUG if using debug libraries if (codegen->build_mode == BuildModeDebug) { diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index bda8fa0adc..bd63b7cbe5 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -690,7 +690,12 @@ const char *ZigLLVMGetVendorTypeName(ZigLLVM_VendorType vendor) { } const char *ZigLLVMGetOSTypeName(ZigLLVM_OSType os) { - return (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin(); + switch (os) { + case ZigLLVM_Uefi: + return "windows"; + default: + return (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin(); + } } const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type) { diff --git a/src/zig_llvm.h b/src/zig_llvm.h index 551a4a7448..bb7cb5c5ff 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -357,8 +358,8 @@ enum ZigLLVM_OSType { ZigLLVM_Mesa3D, ZigLLVM_Contiki, ZigLLVM_AMDPAL, // AMD PAL Runtime - - ZigLLVM_LastOSType = ZigLLVM_AMDPAL + ZigLLVM_Uefi, + ZigLLVM_LastOSType = ZigLLVM_Uefi }; // Synchronize with target.cpp::environ_list @@ -397,6 +398,19 @@ enum ZigLLVM_ObjectFormatType { ZigLLVM_Wasm, }; +// For MSVC-supported subsystems +enum ZigLLVM_MSVCSubsystemType { + ZigLLVM_MSVC_NONE, + ZigLLVM_MSVC_CONSOLE, + ZigLLVM_MSVC_WINDOWS, + ZigLLVM_MSVC_POSIX, + ZigLLVM_MSVC_NATIVE, + ZigLLVM_MSVC_EFI_APPLICATION, + ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER, + ZigLLVM_MSVC_EFI_ROM, + ZigLLVM_MSVC_EFI_RUNTIME_DRIVER, +}; + ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch); ZIG_EXTERN_C const char *ZigLLVMGetSubArchTypeName(enum ZigLLVM_SubArchType sub_arch); ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor); diff --git a/std/debug/index.zig b/std/debug/index.zig index 73c6ea7b56..93d6a60a03 100644 --- a/std/debug/index.zig +++ b/std/debug/index.zig @@ -1135,7 +1135,7 @@ pub const DebugInfo = switch (builtin.os) { return self.ofiles.allocator; } }, - builtin.Os.windows => struct { + builtin.Os.uefi, builtin.Os.windows => struct { pdb: pdb.Pdb, coff: *coff.Coff, sect_contribs: []pdb.SectionContribEntry, diff --git a/std/os/index.zig b/std/os/index.zig index b19679c969..ce65667157 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -18,6 +18,7 @@ test "std.os" { _ = @import("test.zig"); _ = @import("time.zig"); _ = @import("windows/index.zig"); + _ = @import("uefi/index.zig"); _ = @import("get_app_data_dir.zig"); } @@ -26,6 +27,8 @@ pub const darwin = @import("darwin.zig"); pub const linux = @import("linux/index.zig"); pub const freebsd = @import("freebsd/index.zig"); pub const zen = @import("zen.zig"); +pub const uefi = @import("uefi/index.zig"); + pub const posix = switch (builtin.os) { Os.linux => linux, Os.macosx, Os.ios => darwin, @@ -33,6 +36,7 @@ pub const posix = switch (builtin.os) { Os.zen => zen, else => @compileError("Unsupported OS"), }; + pub const net = @import("net.zig"); pub const ChildProcess = @import("child_process.zig").ChildProcess; @@ -187,6 +191,9 @@ pub fn abort() noreturn { } windows.ExitProcess(3); }, + Os.uefi => { + while (true) {} + }, else => @compileError("Unsupported OS"), } } diff --git a/std/os/uefi/index.zig b/std/os/uefi/index.zig new file mode 100644 index 0000000000..e69de29bb2 diff --git a/std/special/panic.zig b/std/special/panic.zig index ca1caea73c..fe1e020604 100644 --- a/std/special/panic.zig +++ b/std/special/panic.zig @@ -10,7 +10,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn @setCold(true); switch (builtin.os) { // TODO: fix panic in zen. - builtin.Os.freestanding, builtin.Os.zen => { + builtin.Os.freestanding, builtin.Os.zen, builtin.Os.uefi => { while (true) {} }, else => { From 480061d2c999375be1442d14451da15d6662e67d Mon Sep 17 00:00:00 2001 From: nebulaeonline Date: Sun, 23 Dec 2018 23:09:07 -0500 Subject: [PATCH 20/34] git user error fix --- src/codegen.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index b76bbfb492..30a4f8c2a4 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7231,8 +7231,7 @@ static void init(CodeGen *g) { } if (g->is_test_build) { - g->windows_subsystem_windows = false; - g->windows_subsystem_console = true; + g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE; } assert(g->root_out_name); From 51baea184bb2bcfb325caf3c5051118deadc319d Mon Sep 17 00:00:00 2001 From: nebulaeonline Date: Sun, 23 Dec 2018 23:46:45 -0500 Subject: [PATCH 21/34] Yet another git user error remnant fixed --- src/target.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/target.cpp b/src/target.cpp index 6992f86cac..973662757b 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -397,6 +397,8 @@ const char *get_target_os_name(Os os_type) { return "freestanding"; case OsZen: return "zen"; + case OsUefi: + return "uefi"; case OsAnanas: case OsCloudABI: case OsDragonFly: From 7dcee99510fe4d69faae67f3aa41cfb47a43045e Mon Sep 17 00:00:00 2001 From: nebulaeonline Date: Sun, 23 Dec 2018 23:59:59 -0500 Subject: [PATCH 22/34] fixed stricmp/strcasecmp between windows/posix --- src/main.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 469ec448e8..303e48d750 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,6 +16,13 @@ #include +#ifdef __GNUC__ +#include +#define STRCASECMP strcasecmp +#else +#define STRCASECMP stricmp +#endif + static int print_error_usage(const char *arg0) { fprintf(stderr, "See `%s help` for detailed usage information\n", arg0); return EXIT_FAILURE; @@ -545,21 +552,21 @@ int main(int argc, char **argv) { return print_error_usage(arg0); } i += 1; - if (stricmp(argv[i], "CONSOLE") == 0) { + if (STRCASECMP(argv[i], "CONSOLE") == 0) { msvc_subsystem_type = ZigLLVM_MSVC_CONSOLE; - } else if (stricmp(argv[i], "WINDOWS") == 0) { + } else if (STRCASECMP(argv[i], "WINDOWS") == 0) { msvc_subsystem_type = ZigLLVM_MSVC_WINDOWS; - } else if (stricmp(argv[i], "POSIX") == 0) { + } else if (STRCASECMP(argv[i], "POSIX") == 0) { msvc_subsystem_type = ZigLLVM_MSVC_POSIX; - } else if (stricmp(argv[i], "NATIVE") == 0) { + } else if (STRCASECMP(argv[i], "NATIVE") == 0) { msvc_subsystem_type = ZigLLVM_MSVC_NATIVE; - } else if (stricmp(argv[i], "EFI_APPLICATION") == 0) { + } else if (STRCASECMP(argv[i], "EFI_APPLICATION") == 0) { msvc_subsystem_type = ZigLLVM_MSVC_EFI_APPLICATION; - } else if (stricmp(argv[i], "EFI_BOOT_SERVICE_DRIVER") == 0) { + } else if (STRCASECMP(argv[i], "EFI_BOOT_SERVICE_DRIVER") == 0) { msvc_subsystem_type = ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER; - } else if (stricmp(argv[i], "EFI_ROM") == 0) { + } else if (STRCASECMP(argv[i], "EFI_ROM") == 0) { msvc_subsystem_type = ZigLLVM_MSVC_EFI_ROM; - } else if (stricmp(argv[i], "EFI_RUNTIME_DRIVER") == 0) { + } else if (STRCASECMP(argv[i], "EFI_RUNTIME_DRIVER") == 0) { msvc_subsystem_type = ZigLLVM_MSVC_EFI_RUNTIME_DRIVER; } else { fprintf(stderr, "Unknown format %s for --msvc-subsystem argument\n", argv[i]); From de473d442371c943bff077428b3786885cadec47 Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Mon, 24 Dec 2018 10:27:08 -0200 Subject: [PATCH 23/34] freebsd: implement std.os.time.sleep --- std/os/time.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/os/time.zig b/std/os/time.zig index d9fe046a55..c3588838bc 100644 --- a/std/os/time.zig +++ b/std/os/time.zig @@ -13,7 +13,7 @@ pub const epoch = @import("epoch.zig"); /// Sleep for the specified duration pub fn sleep(nanoseconds: u64) void { switch (builtin.os) { - Os.linux, Os.macosx, Os.ios => { + Os.linux, Os.macosx, Os.ios, Os.freebsd => { const s = nanoseconds / ns_per_s; const ns = nanoseconds % ns_per_s; posixSleep(@intCast(u63, s), @intCast(u63, ns)); From 28cd337d1ffc547f296f574b82547d6b15253167 Mon Sep 17 00:00:00 2001 From: nebulaeonline Date: Mon, 24 Dec 2018 07:49:15 -0500 Subject: [PATCH 24/34] fixed formatting in options display --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 303e48d750..faca9511dc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -97,7 +97,8 @@ static int print_full_usage(const char *arg0) { " -rdynamic add all symbols to the dynamic symbol table\n" " -rpath [path] add directory to the runtime library search path\n" " --no-rosegment compromise security to workaround valgrind bug\n" - " --msvc-subsystem [subsystem] (windows/uefi) /SUBSYSTEM: to the linker\n" " -framework [name] (darwin) link against framework\n" + " --msvc-subsystem [subsystem] (windows/uefi) /SUBSYSTEM: to the linker\n" + " -framework [name] (darwin) link against framework\n" " -mios-version-min [ver] (darwin) set iOS deployment target\n" " -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target\n" " --ver-major [ver] dynamic library semver major version\n" From 52be7d7404acf2eff53d5c0cfd3ddeb591a5e27c Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Mon, 24 Dec 2018 11:19:09 -0200 Subject: [PATCH 25/34] freebsd: fix flags for opening files Prior to this fix, the compare-outputs test suite was showing a strange behavior, the tests always stopped between tests 6-8 and had a stack track similar to each other. ``` Test 8/68 compare-output multiple files with private function (ReleaseSmall)...OK /usr/home/mgxm/dev/zig/zig-cache/source.zig:7:2: error: invalid token: '&' }&(getStdOut() catch unreachable).outStream().stream; ^ The following command exited with error code 1: ``` With the wrong O_* flags, the source code was being written in append mode which resulted in an invalid file ```zig use @import("foo.zig"); use @import("bar.zig"); pub fn main() void { foo_function(); bar_function(); }&(getStdOut() catch unreachable).outStream().stream; stdout.print("OK 2\n") catch unreachable; } fn privateFunction() void { printText(); } ``` --- std/os/freebsd/index.zig | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/std/os/freebsd/index.zig b/std/os/freebsd/index.zig index ebea64fdf6..603265b956 100644 --- a/std/os/freebsd/index.zig +++ b/std/os/freebsd/index.zig @@ -105,26 +105,26 @@ pub const W_OK = 2; // test for write permission pub const R_OK = 4; // test for read permission -pub const O_RDONLY = 0o0; -pub const O_WRONLY = 0o1; -pub const O_RDWR = 0o2; -pub const O_ACCMODE = 0o3; +pub const O_RDONLY = 0x0000; +pub const O_WRONLY = 0x0001; +pub const O_RDWR = 0x0002; +pub const O_ACCMODE = 0x0003; -pub const O_CREAT = 0o100; -pub const O_EXCL = 0o200; -pub const O_NOCTTY = 0o400; -pub const O_TRUNC = 0o1000; -pub const O_APPEND = 0o2000; -pub const O_NONBLOCK = 0o4000; +pub const O_CREAT = 0x0200; +pub const O_EXCL = 0x0800; +pub const O_NOCTTY = 0x8000; +pub const O_TRUNC = 0x0400; +pub const O_APPEND = 0x0008; +pub const O_NONBLOCK = 0x0004; pub const O_DSYNC = 0o10000; -pub const O_SYNC = 0o4010000; +pub const O_SYNC = 0x0080; pub const O_RSYNC = 0o4010000; pub const O_DIRECTORY = 0o200000; -pub const O_NOFOLLOW = 0o400000; -pub const O_CLOEXEC = 0o2000000; +pub const O_NOFOLLOW = 0x0100; +pub const O_CLOEXEC = 0x00100000; -pub const O_ASYNC = 0o20000; -pub const O_DIRECT = 0o40000; +pub const O_ASYNC = 0x0040; +pub const O_DIRECT = 0x00010000; pub const O_LARGEFILE = 0; pub const O_NOATIME = 0o1000000; pub const O_PATH = 0o10000000; From f49b45b00fbdf3feaea7d8460bdbfd5935ff1ea1 Mon Sep 17 00:00:00 2001 From: nebulaeonline Date: Mon, 24 Dec 2018 14:01:35 -0500 Subject: [PATCH 26/34] tabs to space fix. thanks visual studio. --- src/target.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/target.cpp b/src/target.cpp index 973662757b..61543c38d5 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -397,8 +397,8 @@ const char *get_target_os_name(Os os_type) { return "freestanding"; case OsZen: return "zen"; - case OsUefi: - return "uefi"; + case OsUefi: + return "uefi"; case OsAnanas: case OsCloudABI: case OsDragonFly: From 4a1f0e141893fe56f540709c8fb12b8b8dc22218 Mon Sep 17 00:00:00 2001 From: alexander Date: Wed, 26 Dec 2018 10:31:45 -0600 Subject: [PATCH 27/34] Switching on bools with duplicate and missing value detection: Issue 1768 --- src/ir.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/ir.cpp b/src/ir.cpp index 83960f2eee..b1429ae8ac 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -19787,6 +19787,39 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, return ira->codegen->invalid_instruction; } } + } else if (switch_type->id == ZigTypeIdBool) { + int seenTrue = 0; + int seenFalse = 0; + for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { + IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; + + IrInstruction *value = range->start->child; + + IrInstruction *casted_value = ir_implicit_cast(ira, value, switch_type); + if (type_is_invalid(casted_value->value.type)) + return ira->codegen->invalid_instruction; + + ConstExprValue *const_expr_val = ir_resolve_const(ira, casted_value, UndefBad); + if (!const_expr_val) + return ira->codegen->invalid_instruction; + + assert(const_expr_val->type->id == ZigTypeIdBool); + + if (const_expr_val->data.x_bool == true) { + seenTrue += 1; + } else { + seenFalse += 1; + } + + if ((seenTrue > 1) || (seenFalse > 1)) { + ir_add_error(ira, value, buf_sprintf("duplicate switch value")); + return ira->codegen->invalid_instruction; + } + } + if (((seenTrue < 1) || (seenFalse < 1)) && !instruction->have_else_prong) { + ir_add_error(ira, &instruction->base, buf_sprintf("switch must handle all possibilities")); + return ira->codegen->invalid_instruction; + } } else if (!instruction->have_else_prong) { ir_add_error(ira, &instruction->base, buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name))); From a918ce26b81b8e51c061d85631aa432a025c1ee2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 26 Dec 2018 15:25:54 -0500 Subject: [PATCH 28/34] fixups --- CMakeLists.txt | 2 +- README.md | 40 +++--- src/all_types.hpp | 2 +- src/analyze.cpp | 8 +- src/codegen.cpp | 6 +- src/ir.cpp | 8 +- src/link.cpp | 310 ++++++++++++++++++++++-------------------- src/main.cpp | 78 +++++------ src/target.cpp | 5 +- src/target.hpp | 13 +- src/translate_c.cpp | 2 +- src/zig_llvm.cpp | 7 +- src/zig_llvm.h | 18 +-- std/os/index.zig | 5 +- std/os/uefi.zig | 2 + std/os/uefi/index.zig | 0 std/special/panic.zig | 6 +- 17 files changed, 253 insertions(+), 259 deletions(-) create mode 100644 std/os/uefi.zig delete mode 100644 std/os/uefi/index.zig diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b31f96562..807077476a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -590,7 +590,7 @@ set(ZIG_STD_FILES "os/freebsd/x86_64.zig" "os/path.zig" "os/time.zig" - "os/uefi/index.zig" + "os/uefi.zig" "os/windows/advapi32.zig" "os/windows/error.zig" "os/windows/index.zig" diff --git a/README.md b/README.md index c1eec599e5..e9756b404d 100644 --- a/README.md +++ b/README.md @@ -87,26 +87,26 @@ clarity. #### Support Table -| | freestanding | linux | macosx | windows | freebsd | other | -|--------|--------------|--------|--------|---------|---------|--------| -|x86_64 | Tier 2 | Tier 1 | Tier 1 | Tier 1 | Tier 2 | Tier 3 | -|i386 | Tier 2 | Tier 2 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | -|arm | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|arm64 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | -|bpf | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|hexagon | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|mips | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|powerpc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|r600 | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|amdgcn | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|sparc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|s390x | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|spir | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|lanai | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | -|wasm32 | Tier 4 | N/A | N/A | N/A | N/A | N/A | -|wasm64 | Tier 4 | N/A | N/A | N/A | N/A | N/A | -|riscv32 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | -|riscv64 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | +| | freestanding | linux | macosx | windows | freebsd | UEFI | other | +|--------|--------------|--------|--------|---------|---------|--------|--------| +|x86_64 | Tier 2 | Tier 1 | Tier 1 | Tier 1 | Tier 2 | Tier 2 | Tier 3 | +|i386 | Tier 2 | Tier 2 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | +|arm | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | +|arm64 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | +|bpf | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|hexagon | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|mips | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|powerpc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|r600 | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|amdgcn | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|sparc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|s390x | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|spir | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|lanai | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 | +|wasm32 | Tier 4 | N/A | N/A | N/A | N/A | N/A | N/A | +|wasm64 | Tier 4 | N/A | N/A | N/A | N/A | N/A | N/A | +|riscv32 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | Tier 4 | +|riscv64 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | Tier 4 | ## Community diff --git a/src/all_types.hpp b/src/all_types.hpp index 26e9edbab4..2b55f8ee2e 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1750,11 +1750,11 @@ struct CodeGen { BuildMode build_mode; OutType out_type; ZigTarget zig_target; + TargetSubsystem subsystem; bool is_static; bool strip_debug_symbols; bool is_test_build; bool is_native_target; - ZigLLVM_MSVCSubsystemType msvc_subsystem; bool linker_rdynamic; bool no_rosegment_workaround; bool each_lib_rpath; diff --git a/src/analyze.cpp b/src/analyze.cpp index 48d473fb37..04d957b626 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3203,22 +3203,20 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi if (ccc) { if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) { g->have_c_main = true; - g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE; + g->subsystem = TargetSubsystemConsole; } else if (buf_eql_str(symbol_name, "WinMain") && g->zig_target.os == OsWindows) { g->have_winmain = true; - g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS; + g->subsystem = TargetSubsystemWindows; } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") && g->zig_target.os == OsWindows) { g->have_winmain_crt_startup = true; - g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS; } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") && g->zig_target.os == OsWindows) { g->have_dllmain_crt_startup = true; - g->msvc_subsystem = ZigLLVM_MSVC_WINDOWS; } } @@ -4377,7 +4375,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *r if (is_pub && ok_cc) { if (buf_eql_str(proto_name, "main")) { g->have_pub_main = true; - g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE; + g->subsystem = TargetSubsystemConsole; } else if (buf_eql_str(proto_name, "panic")) { g->have_pub_panic = true; } diff --git a/src/codegen.cpp b/src/codegen.cpp index 30a4f8c2a4..bbf8ffa340 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7231,7 +7231,7 @@ static void init(CodeGen *g) { } if (g->is_test_build) { - g->msvc_subsystem = ZigLLVM_MSVC_CONSOLE; + g->subsystem = TargetSubsystemConsole; } assert(g->root_out_name); @@ -7513,7 +7513,7 @@ static void gen_root_source(CodeGen *g) { report_errors_and_maybe_exit(g); if (!g->is_test_build && g->zig_target.os != OsFreestanding && - g->zig_target.os != OsZen && g->zig_target.os != OsUefi && + g->zig_target.os != OsUefi && !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) { @@ -8070,11 +8070,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_int(ch, g->zig_target.os); cache_int(ch, g->zig_target.env_type); cache_int(ch, g->zig_target.oformat); + cache_int(ch, g->subsystem); cache_bool(ch, g->is_static); cache_bool(ch, g->strip_debug_symbols); cache_bool(ch, g->is_test_build); cache_bool(ch, g->is_native_target); - cache_int(ch, g->msvc_subsystem); cache_bool(ch, g->linker_rdynamic); cache_bool(ch, g->no_rosegment_workaround); cache_bool(ch, g->each_lib_rpath); diff --git a/src/ir.cpp b/src/ir.cpp index a1432c7b11..83960f2eee 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17872,13 +17872,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct if (type_is_invalid(cimport_result->value.type)) return ira->codegen->invalid_instruction; - if (ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_APPLICATION && - ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER && - ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_ROM && - ira->codegen->msvc_subsystem != ZigLLVM_MSVC_EFI_RUNTIME_DRIVER) { - - find_libc_include_path(ira->codegen); - } + find_libc_include_path(ira->codegen); ImportTableEntry *child_import = allocate(1); child_import->decls_scope = create_decls_scope(ira->codegen, node, nullptr, nullptr, child_import); diff --git a/src/link.cpp b/src/link.cpp index 52ca2f2cd9..593f7f309f 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -444,97 +444,20 @@ static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, si return ZigLLDLink(oformat, args, arg_count, link_diag_callback, diag); } -static void construct_linker_job_coff(LinkJob *lj) { +static void add_uefi_link_args(LinkJob *lj) { + lj->args.append("/BASE:0"); + lj->args.append("/ENTRY:EfiMain"); + lj->args.append("/OPT:REF"); + lj->args.append("/SAFESEH:NO"); + lj->args.append("/MERGE:.rdata=.data"); + lj->args.append("/ALIGN:32"); + lj->args.append("/NODEFAULTLIB"); + lj->args.append("/SECTION:.xdata,D"); +} + +static void add_nt_link_args(LinkJob *lj, bool is_library) { CodeGen *g = lj->codegen; - lj->args.append("/ERRORLIMIT:0"); - - if (g->libc_link_lib != nullptr) { - find_libc_lib_path(g); - } - - lj->args.append("-NOLOGO"); - - if (!g->strip_debug_symbols && g->zig_target.os != Os::OsUefi) { - lj->args.append("-DEBUG"); - } - - if (g->out_type == OutTypeExe) { - // TODO compile time stack upper bound detection - lj->args.append("/STACK:16777216"); - } - - coff_append_machine_arg(g, &lj->args); - - // The commented out stuff is from when we linked with MinGW - // Now that we're linking with LLD it remains to be determined - // how to handle --target-environ gnu - // These comments are a clue - - bool is_library = g->out_type == OutTypeLib; - //bool dll = g->out_type == OutTypeLib; - //bool shared = !g->is_static && dll; - //if (g->is_static) { - // lj->args.append("-Bstatic"); - //} else { - // if (dll) { - // lj->args.append("--dll"); - // } else if (shared) { - // lj->args.append("--shared"); - // } - // lj->args.append("-Bdynamic"); - // if (dll || shared) { - // lj->args.append("-e"); - // if (g->zig_target.arch.arch == ZigLLVM_x86) { - // lj->args.append("_DllMainCRTStartup@12"); - // } else { - // lj->args.append("DllMainCRTStartup"); - // } - // lj->args.append("--enable-auto-image-base"); - // } - //} - - - // These are n actual command lines from LINK.EXE UEFI builds (app & driver) to be used as guidance cleaning - // up a bit for building the COFF linker args: - // /OUT:"J:\coding\nebulae\k\x64\Release\k.efi" /LTCG:incremental /Driver /PDB:"J:\coding\nebulae\k\x64\Release\k.pdb" "UefiApplicationEntryPoint.lib" "UefiRuntimeLib.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\nebulae\k\x64\Release\k.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_APPLICATION /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" - // /OUT:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.efi" /LTCG:incremental /Driver /PDB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.pdb" "UefiDriverEntryPoint.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" - - // Sorry for the goto(s) :) - switch (g->msvc_subsystem) { - case ZigLLVM_MSVC_CONSOLE: - lj->args.append("/SUBSYSTEM:console"); - goto building_nt; - case ZigLLVM_MSVC_EFI_APPLICATION: - lj->args.append("/SUBSYSTEM:efi_application"); - goto building_uefi; - case ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER: - lj->args.append("/SUBSYSTEM:efi_boot_service_driver"); - goto building_uefi; - case ZigLLVM_MSVC_EFI_ROM: - lj->args.append("/SUBSYSTEM:efi_rom"); - goto building_uefi; - case ZigLLVM_MSVC_EFI_RUNTIME_DRIVER: - lj->args.append("/SUBSYSTEM:efi_runtime_driver"); - goto building_uefi; - case ZigLLVM_MSVC_NATIVE: - lj->args.append("/SUBSYSTEM:native"); - goto building_nt; - case ZigLLVM_MSVC_POSIX: - lj->args.append("/SUBSYSTEM:posix"); - goto building_nt; - case ZigLLVM_MSVC_WINDOWS: - lj->args.append("/SUBSYSTEM:windows"); - goto building_nt; - case ZigLLVM_MSVC_NONE: - goto continuing_build; - } - -building_uefi: - lj->args.append("/BASE:\"0\" /ENTRY:\"EfiMain\" /OPT:REF /SAFESEH:NO /MERGE:\".rdata=.data\" /ALIGN:32 /NODEFAULTLIB /SECTION:\".xdata,D\""); - goto continuing_build; - -building_nt: if (lj->link_in_crt) { const char *lib_str = g->is_static ? "lib" : ""; const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : ""; @@ -557,17 +480,6 @@ building_nt: //https://msdn.microsoft.com/en-us/library/bb531344.aspx lj->args.append("legacy_stdio_definitions.lib"); - //if (shared || dll) { - // lj->args.append(get_libc_file(g, "dllcrt2.o")); - //} else { - // if (g->windows_linker_unicode) { - // lj->args.append(get_libc_file(g, "crt2u.o")); - // } else { - // lj->args.append(get_libc_file(g, "crt2.o")); - // } - //} - //lj->args.append(get_libc_static_file(g, "crtbegin.o")); - // msvcrt depends on kernel32 lj->args.append("kernel32.lib"); } else { @@ -580,8 +492,156 @@ building_nt: } } } +} -continuing_build: +// These are n actual command lines from LINK.EXE UEFI builds (app & driver) to be used as guidance cleaning +// up a bit for building the COFF linker args: +// /OUT:"J:\coding\nebulae\k\x64\Release\k.efi" /LTCG:incremental /Driver /PDB:"J:\coding\nebulae\k\x64\Release\k.pdb" "UefiApplicationEntryPoint.lib" "UefiRuntimeLib.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\nebulae\k\x64\Release\k.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_APPLICATION /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" +// /OUT:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.efi" /LTCG:incremental /Driver /PDB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.pdb" "UefiDriverEntryPoint.lib" "UefiHiiLib.lib" "UefiHiiServicesLib.lib" "UefiSortLib.lib" "UefiShellLib.lib" "GlueLib.lib" "BaseLib.lib" "BaseDebugPrintErrorLevelLib.lib" "BasePrintLib.lib" "UefiLib.lib" "UefiBootServicesTableLib.lib" "UefiRuntimeServicesTableLib.lib" "UefiDevicePathLibDevicePathProtocol.lib" "UefiDebugLibConOut.lib" "UefiMemoryLib.lib" "UefiMemoryAllocationLib.lib" "BaseSynchronizationLib.lib" "UefiFileHandleLib.lib" /IMPLIB:"J:\coding\VisualUefi\samples\x64\Release\UefiDriver.lib" /DEBUG:FASTLINK /BASE:"0" /MACHINE:X64 /ENTRY:"EfiMain" /OPT:REF /SAFESEH:NO /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /MERGE:".rdata=.data" /NOLOGO /ALIGN:32 /NODEFAULTLIB /SECTION:".xdata,D" +// This commented out stuff is from when we linked with MinGW +// Now that we're linking with LLD it remains to be determined +// how to handle --target-environ gnu +// These comments are a clue +//bool dll = g->out_type == OutTypeLib; +//bool shared = !g->is_static && dll; +//if (g->is_static) { +// lj->args.append("-Bstatic"); +//} else { +// if (dll) { +// lj->args.append("--dll"); +// } else if (shared) { +// lj->args.append("--shared"); +// } +// lj->args.append("-Bdynamic"); +// if (dll || shared) { +// lj->args.append("-e"); +// if (g->zig_target.arch.arch == ZigLLVM_x86) { +// lj->args.append("_DllMainCRTStartup@12"); +// } else { +// lj->args.append("DllMainCRTStartup"); +// } +// lj->args.append("--enable-auto-image-base"); +// } +//} +//if (shared || dll) { +// lj->args.append(get_libc_file(g, "dllcrt2.o")); +//} else { +// if (g->windows_linker_unicode) { +// lj->args.append(get_libc_file(g, "crt2u.o")); +// } else { +// lj->args.append(get_libc_file(g, "crt2.o")); +// } +//} +//lj->args.append(get_libc_static_file(g, "crtbegin.o")); +//if (g->libc_link_lib != nullptr) { +//if (g->is_static) { +// lj->args.append("--start-group"); +//} + +//lj->args.append("-lmingw32"); + +//lj->args.append("-lgcc"); +//bool is_android = (g->zig_target.env_type == ZigLLVM_Android); +//bool is_cyg_ming = is_target_cyg_mingw(&g->zig_target); +//if (!g->is_static && !is_android) { +// if (!is_cyg_ming) { +// lj->args.append("--as-needed"); +// } +// //lj->args.append("-lgcc_s"); +// if (!is_cyg_ming) { +// lj->args.append("--no-as-needed"); +// } +//} +//if (g->is_static && !is_android) { +// //lj->args.append("-lgcc_eh"); +//} +//if (is_android && !g->is_static) { +// lj->args.append("-ldl"); +//} + +//lj->args.append("-lmoldname"); +//lj->args.append("-lmingwex"); +//lj->args.append("-lmsvcrt"); + + +//if (g->windows_subsystem_windows) { +// lj->args.append("-lgdi32"); +// lj->args.append("-lcomdlg32"); +//} +//lj->args.append("-ladvapi32"); +//lj->args.append("-lshell32"); +//lj->args.append("-luser32"); +//lj->args.append("-lkernel32"); + +//if (g->is_static) { +// lj->args.append("--end-group"); +//} + +//if (lj->link_in_crt) { +// lj->args.append(get_libc_static_file(g, "crtend.o")); +//} +//} + + +static void construct_linker_job_coff(LinkJob *lj) { + CodeGen *g = lj->codegen; + + lj->args.append("/ERRORLIMIT:0"); + + if (g->libc_link_lib != nullptr) { + find_libc_lib_path(g); + } + + lj->args.append("/NOLOGO"); + + if (!g->strip_debug_symbols) { + lj->args.append("/DEBUG"); + } + + if (g->out_type == OutTypeExe) { + // TODO compile time stack upper bound detection + lj->args.append("/STACK:16777216"); + } + + coff_append_machine_arg(g, &lj->args); + + bool is_library = g->out_type == OutTypeLib; + switch (g->subsystem) { + case TargetSubsystemAuto: + break; + case TargetSubsystemConsole: + lj->args.append("/SUBSYSTEM:console"); + add_nt_link_args(lj, is_library); + break; + case TargetSubsystemEfiApplication: + lj->args.append("/SUBSYSTEM:efi_application"); + add_uefi_link_args(lj); + break; + case TargetSubsystemEfiBootServiceDriver: + lj->args.append("/SUBSYSTEM:efi_boot_service_driver"); + add_uefi_link_args(lj); + break; + case TargetSubsystemEfiRom: + lj->args.append("/SUBSYSTEM:efi_rom"); + add_uefi_link_args(lj); + break; + case TargetSubsystemEfiRuntimeDriver: + lj->args.append("/SUBSYSTEM:efi_runtime_driver"); + add_uefi_link_args(lj); + break; + case TargetSubsystemNative: + lj->args.append("/SUBSYSTEM:native"); + add_nt_link_args(lj, is_library); + break; + case TargetSubsystemPosix: + lj->args.append("/SUBSYSTEM:posix"); + add_nt_link_args(lj, is_library); + break; + case TargetSubsystemWindows: + lj->args.append("/SUBSYSTEM:windows"); + add_nt_link_args(lj, is_library); + break; + } lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); @@ -665,54 +725,6 @@ continuing_build: } } - //if (g->libc_link_lib != nullptr) { - //if (g->is_static) { - // lj->args.append("--start-group"); - //} - - //lj->args.append("-lmingw32"); - - //lj->args.append("-lgcc"); - //bool is_android = (g->zig_target.env_type == ZigLLVM_Android); - //bool is_cyg_ming = is_target_cyg_mingw(&g->zig_target); - //if (!g->is_static && !is_android) { - // if (!is_cyg_ming) { - // lj->args.append("--as-needed"); - // } - // //lj->args.append("-lgcc_s"); - // if (!is_cyg_ming) { - // lj->args.append("--no-as-needed"); - // } - //} - //if (g->is_static && !is_android) { - // //lj->args.append("-lgcc_eh"); - //} - //if (is_android && !g->is_static) { - // lj->args.append("-ldl"); - //} - - //lj->args.append("-lmoldname"); - //lj->args.append("-lmingwex"); - //lj->args.append("-lmsvcrt"); - - - //if (g->windows_subsystem_windows) { - // lj->args.append("-lgdi32"); - // lj->args.append("-lcomdlg32"); - //} - //lj->args.append("-ladvapi32"); - //lj->args.append("-lshell32"); - //lj->args.append("-luser32"); - //lj->args.append("-lkernel32"); - - //if (g->is_static) { - // lj->args.append("--end-group"); - //} - - //if (lj->link_in_crt) { - // lj->args.append(get_libc_static_file(g, "crtend.o")); - //} - //} } diff --git a/src/main.cpp b/src/main.cpp index faca9511dc..fd8e3db2fa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,13 +16,6 @@ #include -#ifdef __GNUC__ -#include -#define STRCASECMP strcasecmp -#else -#define STRCASECMP stricmp -#endif - static int print_error_usage(const char *arg0) { fprintf(stderr, "See `%s help` for detailed usage information\n", arg0); return EXIT_FAILURE; @@ -97,8 +90,8 @@ static int print_full_usage(const char *arg0) { " -rdynamic add all symbols to the dynamic symbol table\n" " -rpath [path] add directory to the runtime library search path\n" " --no-rosegment compromise security to workaround valgrind bug\n" - " --msvc-subsystem [subsystem] (windows/uefi) /SUBSYSTEM: to the linker\n" - " -framework [name] (darwin) link against framework\n" + " --subsystem [subsystem] (windows) /SUBSYSTEM: to the linker\n" + " -framework [name] (darwin) link against framework\n" " -mios-version-min [ver] (darwin) set iOS deployment target\n" " -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target\n" " --ver-major [ver] dynamic library semver major version\n" @@ -377,8 +370,6 @@ int main(int argc, char **argv) { const char *target_arch = nullptr; const char *target_os = nullptr; const char *target_environ = nullptr; - bool mwindows = false; - bool mconsole = false; bool rdynamic = false; const char *mmacosx_version_min = nullptr; const char *mios_version_min = nullptr; @@ -401,7 +392,7 @@ int main(int argc, char **argv) { int runtime_args_start = -1; bool no_rosegment_workaround = false; bool system_linker_hack = false; - ZigLLVM_MSVCSubsystemType msvc_subsystem_type = ZigLLVM_MSVC_NONE; + TargetSubsystem subsystem = TargetSubsystemAuto; if (argc >= 2 && strcmp(argv[1], "build") == 0) { Buf zig_exe_path_buf = BUF_INIT; @@ -547,36 +538,6 @@ int main(int argc, char **argv) { verbose_llvm_ir = true; } else if (strcmp(arg, "--verbose-cimport") == 0) { verbose_cimport = true; - } else if (strcmp(arg, "--msvc-subsystem") == 0) { - if (i + 1 >= argc) { - fprintf(stderr, "Expected 1 argument after --msvc-subsystem\n"); - return print_error_usage(arg0); - } - i += 1; - if (STRCASECMP(argv[i], "CONSOLE") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_CONSOLE; - } else if (STRCASECMP(argv[i], "WINDOWS") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_WINDOWS; - } else if (STRCASECMP(argv[i], "POSIX") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_POSIX; - } else if (STRCASECMP(argv[i], "NATIVE") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_NATIVE; - } else if (STRCASECMP(argv[i], "EFI_APPLICATION") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_EFI_APPLICATION; - } else if (STRCASECMP(argv[i], "EFI_BOOT_SERVICE_DRIVER") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER; - } else if (STRCASECMP(argv[i], "EFI_ROM") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_EFI_ROM; - } else if (STRCASECMP(argv[i], "EFI_RUNTIME_DRIVER") == 0) { - msvc_subsystem_type = ZigLLVM_MSVC_EFI_RUNTIME_DRIVER; - } else { - fprintf(stderr, "Unknown format %s for --msvc-subsystem argument\n", argv[i]); - return EXIT_FAILURE; - } - } else if (strcmp(arg, "-mwindows") == 0) { - mwindows = true; - } else if (strcmp(arg, "-mconsole") == 0) { - mconsole = true; } else if (strcmp(arg, "-rdynamic") == 0) { rdynamic = true; } else if (strcmp(arg, "--no-rosegment") == 0) { @@ -720,6 +681,37 @@ int main(int argc, char **argv) { ver_patch = atoi(argv[i]); } else if (strcmp(arg, "--test-cmd") == 0) { test_exec_args.append(argv[i]); + } else if (strcmp(arg, "--subsystem") == 0) { + if (strcmp(argv[i], "console") == 0) { + subsystem = TargetSubsystemConsole; + } else if (strcmp(argv[i], "windows") == 0) { + subsystem = TargetSubsystemWindows; + } else if (strcmp(argv[i], "posix") == 0) { + subsystem = TargetSubsystemPosix; + } else if (strcmp(argv[i], "native") == 0) { + subsystem = TargetSubsystemNative; + } else if (strcmp(argv[i], "efi_application") == 0) { + subsystem = TargetSubsystemEfiApplication; + } else if (strcmp(argv[i], "efi_boot_service_driver") == 0) { + subsystem = TargetSubsystemEfiBootServiceDriver; + } else if (strcmp(argv[i], "efi_rom") == 0) { + subsystem = TargetSubsystemEfiRom; + } else if (strcmp(argv[i], "efi_runtime_driver") == 0) { + subsystem = TargetSubsystemEfiRuntimeDriver; + } else { + fprintf(stderr, "invalid: --subsystem %s\n" + "Options are:\n" + " console\n" + " windows\n" + " posix\n" + " native\n" + " efi_application\n" + " efi_boot_service_driver\n" + " efi_rom\n" + " efi_runtime_driver\n" + , argv[i]); + return EXIT_FAILURE; + } } else { fprintf(stderr, "Invalid argument: %s\n", arg); return print_error_usage(arg0); @@ -882,7 +874,7 @@ int main(int argc, char **argv) { buf_out_name = buf_create_from_str("run"); } CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir()); - g->msvc_subsystem = msvc_subsystem_type; + g->subsystem = subsystem; if (disable_pic) { if (out_type != OutTypeLib || !is_static) { diff --git a/src/target.cpp b/src/target.cpp index 61543c38d5..6fea79518c 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -283,6 +283,7 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type) { case OsSolaris: return ZigLLVM_Solaris; case OsWindows: + case OsUefi: return ZigLLVM_Win32; case OsHaiku: return ZigLLVM_Haiku; @@ -316,8 +317,6 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type) { return ZigLLVM_Contiki; case OsAMDPAL: return ZigLLVM_AMDPAL; - case OsUefi: - return ZigLLVM_Uefi; } zig_unreachable(); } @@ -809,7 +808,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { } const char *target_o_file_ext(ZigTarget *target) { - if (target->env_type == ZigLLVM_MSVC || (target->os == OsWindows || target->os == OsUefi)) { + if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) { return ".obj"; } else { return ".o"; diff --git a/src/target.hpp b/src/target.hpp index 62cc20711a..a87b12351a 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -54,13 +54,24 @@ enum Os { OsUefi, }; +enum TargetSubsystem { + TargetSubsystemAuto, // Zig should infer the subsystem + TargetSubsystemConsole, + TargetSubsystemWindows, + TargetSubsystemPosix, + TargetSubsystemNative, + TargetSubsystemEfiApplication, + TargetSubsystemEfiBootServiceDriver, + TargetSubsystemEfiRom, + TargetSubsystemEfiRuntimeDriver, +}; + struct ZigTarget { ArchType arch; ZigLLVM_VendorType vendor; Os os; ZigLLVM_EnvironmentType env_type; ZigLLVM_ObjectFormatType oformat; - ZigLLVM_MSVCSubsystemType msvc_subsystem = ZigLLVM_MSVC_NONE; }; enum CIntType { diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 0e56e29810..02fa3b24be 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -4749,7 +4749,7 @@ Error parse_h_file(ImportTableEntry *import, ZigList *errors, const clang_argv.append("-isystem"); clang_argv.append(buf_ptr(codegen->zig_c_headers_dir)); - if (codegen->libc_include_dir) { + if (codegen->libc_include_dir != nullptr) { clang_argv.append("-isystem"); clang_argv.append(buf_ptr(codegen->libc_include_dir)); } diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index bd63b7cbe5..bda8fa0adc 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -690,12 +690,7 @@ const char *ZigLLVMGetVendorTypeName(ZigLLVM_VendorType vendor) { } const char *ZigLLVMGetOSTypeName(ZigLLVM_OSType os) { - switch (os) { - case ZigLLVM_Uefi: - return "windows"; - default: - return (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin(); - } + return (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin(); } const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type) { diff --git a/src/zig_llvm.h b/src/zig_llvm.h index bb7cb5c5ff..551a4a7448 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -358,8 +357,8 @@ enum ZigLLVM_OSType { ZigLLVM_Mesa3D, ZigLLVM_Contiki, ZigLLVM_AMDPAL, // AMD PAL Runtime - ZigLLVM_Uefi, - ZigLLVM_LastOSType = ZigLLVM_Uefi + + ZigLLVM_LastOSType = ZigLLVM_AMDPAL }; // Synchronize with target.cpp::environ_list @@ -398,19 +397,6 @@ enum ZigLLVM_ObjectFormatType { ZigLLVM_Wasm, }; -// For MSVC-supported subsystems -enum ZigLLVM_MSVCSubsystemType { - ZigLLVM_MSVC_NONE, - ZigLLVM_MSVC_CONSOLE, - ZigLLVM_MSVC_WINDOWS, - ZigLLVM_MSVC_POSIX, - ZigLLVM_MSVC_NATIVE, - ZigLLVM_MSVC_EFI_APPLICATION, - ZigLLVM_MSVC_EFI_BOOT_SERVICE_DRIVER, - ZigLLVM_MSVC_EFI_ROM, - ZigLLVM_MSVC_EFI_RUNTIME_DRIVER, -}; - ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch); ZIG_EXTERN_C const char *ZigLLVMGetSubArchTypeName(enum ZigLLVM_SubArchType sub_arch); ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor); diff --git a/std/os/index.zig b/std/os/index.zig index ce65667157..bb2eb76265 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -18,7 +18,7 @@ test "std.os" { _ = @import("test.zig"); _ = @import("time.zig"); _ = @import("windows/index.zig"); - _ = @import("uefi/index.zig"); + _ = @import("uefi.zig"); _ = @import("get_app_data_dir.zig"); } @@ -27,7 +27,7 @@ pub const darwin = @import("darwin.zig"); pub const linux = @import("linux/index.zig"); pub const freebsd = @import("freebsd/index.zig"); pub const zen = @import("zen.zig"); -pub const uefi = @import("uefi/index.zig"); +pub const uefi = @import("uefi.zig"); pub const posix = switch (builtin.os) { Os.linux => linux, @@ -192,6 +192,7 @@ pub fn abort() noreturn { windows.ExitProcess(3); }, Os.uefi => { + // TODO there's gotta be a better thing to do here than loop forever while (true) {} }, else => @compileError("Unsupported OS"), diff --git a/std/os/uefi.zig b/std/os/uefi.zig new file mode 100644 index 0000000000..8ed60d9c9b --- /dev/null +++ b/std/os/uefi.zig @@ -0,0 +1,2 @@ +// TODO this is where the extern declarations go. For example, see +// inc/efilib.h in gnu-efi-code diff --git a/std/os/uefi/index.zig b/std/os/uefi/index.zig deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/std/special/panic.zig b/std/special/panic.zig index fe1e020604..bd3ad971e0 100644 --- a/std/special/panic.zig +++ b/std/special/panic.zig @@ -10,9 +10,13 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn @setCold(true); switch (builtin.os) { // TODO: fix panic in zen. - builtin.Os.freestanding, builtin.Os.zen, builtin.Os.uefi => { + builtin.Os.freestanding, builtin.Os.zen => { while (true) {} }, + builtin.Os.uefi => { + // TODO look into using the debug info and logging helpful messages + std.os.abort(); + }, else => { const first_trace_addr = @ptrToInt(@returnAddress()); std.debug.panicExtra(error_return_trace, first_trace_addr, "{}", msg); From c29cae76b0fefe4af53d3f4fe72f8e3e95c93809 Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Wed, 26 Dec 2018 22:44:13 -0200 Subject: [PATCH 29/34] tests: add FreeBSD to the test matrix --- test/tests.zig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/tests.zig b/test/tests.zig index 1ca06b4b34..866955f707 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -38,6 +38,11 @@ const test_targets = []TestTarget{ .arch = builtin.Arch.x86_64, .environ = builtin.Environ.unknown, }, + TestTarget{ + .os = builtin.Os.freebsd, + .arch = builtin.Arch.x86_64, + .environ = builtin.Environ.unknown, + }, TestTarget{ .os = builtin.Os.windows, .arch = builtin.Arch.x86_64, From aaef6259c32ff43be912c31f70e005170ee86efd Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 26 Dec 2018 20:44:06 -0500 Subject: [PATCH 30/34] allow not having libc include paths and doing @cImport --- src/analyze.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index 04d957b626..3e2e5abc74 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -4590,8 +4590,7 @@ static Buf *get_posix_libc_include_path(void) { void find_libc_include_path(CodeGen *g) { if (g->libc_include_dir == nullptr) { if (!g->is_native_target) { - fprintf(stderr, "Unable to determine libc include path. --libc-include-dir"); - exit(1); + return; } if (g->zig_target.os == OsWindows) { From 64061cc1bfb8e925d20f5824aa178b61eb2e5f11 Mon Sep 17 00:00:00 2001 From: alexander Date: Thu, 27 Dec 2018 13:46:32 -0600 Subject: [PATCH 31/34] Test cases for compiler error and working behavior for switching on booleans --- test/cases/switch.zig | 37 +++++++++++++++++++++++++++++++++++++ test/compile_errors.zig | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/test/cases/switch.zig b/test/cases/switch.zig index d5258f0bb1..1162fdd4b2 100644 --- a/test/cases/switch.zig +++ b/test/cases/switch.zig @@ -232,3 +232,40 @@ test "capture value of switch with all unreachable prongs" { }; assert(x == 1); } + +test "switching on booleans" { + testSwitchOnBools(); + comptime testSwitchOnBools(); +} + +fn testSwitchOnBools() void { + assert(testSwitchOnBoolsTrueAndFalse(true) == false); + assert(testSwitchOnBoolsTrueAndFalse(false) == true); + + assert(testSwitchOnBoolsTrueWithElse(true) == false); + assert(testSwitchOnBoolsTrueWithElse(false) == true); + + assert(testSwitchOnBoolsFalseWithElse(true) == false); + assert(testSwitchOnBoolsFalseWithElse(false) == true); +} + +fn testSwitchOnBoolsTrueAndFalse(x: bool) bool { + return switch (x) { + true => false, + false => true, + }; +} + +fn testSwitchOnBoolsTrueWithElse(x: bool) bool { + return switch (x) { + true => false, + else => true, + }; +} + +fn testSwitchOnBoolsFalseWithElse(x: bool) bool { + return switch (x) { + false => true, + else => false, + }; +} diff --git a/test/compile_errors.zig b/test/compile_errors.zig index ee3741ee6b..880a96a322 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -1,6 +1,44 @@ const tests = @import("tests.zig"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.add( + "duplicate boolean switch value", + \\comptime { + \\ const x = switch (true) { + \\ true => false, + \\ false => true, + \\ true => false, + \\ }; + \\} + \\comptime { + \\ const x = switch (true) { + \\ false => true, + \\ true => false, + \\ false => true, + \\ }; + \\} + , + ".tmp_source.zig:5:9: error: duplicate switch value", + ".tmp_source.zig:12:9: error: duplicate switch value", + ); + + cases.add( + "missing boolean switch value", + \\comptime { + \\ const x = switch (true) { + \\ true => false, + \\ }; + \\} + \\comptime { + \\ const x = switch (true) { + \\ false => true, + \\ }; + \\} + , + ".tmp_source.zig:2:15: error: switch must handle all possibilities", + ".tmp_source.zig:7:15: error: switch must handle all possibilities", + ); + cases.add( "reading past end of pointer casted array", \\comptime { From 4ff23b668a339b28dceba3d6bc584009aacd1678 Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Fri, 28 Dec 2018 11:38:58 -0200 Subject: [PATCH 32/34] tests: remove freebsd from the test matrix - Manually add all the native tests to CI manifest. --- .builds/freebsd.yml | 30 ++++++++++++++++++++++++++++++ test/tests.zig | 5 ----- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/.builds/freebsd.yml b/.builds/freebsd.yml index db1ddb337a..f337bae233 100644 --- a/.builds/freebsd.yml +++ b/.builds/freebsd.yml @@ -14,6 +14,36 @@ tasks: - test: | cd zig/build bin/zig test ../test/behavior.zig + bin/zig test ../std/special/compiler_rt/index.zig + bin/zig test ../std/index.zig + + bin/zig test ../test/behavior.zig --library c + bin/zig test ../std/special/compiler_rt/index.zig --library c + bin/zig test ../std/index.zig --library c + + bin/zig test ../test/behavior.zig --release-fast + bin/zig test ../std/special/compiler_rt/index.zig --release-fast + bin/zig test ../std/index.zig --release-fast + + bin/zig test ../test/behavior.zig --release-fast --library c + bin/zig test ../std/special/compiler_rt/index.zig --release-fast --library c + bin/zig test ../std/index.zig --release-fast --library c + + bin/zig test ../test/behavior.zig --release-small --library c + bin/zig test ../std/special/compiler_rt/index.zig --release-small --library c + bin/zig test ../std/index.zig --release-small --library c + + bin/zig test ../test/behavior.zig --release-small + bin/zig test ../std/special/compiler_rt/index.zig --release-small + bin/zig test ../std/index.zig --release-small + + bin/zig test ../test/behavior.zig --release-safe + bin/zig test ../std/special/compiler_rt/index.zig --release-safe + bin/zig test ../std/index.zig --release-safe + + bin/zig test ../test/behavior.zig --release-safe --library c + bin/zig test ../std/special/compiler_rt/index.zig --release-safe --library c + bin/zig test ../std/index.zig --release-safe --library c # TODO enable all tests #bin/zig build --build-file ../build.zig test # TODO integrate with the download page updater and make a diff --git a/test/tests.zig b/test/tests.zig index 866955f707..1ca06b4b34 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -38,11 +38,6 @@ const test_targets = []TestTarget{ .arch = builtin.Arch.x86_64, .environ = builtin.Environ.unknown, }, - TestTarget{ - .os = builtin.Os.freebsd, - .arch = builtin.Arch.x86_64, - .environ = builtin.Environ.unknown, - }, TestTarget{ .os = builtin.Os.windows, .arch = builtin.Arch.x86_64, From 2e08bd6be4a3b472fcaa69f0cb7683b269cdacdd Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Fri, 28 Dec 2018 15:36:43 -0200 Subject: [PATCH 33/34] ci: update freebsd manifest --- .builds/freebsd.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.builds/freebsd.yml b/.builds/freebsd.yml index f337bae233..c7d92712b0 100644 --- a/.builds/freebsd.yml +++ b/.builds/freebsd.yml @@ -1,5 +1,4 @@ -arch: x86_64 -image: freebsd +image: freebsd/latest packages: - cmake - ninja @@ -15,35 +14,27 @@ tasks: cd zig/build bin/zig test ../test/behavior.zig bin/zig test ../std/special/compiler_rt/index.zig - bin/zig test ../std/index.zig bin/zig test ../test/behavior.zig --library c bin/zig test ../std/special/compiler_rt/index.zig --library c - bin/zig test ../std/index.zig --library c bin/zig test ../test/behavior.zig --release-fast bin/zig test ../std/special/compiler_rt/index.zig --release-fast - bin/zig test ../std/index.zig --release-fast bin/zig test ../test/behavior.zig --release-fast --library c bin/zig test ../std/special/compiler_rt/index.zig --release-fast --library c - bin/zig test ../std/index.zig --release-fast --library c bin/zig test ../test/behavior.zig --release-small --library c bin/zig test ../std/special/compiler_rt/index.zig --release-small --library c - bin/zig test ../std/index.zig --release-small --library c bin/zig test ../test/behavior.zig --release-small bin/zig test ../std/special/compiler_rt/index.zig --release-small - bin/zig test ../std/index.zig --release-small bin/zig test ../test/behavior.zig --release-safe bin/zig test ../std/special/compiler_rt/index.zig --release-safe - bin/zig test ../std/index.zig --release-safe bin/zig test ../test/behavior.zig --release-safe --library c bin/zig test ../std/special/compiler_rt/index.zig --release-safe --library c - bin/zig test ../std/index.zig --release-safe --library c # TODO enable all tests #bin/zig build --build-file ../build.zig test # TODO integrate with the download page updater and make a From 6df8e4bca73309f2e340dbfa9031f1bb16a73bcc Mon Sep 17 00:00:00 2001 From: alexander Date: Sat, 29 Dec 2018 21:49:31 -0600 Subject: [PATCH 34/34] Add DIFlagStaticMember flag to functions. Prevents LLVM from generating debug info for struct member functions with a pointer as the first parameter as though the first parameter were the implicit "this" pointer from C++. --- src/zig_llvm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index bda8fa0adc..3c01a0954d 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -605,7 +605,7 @@ ZigLLVMDISubprogram *ZigLLVMCreateFunction(ZigLLVMDIBuilder *dibuilder, ZigLLVMD reinterpret_cast(file), lineno, di_sub_type, - is_local_to_unit, is_definition, scope_line, DINode::FlagZero, is_optimized, + is_local_to_unit, is_definition, scope_line, DINode::FlagStaticMember, is_optimized, nullptr, reinterpret_cast(decl_subprogram)); return reinterpret_cast(result);