diff --git a/lib/std/atomic.zig b/lib/std/atomic.zig index 2efcefdd42cc64ffeb79bb372ce0b3aba276436b..e1a6767590ee5ea031acbb0f501912a71d8864cb 100644 --- a/lib/std/atomic.zig +++ b/lib/std/atomic.zig @@ -433,18 +433,20 @@ pub const cache_line = switch (builtin.cpu.arch) { .powerpc64le, => 128, + // https://github.com/llvm/llvm-project/blob/e379094328e49731a606304f7e3559d4f1fa96f9/clang/lib/Basic/Targets/Hexagon.h#L145-L151 + .hexagon, + => if (std.Target.hexagon.featureSetHas(builtin.target.cpu.features, .v73)) 64 else 32, + // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_arm.go#L7 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips.go#L7 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mipsle.go#L7 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips64x.go#L9 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_riscv64.go#L7 - // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/hexagon/include/asm/cache.h#L13 // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/sparc/include/asm/cache.h#L14 .arm, .armeb, .thumb, .thumbeb, - .hexagon, .mips, .mipsel, .mips64, diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 40dfcb933b5763cf83b1d46c3103a7c6a2e7adb0..dc734d08431c7adc7101dc13d8f4a70b0ca639cf 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -37,8 +37,9 @@ const syscall_bits = switch (native_arch) { const arch_bits = switch (native_arch) { .x86 => @import("linux/x86.zig"), .x86_64 => @import("linux/x86_64.zig"), - .aarch64, .aarch64_be => @import("linux/arm64.zig"), - .arm, .armeb, .thumb, .thumbeb => @import("linux/arm-eabi.zig"), + .aarch64, .aarch64_be => @import("linux/aarch64.zig"), + .arm, .armeb, .thumb, .thumbeb => @import("linux/arm.zig"), + .hexagon => @import("linux/hexagon.zig"), .riscv32 => @import("linux/riscv32.zig"), .riscv64 => @import("linux/riscv64.zig"), .sparc64 => @import("linux/sparc64.zig"), @@ -116,7 +117,7 @@ pub const user_desc = arch_bits.user_desc; pub const getcontext = arch_bits.getcontext; pub const tls = @import("linux/tls.zig"); -pub const pie = @import("linux/start_pie.zig"); +pub const pie = @import("linux/pie.zig"); pub const BPF = @import("linux/bpf.zig"); pub const IOCTL = @import("linux/ioctl.zig"); pub const SECCOMP = @import("linux/seccomp.zig"); @@ -277,7 +278,7 @@ pub const MAP = switch (native_arch) { UNINITIALIZED: bool = false, _: u5 = 0, }, - .s390x => packed struct(u32) { + .hexagon, .s390x => packed struct(u32) { TYPE: MAP_TYPE, FIXED: bool = false, ANONYMOUS: bool = false, @@ -441,7 +442,7 @@ pub const O = switch (native_arch) { TMPFILE: bool = false, _: u9 = 0, }, - .s390x => packed struct(u32) { + .hexagon, .s390x => packed struct(u32) { ACCMODE: ACCMODE = .RDONLY, _2: u4 = 0, CREAT: bool = false, diff --git a/lib/std/os/linux/aarch64.zig b/lib/std/os/linux/aarch64.zig new file mode 100644 index 0000000000000000000000000000000000000000..9248360ae97dd2af673b8a2fca2046a3d5622eae --- /dev/null +++ b/lib/std/os/linux/aarch64.zig @@ -0,0 +1,288 @@ +const std = @import("../../std.zig"); +const maxInt = std.math.maxInt; +const linux = std.os.linux; +const SYS = linux.SYS; +const socklen_t = linux.socklen_t; +const sockaddr = linux.sockaddr; +const iovec = std.posix.iovec; +const iovec_const = std.posix.iovec_const; +const uid_t = linux.uid_t; +const gid_t = linux.gid_t; +const pid_t = linux.pid_t; +const stack_t = linux.stack_t; +const sigset_t = linux.sigset_t; +const timespec = std.os.linux.timespec; + +pub fn syscall0(number: SYS) usize { + return asm volatile ("svc #0" + : [ret] "={x0}" (-> usize), + : [number] "{x8}" (@intFromEnum(number)), + : "memory", "cc" + ); +} + +pub fn syscall1(number: SYS, arg1: usize) usize { + return asm volatile ("svc #0" + : [ret] "={x0}" (-> usize), + : [number] "{x8}" (@intFromEnum(number)), + [arg1] "{x0}" (arg1), + : "memory", "cc" + ); +} + +pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize { + return asm volatile ("svc #0" + : [ret] "={x0}" (-> usize), + : [number] "{x8}" (@intFromEnum(number)), + [arg1] "{x0}" (arg1), + [arg2] "{x1}" (arg2), + : "memory", "cc" + ); +} + +pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize { + return asm volatile ("svc #0" + : [ret] "={x0}" (-> usize), + : [number] "{x8}" (@intFromEnum(number)), + [arg1] "{x0}" (arg1), + [arg2] "{x1}" (arg2), + [arg3] "{x2}" (arg3), + : "memory", "cc" + ); +} + +pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { + return asm volatile ("svc #0" + : [ret] "={x0}" (-> usize), + : [number] "{x8}" (@intFromEnum(number)), + [arg1] "{x0}" (arg1), + [arg2] "{x1}" (arg2), + [arg3] "{x2}" (arg3), + [arg4] "{x3}" (arg4), + : "memory", "cc" + ); +} + +pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { + return asm volatile ("svc #0" + : [ret] "={x0}" (-> usize), + : [number] "{x8}" (@intFromEnum(number)), + [arg1] "{x0}" (arg1), + [arg2] "{x1}" (arg2), + [arg3] "{x2}" (arg3), + [arg4] "{x3}" (arg4), + [arg5] "{x4}" (arg5), + : "memory", "cc" + ); +} + +pub fn syscall6( + number: SYS, + arg1: usize, + arg2: usize, + arg3: usize, + arg4: usize, + arg5: usize, + arg6: usize, +) usize { + return asm volatile ("svc #0" + : [ret] "={x0}" (-> usize), + : [number] "{x8}" (@intFromEnum(number)), + [arg1] "{x0}" (arg1), + [arg2] "{x1}" (arg2), + [arg3] "{x2}" (arg3), + [arg4] "{x3}" (arg4), + [arg5] "{x4}" (arg5), + [arg6] "{x5}" (arg6), + : "memory", "cc" + ); +} + +pub fn clone() callconv(.Naked) usize { + // __clone(func, stack, flags, arg, ptid, tls, ctid) + // x0, x1, w2, x3, x4, x5, x6 + // + // syscall(SYS_clone, flags, stack, ptid, tls, ctid) + // x8, x0, x1, x2, x3, x4 + asm volatile ( + \\ // align stack and save func,arg + \\ and x1,x1,#-16 + \\ stp x0,x3,[x1,#-16]! + \\ + \\ // syscall + \\ uxtw x0,w2 + \\ mov x2,x4 + \\ mov x3,x5 + \\ mov x4,x6 + \\ mov x8,#220 // SYS_clone + \\ svc #0 + \\ + \\ cbz x0,1f + \\ // parent + \\ ret + \\ // child + \\1: ldp x1,x0,[sp],#16 + \\ blr x1 + \\ mov x8,#93 // SYS_exit + \\ svc #0 + ); +} + +pub const restore = restore_rt; + +pub fn restore_rt() callconv(.Naked) noreturn { + switch (@import("builtin").zig_backend) { + .stage2_c => asm volatile ( + \\ mov x8, %[number] + \\ svc #0 + : + : [number] "i" (@intFromEnum(SYS.rt_sigreturn)), + : "memory", "cc" + ), + else => asm volatile ( + \\ svc #0 + : + : [number] "{x8}" (@intFromEnum(SYS.rt_sigreturn)), + : "memory", "cc" + ), + } +} + +pub const F = struct { + pub const DUPFD = 0; + pub const GETFD = 1; + pub const SETFD = 2; + pub const GETFL = 3; + pub const SETFL = 4; + + pub const SETOWN = 8; + pub const GETOWN = 9; + pub const SETSIG = 10; + pub const GETSIG = 11; + + pub const GETLK = 5; + pub const SETLK = 6; + pub const SETLKW = 7; + + pub const RDLCK = 0; + pub const WRLCK = 1; + pub const UNLCK = 2; + + pub const SETOWN_EX = 15; + pub const GETOWN_EX = 16; + + pub const GETOWNER_UIDS = 17; +}; + +pub const VDSO = struct { + pub const CGT_SYM = "__kernel_clock_gettime"; + pub const CGT_VER = "LINUX_2.6.39"; +}; + +pub const Flock = extern struct { + type: i16, + whence: i16, + start: off_t, + len: off_t, + pid: pid_t, + __unused: [4]u8, +}; + +pub const msghdr = extern struct { + name: ?*sockaddr, + namelen: socklen_t, + iov: [*]iovec, + iovlen: i32, + __pad1: i32 = 0, + control: ?*anyopaque, + controllen: socklen_t, + __pad2: socklen_t = 0, + flags: i32, +}; + +pub const msghdr_const = extern struct { + name: ?*const sockaddr, + namelen: socklen_t, + iov: [*]const iovec_const, + iovlen: i32, + __pad1: i32 = 0, + control: ?*const anyopaque, + controllen: socklen_t, + __pad2: socklen_t = 0, + flags: i32, +}; + +pub const blksize_t = i32; +pub const nlink_t = u32; +pub const time_t = isize; +pub const mode_t = u32; +pub const off_t = isize; +pub const ino_t = usize; +pub const dev_t = usize; +pub const blkcnt_t = isize; + +// The `stat` definition used by the Linux kernel. +pub const Stat = extern struct { + dev: dev_t, + ino: ino_t, + mode: mode_t, + nlink: nlink_t, + uid: uid_t, + gid: gid_t, + rdev: dev_t, + __pad: usize, + size: off_t, + blksize: blksize_t, + __pad2: i32, + blocks: blkcnt_t, + atim: timespec, + mtim: timespec, + ctim: timespec, + __unused: [2]u32, + + pub fn atime(self: @This()) timespec { + return self.atim; + } + + pub fn mtime(self: @This()) timespec { + return self.mtim; + } + + pub fn ctime(self: @This()) timespec { + return self.ctim; + } +}; + +pub const timeval = extern struct { + sec: isize, + usec: isize, +}; + +pub const timezone = extern struct { + minuteswest: i32, + dsttime: i32, +}; + +pub const mcontext_t = extern struct { + fault_address: usize, + regs: [31]usize, + sp: usize, + pc: usize, + pstate: usize, + // Make sure the field is correctly aligned since this area + // holds various FP/vector registers + reserved1: [256 * 16]u8 align(16), +}; + +pub const ucontext_t = extern struct { + flags: usize, + link: ?*ucontext_t, + stack: stack_t, + sigmask: sigset_t, + mcontext: mcontext_t, +}; + +/// TODO +pub const getcontext = {}; + +pub const Elf_Symndx = u32; diff --git a/lib/std/os/linux/arm-eabi.zig b/lib/std/os/linux/arm-eabi.zig deleted file mode 100644 index 1d22b8c3dba79e1c1b83f4af2fb682a19da0a399..0000000000000000000000000000000000000000 --- a/lib/std/os/linux/arm-eabi.zig +++ /dev/null @@ -1,344 +0,0 @@ -const std = @import("../../std.zig"); -const maxInt = std.math.maxInt; -const linux = std.os.linux; -const SYS = linux.SYS; -const iovec = std.posix.iovec; -const iovec_const = std.posix.iovec_const; -const socklen_t = linux.socklen_t; -const stack_t = linux.stack_t; -const sigset_t = linux.sigset_t; -const uid_t = linux.uid_t; -const gid_t = linux.gid_t; -const pid_t = linux.pid_t; -const sockaddr = linux.sockaddr; -const timespec = linux.timespec; - -pub fn syscall0(number: SYS) usize { - return asm volatile ("svc #0" - : [ret] "={r0}" (-> usize), - : [number] "{r7}" (@intFromEnum(number)), - : "memory" - ); -} - -pub fn syscall1(number: SYS, arg1: usize) usize { - return asm volatile ("svc #0" - : [ret] "={r0}" (-> usize), - : [number] "{r7}" (@intFromEnum(number)), - [arg1] "{r0}" (arg1), - : "memory" - ); -} - -pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize { - return asm volatile ("svc #0" - : [ret] "={r0}" (-> usize), - : [number] "{r7}" (@intFromEnum(number)), - [arg1] "{r0}" (arg1), - [arg2] "{r1}" (arg2), - : "memory" - ); -} - -pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize { - return asm volatile ("svc #0" - : [ret] "={r0}" (-> usize), - : [number] "{r7}" (@intFromEnum(number)), - [arg1] "{r0}" (arg1), - [arg2] "{r1}" (arg2), - [arg3] "{r2}" (arg3), - : "memory" - ); -} - -pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { - return asm volatile ("svc #0" - : [ret] "={r0}" (-> usize), - : [number] "{r7}" (@intFromEnum(number)), - [arg1] "{r0}" (arg1), - [arg2] "{r1}" (arg2), - [arg3] "{r2}" (arg3), - [arg4] "{r3}" (arg4), - : "memory" - ); -} - -pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { - return asm volatile ("svc #0" - : [ret] "={r0}" (-> usize), - : [number] "{r7}" (@intFromEnum(number)), - [arg1] "{r0}" (arg1), - [arg2] "{r1}" (arg2), - [arg3] "{r2}" (arg3), - [arg4] "{r3}" (arg4), - [arg5] "{r4}" (arg5), - : "memory" - ); -} - -pub fn syscall6( - number: SYS, - arg1: usize, - arg2: usize, - arg3: usize, - arg4: usize, - arg5: usize, - arg6: usize, -) usize { - return asm volatile ("svc #0" - : [ret] "={r0}" (-> usize), - : [number] "{r7}" (@intFromEnum(number)), - [arg1] "{r0}" (arg1), - [arg2] "{r1}" (arg2), - [arg3] "{r2}" (arg3), - [arg4] "{r3}" (arg4), - [arg5] "{r4}" (arg5), - [arg6] "{r5}" (arg6), - : "memory" - ); -} - -pub fn clone() callconv(.Naked) usize { - // __clone(func, stack, flags, arg, ptid, tls, ctid) - // r0, r1, r2, r3, +0, +4, +8 - // - // syscall(SYS_clone, flags, stack, ptid, tls, ctid) - // r7 r0, r1, r2, r3, r4 - asm volatile ( - \\ stmfd sp!,{r4,r5,r6,r7} - \\ mov r7,#120 // SYS_clone - \\ mov r6,r3 - \\ mov r5,r0 - \\ mov r0,r2 - \\ and r1,r1,#-16 - \\ ldr r2,[sp,#16] - \\ ldr r3,[sp,#20] - \\ ldr r4,[sp,#24] - \\ svc 0 - \\ tst r0,r0 - \\ beq 1f - \\ ldmfd sp!,{r4,r5,r6,r7} - \\ bx lr - \\ - \\1: mov r0,r6 - \\ bl 3f - \\2: mov r7,#1 // SYS_exit - \\ svc 0 - \\ b 2b - \\3: bx r5 - ); -} - -pub fn restore() callconv(.Naked) noreturn { - switch (@import("builtin").zig_backend) { - .stage2_c => asm volatile ( - \\ mov r7, %[number] - \\ svc #0 - : - : [number] "I" (@intFromEnum(SYS.sigreturn)), - : "memory" - ), - else => asm volatile ( - \\ svc #0 - : - : [number] "{r7}" (@intFromEnum(SYS.sigreturn)), - : "memory" - ), - } -} - -pub fn restore_rt() callconv(.Naked) noreturn { - switch (@import("builtin").zig_backend) { - .stage2_c => asm volatile ( - \\ mov r7, %[number] - \\ svc #0 - : - : [number] "I" (@intFromEnum(SYS.rt_sigreturn)), - : "memory" - ), - else => asm volatile ( - \\ svc #0 - : - : [number] "{r7}" (@intFromEnum(SYS.rt_sigreturn)), - : "memory" - ), - } -} - -pub const MMAP2_UNIT = 4096; - -pub const F = struct { - pub const DUPFD = 0; - pub const GETFD = 1; - pub const SETFD = 2; - pub const GETFL = 3; - pub const SETFL = 4; - - pub const SETOWN = 8; - pub const GETOWN = 9; - pub const SETSIG = 10; - pub const GETSIG = 11; - - pub const GETLK = 12; - pub const SETLK = 13; - pub const SETLKW = 14; - - pub const RDLCK = 0; - pub const WRLCK = 1; - pub const UNLCK = 2; - - pub const SETOWN_EX = 15; - pub const GETOWN_EX = 16; - - pub const GETOWNER_UIDS = 17; -}; - -pub const VDSO = struct { - pub const CGT_SYM = "__vdso_clock_gettime"; - pub const CGT_VER = "LINUX_2.6"; -}; - -pub const HWCAP = struct { - pub const SWP = 1 << 0; - pub const HALF = 1 << 1; - pub const THUMB = 1 << 2; - pub const @"26BIT" = 1 << 3; - pub const FAST_MULT = 1 << 4; - pub const FPA = 1 << 5; - pub const VFP = 1 << 6; - pub const EDSP = 1 << 7; - pub const JAVA = 1 << 8; - pub const IWMMXT = 1 << 9; - pub const CRUNCH = 1 << 10; - pub const THUMBEE = 1 << 11; - pub const NEON = 1 << 12; - pub const VFPv3 = 1 << 13; - pub const VFPv3D16 = 1 << 14; - pub const TLS = 1 << 15; - pub const VFPv4 = 1 << 16; - pub const IDIVA = 1 << 17; - pub const IDIVT = 1 << 18; - pub const VFPD32 = 1 << 19; - pub const IDIV = IDIVA | IDIVT; - pub const LPAE = 1 << 20; - pub const EVTSTRM = 1 << 21; -}; - -pub const Flock = extern struct { - type: i16, - whence: i16, - __pad0: [4]u8, - start: off_t, - len: off_t, - pid: pid_t, - __unused: [4]u8, -}; - -pub const msghdr = extern struct { - name: ?*sockaddr, - namelen: socklen_t, - iov: [*]iovec, - iovlen: i32, - control: ?*anyopaque, - controllen: socklen_t, - flags: i32, -}; - -pub const msghdr_const = extern struct { - name: ?*const sockaddr, - namelen: socklen_t, - iov: [*]const iovec_const, - iovlen: i32, - control: ?*const anyopaque, - controllen: socklen_t, - flags: i32, -}; - -pub const blksize_t = i32; -pub const nlink_t = u32; -pub const time_t = isize; -pub const mode_t = u32; -pub const off_t = i64; -pub const ino_t = u64; -pub const dev_t = u64; -pub const blkcnt_t = i64; - -// The `stat` definition used by the Linux kernel. -pub const Stat = extern struct { - dev: dev_t, - __dev_padding: u32, - __ino_truncated: u32, - mode: mode_t, - nlink: nlink_t, - uid: uid_t, - gid: gid_t, - rdev: dev_t, - __rdev_padding: u32, - size: off_t, - blksize: blksize_t, - blocks: blkcnt_t, - atim: timespec, - mtim: timespec, - ctim: timespec, - ino: ino_t, - - pub fn atime(self: @This()) timespec { - return self.atim; - } - - pub fn mtime(self: @This()) timespec { - return self.mtim; - } - - pub fn ctime(self: @This()) timespec { - return self.ctim; - } -}; - -pub const timeval = extern struct { - sec: i32, - usec: i32, -}; - -pub const timezone = extern struct { - minuteswest: i32, - dsttime: i32, -}; - -pub const mcontext_t = extern struct { - trap_no: usize, - error_code: usize, - oldmask: usize, - arm_r0: usize, - arm_r1: usize, - arm_r2: usize, - arm_r3: usize, - arm_r4: usize, - arm_r5: usize, - arm_r6: usize, - arm_r7: usize, - arm_r8: usize, - arm_r9: usize, - arm_r10: usize, - arm_fp: usize, - arm_ip: usize, - arm_sp: usize, - arm_lr: usize, - arm_pc: usize, - arm_cpsr: usize, - fault_address: usize, -}; - -pub const ucontext_t = extern struct { - flags: usize, - link: ?*ucontext_t, - stack: stack_t, - mcontext: mcontext_t, - sigmask: sigset_t, - regspace: [64]u64, -}; - -/// TODO -pub const getcontext = {}; - -pub const Elf_Symndx = u32; diff --git a/lib/std/os/linux/arm.zig b/lib/std/os/linux/arm.zig new file mode 100644 index 0000000000000000000000000000000000000000..1d22b8c3dba79e1c1b83f4af2fb682a19da0a399 --- /dev/null +++ b/lib/std/os/linux/arm.zig @@ -0,0 +1,344 @@ +const std = @import("../../std.zig"); +const maxInt = std.math.maxInt; +const linux = std.os.linux; +const SYS = linux.SYS; +const iovec = std.posix.iovec; +const iovec_const = std.posix.iovec_const; +const socklen_t = linux.socklen_t; +const stack_t = linux.stack_t; +const sigset_t = linux.sigset_t; +const uid_t = linux.uid_t; +const gid_t = linux.gid_t; +const pid_t = linux.pid_t; +const sockaddr = linux.sockaddr; +const timespec = linux.timespec; + +pub fn syscall0(number: SYS) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize), + : [number] "{r7}" (@intFromEnum(number)), + : "memory" + ); +} + +pub fn syscall1(number: SYS, arg1: usize) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize), + : [number] "{r7}" (@intFromEnum(number)), + [arg1] "{r0}" (arg1), + : "memory" + ); +} + +pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize), + : [number] "{r7}" (@intFromEnum(number)), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + : "memory" + ); +} + +pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize), + : [number] "{r7}" (@intFromEnum(number)), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + [arg3] "{r2}" (arg3), + : "memory" + ); +} + +pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize), + : [number] "{r7}" (@intFromEnum(number)), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + [arg3] "{r2}" (arg3), + [arg4] "{r3}" (arg4), + : "memory" + ); +} + +pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize), + : [number] "{r7}" (@intFromEnum(number)), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + [arg3] "{r2}" (arg3), + [arg4] "{r3}" (arg4), + [arg5] "{r4}" (arg5), + : "memory" + ); +} + +pub fn syscall6( + number: SYS, + arg1: usize, + arg2: usize, + arg3: usize, + arg4: usize, + arg5: usize, + arg6: usize, +) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize), + : [number] "{r7}" (@intFromEnum(number)), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + [arg3] "{r2}" (arg3), + [arg4] "{r3}" (arg4), + [arg5] "{r4}" (arg5), + [arg6] "{r5}" (arg6), + : "memory" + ); +} + +pub fn clone() callconv(.Naked) usize { + // __clone(func, stack, flags, arg, ptid, tls, ctid) + // r0, r1, r2, r3, +0, +4, +8 + // + // syscall(SYS_clone, flags, stack, ptid, tls, ctid) + // r7 r0, r1, r2, r3, r4 + asm volatile ( + \\ stmfd sp!,{r4,r5,r6,r7} + \\ mov r7,#120 // SYS_clone + \\ mov r6,r3 + \\ mov r5,r0 + \\ mov r0,r2 + \\ and r1,r1,#-16 + \\ ldr r2,[sp,#16] + \\ ldr r3,[sp,#20] + \\ ldr r4,[sp,#24] + \\ svc 0 + \\ tst r0,r0 + \\ beq 1f + \\ ldmfd sp!,{r4,r5,r6,r7} + \\ bx lr + \\ + \\1: mov r0,r6 + \\ bl 3f + \\2: mov r7,#1 // SYS_exit + \\ svc 0 + \\ b 2b + \\3: bx r5 + ); +} + +pub fn restore() callconv(.Naked) noreturn { + switch (@import("builtin").zig_backend) { + .stage2_c => asm volatile ( + \\ mov r7, %[number] + \\ svc #0 + : + : [number] "I" (@intFromEnum(SYS.sigreturn)), + : "memory" + ), + else => asm volatile ( + \\ svc #0 + : + : [number] "{r7}" (@intFromEnum(SYS.sigreturn)), + : "memory" + ), + } +} + +pub fn restore_rt() callconv(.Naked) noreturn { + switch (@import("builtin").zig_backend) { + .stage2_c => asm volatile ( + \\ mov r7, %[number] + \\ svc #0 + : + : [number] "I" (@intFromEnum(SYS.rt_sigreturn)), + : "memory" + ), + else => asm volatile ( + \\ svc #0 + : + : [number] "{r7}" (@intFromEnum(SYS.rt_sigreturn)), + : "memory" + ), + } +} + +pub const MMAP2_UNIT = 4096; + +pub const F = struct { + pub const DUPFD = 0; + pub const GETFD = 1; + pub const SETFD = 2; + pub const GETFL = 3; + pub const SETFL = 4; + + pub const SETOWN = 8; + pub const GETOWN = 9; + pub const SETSIG = 10; + pub const GETSIG = 11; + + pub const GETLK = 12; + pub const SETLK = 13; + pub const SETLKW = 14; + + pub const RDLCK = 0; + pub const WRLCK = 1; + pub const UNLCK = 2; + + pub const SETOWN_EX = 15; + pub const GETOWN_EX = 16; + + pub const GETOWNER_UIDS = 17; +}; + +pub const VDSO = struct { + pub const CGT_SYM = "__vdso_clock_gettime"; + pub const CGT_VER = "LINUX_2.6"; +}; + +pub const HWCAP = struct { + pub const SWP = 1 << 0; + pub const HALF = 1 << 1; + pub const THUMB = 1 << 2; + pub const @"26BIT" = 1 << 3; + pub const FAST_MULT = 1 << 4; + pub const FPA = 1 << 5; + pub const VFP = 1 << 6; + pub const EDSP = 1 << 7; + pub const JAVA = 1 << 8; + pub const IWMMXT = 1 << 9; + pub const CRUNCH = 1 << 10; + pub const THUMBEE = 1 << 11; + pub const NEON = 1 << 12; + pub const VFPv3 = 1 << 13; + pub const VFPv3D16 = 1 << 14; + pub const TLS = 1 << 15; + pub const VFPv4 = 1 << 16; + pub const IDIVA = 1 << 17; + pub const IDIVT = 1 << 18; + pub const VFPD32 = 1 << 19; + pub const IDIV = IDIVA | IDIVT; + pub const LPAE = 1 << 20; + pub const EVTSTRM = 1 << 21; +}; + +pub const Flock = extern struct { + type: i16, + whence: i16, + __pad0: [4]u8, + start: off_t, + len: off_t, + pid: pid_t, + __unused: [4]u8, +}; + +pub const msghdr = extern struct { + name: ?*sockaddr, + namelen: socklen_t, + iov: [*]iovec, + iovlen: i32, + control: ?*anyopaque, + controllen: socklen_t, + flags: i32, +}; + +pub const msghdr_const = extern struct { + name: ?*const sockaddr, + namelen: socklen_t, + iov: [*]const iovec_const, + iovlen: i32, + control: ?*const anyopaque, + controllen: socklen_t, + flags: i32, +}; + +pub const blksize_t = i32; +pub const nlink_t = u32; +pub const time_t = isize; +pub const mode_t = u32; +pub const off_t = i64; +pub const ino_t = u64; +pub const dev_t = u64; +pub const blkcnt_t = i64; + +// The `stat` definition used by the Linux kernel. +pub const Stat = extern struct { + dev: dev_t, + __dev_padding: u32, + __ino_truncated: u32, + mode: mode_t, + nlink: nlink_t, + uid: uid_t, + gid: gid_t, + rdev: dev_t, + __rdev_padding: u32, + size: off_t, + blksize: blksize_t, + blocks: blkcnt_t, + atim: timespec, + mtim: timespec, + ctim: timespec, + ino: ino_t, + + pub fn atime(self: @This()) timespec { + return self.atim; + } + + pub fn mtime(self: @This()) timespec { + return self.mtim; + } + + pub fn ctime(self: @This()) timespec { + return self.ctim; + } +}; + +pub const timeval = extern struct { + sec: i32, + usec: i32, +}; + +pub const timezone = extern struct { + minuteswest: i32, + dsttime: i32, +}; + +pub const mcontext_t = extern struct { + trap_no: usize, + error_code: usize, + oldmask: usize, + arm_r0: usize, + arm_r1: usize, + arm_r2: usize, + arm_r3: usize, + arm_r4: usize, + arm_r5: usize, + arm_r6: usize, + arm_r7: usize, + arm_r8: usize, + arm_r9: usize, + arm_r10: usize, + arm_fp: usize, + arm_ip: usize, + arm_sp: usize, + arm_lr: usize, + arm_pc: usize, + arm_cpsr: usize, + fault_address: usize, +}; + +pub const ucontext_t = extern struct { + flags: usize, + link: ?*ucontext_t, + stack: stack_t, + mcontext: mcontext_t, + sigmask: sigset_t, + regspace: [64]u64, +}; + +/// TODO +pub const getcontext = {}; + +pub const Elf_Symndx = u32; diff --git a/lib/std/os/linux/arm64.zig b/lib/std/os/linux/arm64.zig deleted file mode 100644 index 9248360ae97dd2af673b8a2fca2046a3d5622eae..0000000000000000000000000000000000000000 --- a/lib/std/os/linux/arm64.zig +++ /dev/null @@ -1,288 +0,0 @@ -const std = @import("../../std.zig"); -const maxInt = std.math.maxInt; -const linux = std.os.linux; -const SYS = linux.SYS; -const socklen_t = linux.socklen_t; -const sockaddr = linux.sockaddr; -const iovec = std.posix.iovec; -const iovec_const = std.posix.iovec_const; -const uid_t = linux.uid_t; -const gid_t = linux.gid_t; -const pid_t = linux.pid_t; -const stack_t = linux.stack_t; -const sigset_t = linux.sigset_t; -const timespec = std.os.linux.timespec; - -pub fn syscall0(number: SYS) usize { - return asm volatile ("svc #0" - : [ret] "={x0}" (-> usize), - : [number] "{x8}" (@intFromEnum(number)), - : "memory", "cc" - ); -} - -pub fn syscall1(number: SYS, arg1: usize) usize { - return asm volatile ("svc #0" - : [ret] "={x0}" (-> usize), - : [number] "{x8}" (@intFromEnum(number)), - [arg1] "{x0}" (arg1), - : "memory", "cc" - ); -} - -pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize { - return asm volatile ("svc #0" - : [ret] "={x0}" (-> usize), - : [number] "{x8}" (@intFromEnum(number)), - [arg1] "{x0}" (arg1), - [arg2] "{x1}" (arg2), - : "memory", "cc" - ); -} - -pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize { - return asm volatile ("svc #0" - : [ret] "={x0}" (-> usize), - : [number] "{x8}" (@intFromEnum(number)), - [arg1] "{x0}" (arg1), - [arg2] "{x1}" (arg2), - [arg3] "{x2}" (arg3), - : "memory", "cc" - ); -} - -pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { - return asm volatile ("svc #0" - : [ret] "={x0}" (-> usize), - : [number] "{x8}" (@intFromEnum(number)), - [arg1] "{x0}" (arg1), - [arg2] "{x1}" (arg2), - [arg3] "{x2}" (arg3), - [arg4] "{x3}" (arg4), - : "memory", "cc" - ); -} - -pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { - return asm volatile ("svc #0" - : [ret] "={x0}" (-> usize), - : [number] "{x8}" (@intFromEnum(number)), - [arg1] "{x0}" (arg1), - [arg2] "{x1}" (arg2), - [arg3] "{x2}" (arg3), - [arg4] "{x3}" (arg4), - [arg5] "{x4}" (arg5), - : "memory", "cc" - ); -} - -pub fn syscall6( - number: SYS, - arg1: usize, - arg2: usize, - arg3: usize, - arg4: usize, - arg5: usize, - arg6: usize, -) usize { - return asm volatile ("svc #0" - : [ret] "={x0}" (-> usize), - : [number] "{x8}" (@intFromEnum(number)), - [arg1] "{x0}" (arg1), - [arg2] "{x1}" (arg2), - [arg3] "{x2}" (arg3), - [arg4] "{x3}" (arg4), - [arg5] "{x4}" (arg5), - [arg6] "{x5}" (arg6), - : "memory", "cc" - ); -} - -pub fn clone() callconv(.Naked) usize { - // __clone(func, stack, flags, arg, ptid, tls, ctid) - // x0, x1, w2, x3, x4, x5, x6 - // - // syscall(SYS_clone, flags, stack, ptid, tls, ctid) - // x8, x0, x1, x2, x3, x4 - asm volatile ( - \\ // align stack and save func,arg - \\ and x1,x1,#-16 - \\ stp x0,x3,[x1,#-16]! - \\ - \\ // syscall - \\ uxtw x0,w2 - \\ mov x2,x4 - \\ mov x3,x5 - \\ mov x4,x6 - \\ mov x8,#220 // SYS_clone - \\ svc #0 - \\ - \\ cbz x0,1f - \\ // parent - \\ ret - \\ // child - \\1: ldp x1,x0,[sp],#16 - \\ blr x1 - \\ mov x8,#93 // SYS_exit - \\ svc #0 - ); -} - -pub const restore = restore_rt; - -pub fn restore_rt() callconv(.Naked) noreturn { - switch (@import("builtin").zig_backend) { - .stage2_c => asm volatile ( - \\ mov x8, %[number] - \\ svc #0 - : - : [number] "i" (@intFromEnum(SYS.rt_sigreturn)), - : "memory", "cc" - ), - else => asm volatile ( - \\ svc #0 - : - : [number] "{x8}" (@intFromEnum(SYS.rt_sigreturn)), - : "memory", "cc" - ), - } -} - -pub const F = struct { - pub const DUPFD = 0; - pub const GETFD = 1; - pub const SETFD = 2; - pub const GETFL = 3; - pub const SETFL = 4; - - pub const SETOWN = 8; - pub const GETOWN = 9; - pub const SETSIG = 10; - pub const GETSIG = 11; - - pub const GETLK = 5; - pub const SETLK = 6; - pub const SETLKW = 7; - - pub const RDLCK = 0; - pub const WRLCK = 1; - pub const UNLCK = 2; - - pub const SETOWN_EX = 15; - pub const GETOWN_EX = 16; - - pub const GETOWNER_UIDS = 17; -}; - -pub const VDSO = struct { - pub const CGT_SYM = "__kernel_clock_gettime"; - pub const CGT_VER = "LINUX_2.6.39"; -}; - -pub const Flock = extern struct { - type: i16, - whence: i16, - start: off_t, - len: off_t, - pid: pid_t, - __unused: [4]u8, -}; - -pub const msghdr = extern struct { - name: ?*sockaddr, - namelen: socklen_t, - iov: [*]iovec, - iovlen: i32, - __pad1: i32 = 0, - control: ?*anyopaque, - controllen: socklen_t, - __pad2: socklen_t = 0, - flags: i32, -}; - -pub const msghdr_const = extern struct { - name: ?*const sockaddr, - namelen: socklen_t, - iov: [*]const iovec_const, - iovlen: i32, - __pad1: i32 = 0, - control: ?*const anyopaque, - controllen: socklen_t, - __pad2: socklen_t = 0, - flags: i32, -}; - -pub const blksize_t = i32; -pub const nlink_t = u32; -pub const time_t = isize; -pub const mode_t = u32; -pub const off_t = isize; -pub const ino_t = usize; -pub const dev_t = usize; -pub const blkcnt_t = isize; - -// The `stat` definition used by the Linux kernel. -pub const Stat = extern struct { - dev: dev_t, - ino: ino_t, - mode: mode_t, - nlink: nlink_t, - uid: uid_t, - gid: gid_t, - rdev: dev_t, - __pad: usize, - size: off_t, - blksize: blksize_t, - __pad2: i32, - blocks: blkcnt_t, - atim: timespec, - mtim: timespec, - ctim: timespec, - __unused: [2]u32, - - pub fn atime(self: @This()) timespec { - return self.atim; - } - - pub fn mtime(self: @This()) timespec { - return self.mtim; - } - - pub fn ctime(self: @This()) timespec { - return self.ctim; - } -}; - -pub const timeval = extern struct { - sec: isize, - usec: isize, -}; - -pub const timezone = extern struct { - minuteswest: i32, - dsttime: i32, -}; - -pub const mcontext_t = extern struct { - fault_address: usize, - regs: [31]usize, - sp: usize, - pc: usize, - pstate: usize, - // Make sure the field is correctly aligned since this area - // holds various FP/vector registers - reserved1: [256 * 16]u8 align(16), -}; - -pub const ucontext_t = extern struct { - flags: usize, - link: ?*ucontext_t, - stack: stack_t, - sigmask: sigset_t, - mcontext: mcontext_t, -}; - -/// TODO -pub const getcontext = {}; - -pub const Elf_Symndx = u32; diff --git a/lib/std/os/linux/hexagon.zig b/lib/std/os/linux/hexagon.zig new file mode 100644 index 0000000000000000000000000000000000000000..e9bf9ab57c4757daf873d3b5ec0376a0147f2d0b --- /dev/null +++ b/lib/std/os/linux/hexagon.zig @@ -0,0 +1,254 @@ +const std = @import("../../std.zig"); +const iovec = std.posix.iovec; +const iovec_const = std.posix.iovec_const; +const linux = std.os.linux; +const SYS = linux.SYS; +const uid_t = std.os.linux.uid_t; +const gid_t = std.os.linux.gid_t; +const pid_t = std.os.linux.pid_t; +const sockaddr = linux.sockaddr; +const socklen_t = linux.socklen_t; +const timespec = std.os.linux.timespec; + +pub fn syscall0(number: SYS) usize { + return asm volatile ("trap0(#1)" + : [ret] "={r0}" (-> usize), + : [number] "{r6}" (@intFromEnum(number)), + : "memory" + ); +} + +pub fn syscall1(number: SYS, arg1: usize) usize { + return asm volatile ("trap0(#1)" + : [ret] "={r0}" (-> usize), + : [number] "{r6}" (@intFromEnum(number)), + [arg1] "{r0}" (arg1), + : "memory" + ); +} + +pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize { + return asm volatile ("trap0(#1)" + : [ret] "={r0}" (-> usize), + : [number] "{r6}" (@intFromEnum(number)), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + : "memory" + ); +} + +pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize { + return asm volatile ("trap0(#1)" + : [ret] "={r0}" (-> usize), + : [number] "{r6}" (@intFromEnum(number)), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + [arg3] "{r2}" (arg3), + : "memory" + ); +} + +pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { + return asm volatile ("trap0(#1)" + : [ret] "={r0}" (-> usize), + : [number] "{r6}" (@intFromEnum(number)), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + [arg3] "{r2}" (arg3), + [arg4] "{r3}" (arg4), + : "memory" + ); +} + +pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { + return asm volatile ("trap0(#1)" + : [ret] "={r0}" (-> usize), + : [number] "{r6}" (@intFromEnum(number)), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + [arg3] "{r2}" (arg3), + [arg4] "{r3}" (arg4), + [arg5] "{r4}" (arg5), + : "memory" + ); +} + +pub fn syscall6( + number: SYS, + arg1: usize, + arg2: usize, + arg3: usize, + arg4: usize, + arg5: usize, + arg6: usize, +) usize { + return asm volatile ("trap0(#1)" + : [ret] "={r0}" (-> usize), + : [number] "{r6}" (@intFromEnum(number)), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + [arg3] "{r2}" (arg3), + [arg4] "{r3}" (arg4), + [arg5] "{r4}" (arg5), + [arg6] "{r5}" (arg6), + : "memory" + ); +} + +pub fn clone() callconv(.Naked) usize { + // __clone(func, stack, flags, arg, ptid, tls, ctid) + // r0, r1, r2, r3, r4, r5, +0 + // + // syscall(SYS_clone, flags, stack, ptid, ctid, tls) + // r6 r0, r1, r2, r3, r4 + asm volatile ( + \\ allocframe(#8) + \\ + \\ r11 = r0 + \\ r10 = r3 + \\ + \\ r6 = #220 // SYS_clone + \\ r0 = r2 + \\ r1 = and(r1, #-8) + \\ r2 = r4 + \\ r3 = memw(r30 + #8) + \\ r4 = r5 + \\ trap0(#1) + \\ + \\ p0 = cmp.eq(r0, #0) + \\ if (!p0) dealloc_return + \\ + \\ r0 = r10 + \\ callr r11 + \\ + \\ r6 = #93 // SYS_exit + \\ r0 = #0 + \\ trap0(#1) + ); +} + +pub const restore = restore_rt; + +pub fn restore_rt() callconv(.Naked) noreturn { + asm volatile ( + \\ trap0(#0) + : + : [number] "{r6}" (@intFromEnum(SYS.rt_sigreturn)), + : "memory" + ); +} + +pub const F = struct { + pub const DUPFD = 0; + pub const GETFD = 1; + pub const SETFD = 2; + pub const GETFL = 3; + pub const SETFL = 4; + pub const GETLK = 5; + pub const SETLK = 6; + pub const SETLKW = 7; + pub const SETOWN = 8; + pub const GETOWN = 9; + pub const SETSIG = 10; + pub const GETSIG = 11; + + pub const RDLCK = 0; + pub const WRLCK = 1; + pub const UNLCK = 2; + + pub const SETOWN_EX = 15; + pub const GETOWN_EX = 16; + + pub const GETOWNER_UIDS = 17; +}; + +pub const timeval = extern struct { + sec: time_t, + usec: i32, +}; + +pub const Flock = extern struct { + type: i16, + whence: i16, + start: off_t, + len: off_t, + pid: pid_t, + __unused: [4]u8, +}; + +pub const msghdr = extern struct { + name: ?*sockaddr, + namelen: socklen_t, + iov: [*]iovec, + iovlen: i32, + __pad1: i32 = 0, + control: ?*anyopaque, + controllen: socklen_t, + __pad2: socklen_t = 0, + flags: i32, +}; + +pub const msghdr_const = extern struct { + name: ?*const sockaddr, + namelen: socklen_t, + iov: [*]const iovec_const, + iovlen: i32, + __pad1: i32 = 0, + control: ?*const anyopaque, + controllen: socklen_t, + __pad2: socklen_t = 0, + flags: i32, +}; + +pub const blksize_t = i32; +pub const nlink_t = u32; +pub const time_t = i32; +pub const mode_t = u32; +pub const off_t = i64; +pub const ino_t = u64; +pub const dev_t = u64; +pub const blkcnt_t = i64; + +// The `stat` definition used by the Linux kernel. +pub const Stat = extern struct { + dev: dev_t, + ino: ino_t, + mode: mode_t, + nlink: nlink_t, + uid: uid_t, + gid: gid_t, + rdev: dev_t, + __pad: u32, + size: off_t, + blksize: blksize_t, + __pad2: i32, + blocks: blkcnt_t, + atim: timespec, + mtim: timespec, + ctim: timespec, + __unused: [2]u32, + + pub fn atime(self: @This()) timespec { + return self.atim; + } + + pub fn mtime(self: @This()) timespec { + return self.mtim; + } + + pub fn ctime(self: @This()) timespec { + return self.ctim; + } +}; + +pub const Elf_Symndx = u32; + +pub const MMAP2_UNIT = 4096; + +pub const VDSO = void; + +/// TODO +pub const ucontext_t = void; + +/// TODO +pub const getcontext = {}; diff --git a/lib/std/os/linux/pie.zig b/lib/std/os/linux/pie.zig new file mode 100644 index 0000000000000000000000000000000000000000..5099f39563b01add9a4c1f1b51919724e4ed0d71 --- /dev/null +++ b/lib/std/os/linux/pie.zig @@ -0,0 +1,304 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const elf = std.elf; +const assert = std.debug.assert; + +const R_AMD64_RELATIVE = 8; +const R_386_RELATIVE = 8; +const R_ARC_RELATIVE = 56; +const R_ARM_RELATIVE = 23; +const R_AARCH64_RELATIVE = 1027; +const R_CSKY_RELATIVE = 9; +const R_HEXAGON_RELATIVE = 35; +const R_LARCH_RELATIVE = 3; +const R_68K_RELATIVE = 22; +const R_MIPS_RELATIVE = 128; +const R_PPC_RELATIVE = 22; +const R_RISCV_RELATIVE = 3; +const R_390_RELATIVE = 12; +const R_SPARC_RELATIVE = 22; + +const R_RELATIVE = switch (builtin.cpu.arch) { + .x86 => R_386_RELATIVE, + .x86_64 => R_AMD64_RELATIVE, + .arc => R_ARC_RELATIVE, + .arm, .armeb, .thumb, .thumbeb => R_ARM_RELATIVE, + .aarch64, .aarch64_be => R_AARCH64_RELATIVE, + .csky => R_CSKY_RELATIVE, + .hexagon => R_HEXAGON_RELATIVE, + .loongarch32, .loongarch64 => R_LARCH_RELATIVE, + .m68k => R_68K_RELATIVE, + .mips, .mipsel, .mips64, .mips64el => R_MIPS_RELATIVE, + .powerpc, .powerpcle, .powerpc64, .powerpc64le => R_PPC_RELATIVE, + .riscv32, .riscv64 => R_RISCV_RELATIVE, + .s390x => R_390_RELATIVE, + .sparc, .sparc64 => R_SPARC_RELATIVE, + else => @compileError("Missing R_RELATIVE definition for this target"), +}; + +// Obtain a pointer to the _DYNAMIC array. +// We have to compute its address as a PC-relative quantity not to require a +// relocation that, at this point, is not yet applied. +inline fn getDynamicSymbol() [*]elf.Dyn { + return switch (builtin.cpu.arch) { + .x86 => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ call 1f + \\ 1: pop %[ret] + \\ lea _DYNAMIC-1b(%[ret]), %[ret] + : [ret] "=r" (-> [*]elf.Dyn), + ), + .x86_64 => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ lea _DYNAMIC(%%rip), %[ret] + : [ret] "=r" (-> [*]elf.Dyn), + ), + .arc => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ add %[ret], pcl, _DYNAMIC@pcl + : [ret] "=r" (-> [*]elf.Dyn), + ), + // Work around the limited offset range of `ldr` + .arm, .armeb, .thumb, .thumbeb => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ ldr %[ret], 1f + \\ add %[ret], pc + \\ b 2f + \\ 1: .word _DYNAMIC-1b + \\ 2: + : [ret] "=r" (-> [*]elf.Dyn), + ), + // A simple `adr` is not enough as it has a limited offset range + .aarch64, .aarch64_be => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ adrp %[ret], _DYNAMIC + \\ add %[ret], %[ret], #:lo12:_DYNAMIC + : [ret] "=r" (-> [*]elf.Dyn), + ), + // The CSKY ABI requires the gb register to point to the GOT. Additionally, the first + // entry in the GOT is defined to hold the address of _DYNAMIC. + .csky => asm volatile ( + \\ mov %[ret], gb + \\ ldw %[ret], %[ret] + : [ret] "=r" (-> [*]elf.Dyn), + ), + .hexagon => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ jump 1f + \\ .word _DYNAMIC - . + \\ 1: + \\ r1 = pc + \\ r1 = add(r1, #-4) + \\ %[ret] = memw(r1) + \\ %[ret] = add(r1, %[ret]) + : [ret] "=r" (-> [*]elf.Dyn), + : + : "r1" + ), + .loongarch32, .loongarch64 => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ la.local %[ret], _DYNAMIC + : [ret] "=r" (-> [*]elf.Dyn), + ), + // Note that the - 8 is needed because pc in the second lea instruction points into the + // middle of that instruction. (The first lea is 6 bytes, the second is 4 bytes.) + .m68k => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ lea _DYNAMIC - . - 8, %[ret] + \\ lea (%[ret], %%pc), %[ret] + : [ret] "=r" (-> [*]elf.Dyn), + ), + .mips, .mipsel => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ bal 1f + \\ .gpword _DYNAMIC + \\ 1: + \\ lw %[ret], 0($ra) + \\ addu %[ret], %[ret], $gp + : [ret] "=r" (-> [*]elf.Dyn), + : + : "lr" + ), + .mips64, .mips64el => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ .balign 8 + \\ bal 1f + \\ .gpdword _DYNAMIC + \\ 1: + \\ ld %[ret], 0($ra) + \\ daddu %[ret], %[ret], $gp + : [ret] "=r" (-> [*]elf.Dyn), + : + : "lr" + ), + .powerpc, .powerpcle => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ bl 1f + \\ .long _DYNAMIC - . + \\ 1: + \\ mflr %[ret] + \\ lwz 4, 0(%[ret]) + \\ add %[ret], 4, %[ret] + : [ret] "=r" (-> [*]elf.Dyn), + : + : "lr", "r4" + ), + .powerpc64, .powerpc64le => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ bl 1f + \\ .quad _DYNAMIC - . + \\ 1: + \\ mflr %[ret] + \\ ld 4, 0(%[ret]) + \\ add %[ret], 4, %[ret] + : [ret] "=r" (-> [*]elf.Dyn), + : + : "lr", "r4" + ), + .riscv32, .riscv64 => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ lla %[ret], _DYNAMIC + : [ret] "=r" (-> [*]elf.Dyn), + ), + .s390x => asm volatile ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + \\ larl %[ret], 1f + \\ ag %[ret], 0(%[ret]) + \\ b 2f + \\ 1: .quad _DYNAMIC - . + \\ 2: + : [ret] "=r" (-> [*]elf.Dyn), + ), + // The compiler does not necessarily have any obligation to load the `l7` register (pointing + // to the GOT), so do it ourselves just in case. + .sparc, .sparc64 => asm volatile ( + \\ sethi %%hi(_GLOBAL_OFFSET_TABLE_ - 4), %%l7 + \\ call 1f + \\ add %%l7, %%lo(_GLOBAL_OFFSET_TABLE_ + 4), %%l7 + \\ 1: + \\ add %%l7, %%o7, %[ret] + : [ret] "=r" (-> [*]elf.Dyn), + ), + else => { + @compileError("PIE startup is not yet supported for this target!"); + }, + }; +} + +pub fn relocate(phdrs: []elf.Phdr) void { + @setRuntimeSafety(false); + @disableInstrumentation(); + + const dynv = getDynamicSymbol(); + + // Recover the delta applied by the loader by comparing the effective and + // the theoretical load addresses for the `_DYNAMIC` symbol. + const base_addr = base: { + for (phdrs) |*phdr| { + if (phdr.p_type != elf.PT_DYNAMIC) continue; + break :base @intFromPtr(dynv) - phdr.p_vaddr; + } + // This is not supposed to happen for well-formed binaries. + @trap(); + }; + + var sorted_dynv: [elf.DT_NUM]elf.Addr = undefined; + + // Zero-initialized this way to prevent the compiler from turning this into + // `memcpy` or `memset` calls (which can require relocations). + for (&sorted_dynv) |*dyn| { + const pdyn: *volatile elf.Addr = @ptrCast(dyn); + pdyn.* = 0; + } + + { + // `dynv` has no defined order. Fix that. + var i: usize = 0; + while (dynv[i].d_tag != elf.DT_NULL) : (i += 1) { + if (dynv[i].d_tag < elf.DT_NUM) sorted_dynv[@bitCast(dynv[i].d_tag)] = dynv[i].d_val; + } + } + + // Deal with the GOT relocations that MIPS uses first. + if (builtin.cpu.arch.isMIPS()) { + const count: elf.Addr = blk: { + // This is an architecture-specific tag, so not part of `sorted_dynv`. + var i: usize = 0; + while (dynv[i].d_tag != elf.DT_NULL) : (i += 1) { + if (dynv[i].d_tag == elf.DT_MIPS_LOCAL_GOTNO) break :blk dynv[i].d_val; + } + + break :blk 0; + }; + + const got: [*]usize = @ptrFromInt(base_addr + sorted_dynv[elf.DT_PLTGOT]); + + for (0..count) |i| { + got[i] += base_addr; + } + } + + // Apply normal relocations. + + const rel = sorted_dynv[elf.DT_REL]; + if (rel != 0) { + const rels = @call(.always_inline, std.mem.bytesAsSlice, .{ + elf.Rel, + @as([*]u8, @ptrFromInt(base_addr + rel))[0..sorted_dynv[elf.DT_RELSZ]], + }); + for (rels) |r| { + if (r.r_type() != R_RELATIVE) continue; + @as(*usize, @ptrFromInt(base_addr + r.r_offset)).* += base_addr; + } + } + + const rela = sorted_dynv[elf.DT_RELA]; + if (rela != 0) { + const relas = @call(.always_inline, std.mem.bytesAsSlice, .{ + elf.Rela, + @as([*]u8, @ptrFromInt(base_addr + rela))[0..sorted_dynv[elf.DT_RELASZ]], + }); + for (relas) |r| { + if (r.r_type() != R_RELATIVE) continue; + @as(*usize, @ptrFromInt(base_addr + r.r_offset)).* = base_addr + @as(usize, @bitCast(r.r_addend)); + } + } + + const relr = sorted_dynv[elf.DT_RELR]; + if (relr != 0) { + const relrs = @call(.always_inline, std.mem.bytesAsSlice, .{ + elf.Relr, + @as([*]u8, @ptrFromInt(base_addr + relr))[0..sorted_dynv[elf.DT_RELRSZ]], + }); + var current: [*]usize = undefined; + for (relrs) |r| { + if ((r & 1) == 0) { + current = @ptrFromInt(base_addr + r); + current[0] += base_addr; + current += 1; + } else { + // Skip the first bit; there are 63 locations in the bitmap. + var i: if (@sizeOf(usize) == 8) u6 else u5 = 1; + while (i < @bitSizeOf(elf.Relr)) : (i += 1) { + if (((r >> i) & 1) != 0) current[i] += base_addr; + } + + current += @bitSizeOf(elf.Relr) - 1; + } + } + } +} diff --git a/lib/std/os/linux/start_pie.zig b/lib/std/os/linux/start_pie.zig deleted file mode 100644 index 5099f39563b01add9a4c1f1b51919724e4ed0d71..0000000000000000000000000000000000000000 --- a/lib/std/os/linux/start_pie.zig +++ /dev/null @@ -1,304 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const elf = std.elf; -const assert = std.debug.assert; - -const R_AMD64_RELATIVE = 8; -const R_386_RELATIVE = 8; -const R_ARC_RELATIVE = 56; -const R_ARM_RELATIVE = 23; -const R_AARCH64_RELATIVE = 1027; -const R_CSKY_RELATIVE = 9; -const R_HEXAGON_RELATIVE = 35; -const R_LARCH_RELATIVE = 3; -const R_68K_RELATIVE = 22; -const R_MIPS_RELATIVE = 128; -const R_PPC_RELATIVE = 22; -const R_RISCV_RELATIVE = 3; -const R_390_RELATIVE = 12; -const R_SPARC_RELATIVE = 22; - -const R_RELATIVE = switch (builtin.cpu.arch) { - .x86 => R_386_RELATIVE, - .x86_64 => R_AMD64_RELATIVE, - .arc => R_ARC_RELATIVE, - .arm, .armeb, .thumb, .thumbeb => R_ARM_RELATIVE, - .aarch64, .aarch64_be => R_AARCH64_RELATIVE, - .csky => R_CSKY_RELATIVE, - .hexagon => R_HEXAGON_RELATIVE, - .loongarch32, .loongarch64 => R_LARCH_RELATIVE, - .m68k => R_68K_RELATIVE, - .mips, .mipsel, .mips64, .mips64el => R_MIPS_RELATIVE, - .powerpc, .powerpcle, .powerpc64, .powerpc64le => R_PPC_RELATIVE, - .riscv32, .riscv64 => R_RISCV_RELATIVE, - .s390x => R_390_RELATIVE, - .sparc, .sparc64 => R_SPARC_RELATIVE, - else => @compileError("Missing R_RELATIVE definition for this target"), -}; - -// Obtain a pointer to the _DYNAMIC array. -// We have to compute its address as a PC-relative quantity not to require a -// relocation that, at this point, is not yet applied. -inline fn getDynamicSymbol() [*]elf.Dyn { - return switch (builtin.cpu.arch) { - .x86 => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ call 1f - \\ 1: pop %[ret] - \\ lea _DYNAMIC-1b(%[ret]), %[ret] - : [ret] "=r" (-> [*]elf.Dyn), - ), - .x86_64 => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ lea _DYNAMIC(%%rip), %[ret] - : [ret] "=r" (-> [*]elf.Dyn), - ), - .arc => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ add %[ret], pcl, _DYNAMIC@pcl - : [ret] "=r" (-> [*]elf.Dyn), - ), - // Work around the limited offset range of `ldr` - .arm, .armeb, .thumb, .thumbeb => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ ldr %[ret], 1f - \\ add %[ret], pc - \\ b 2f - \\ 1: .word _DYNAMIC-1b - \\ 2: - : [ret] "=r" (-> [*]elf.Dyn), - ), - // A simple `adr` is not enough as it has a limited offset range - .aarch64, .aarch64_be => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ adrp %[ret], _DYNAMIC - \\ add %[ret], %[ret], #:lo12:_DYNAMIC - : [ret] "=r" (-> [*]elf.Dyn), - ), - // The CSKY ABI requires the gb register to point to the GOT. Additionally, the first - // entry in the GOT is defined to hold the address of _DYNAMIC. - .csky => asm volatile ( - \\ mov %[ret], gb - \\ ldw %[ret], %[ret] - : [ret] "=r" (-> [*]elf.Dyn), - ), - .hexagon => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ jump 1f - \\ .word _DYNAMIC - . - \\ 1: - \\ r1 = pc - \\ r1 = add(r1, #-4) - \\ %[ret] = memw(r1) - \\ %[ret] = add(r1, %[ret]) - : [ret] "=r" (-> [*]elf.Dyn), - : - : "r1" - ), - .loongarch32, .loongarch64 => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ la.local %[ret], _DYNAMIC - : [ret] "=r" (-> [*]elf.Dyn), - ), - // Note that the - 8 is needed because pc in the second lea instruction points into the - // middle of that instruction. (The first lea is 6 bytes, the second is 4 bytes.) - .m68k => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ lea _DYNAMIC - . - 8, %[ret] - \\ lea (%[ret], %%pc), %[ret] - : [ret] "=r" (-> [*]elf.Dyn), - ), - .mips, .mipsel => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ bal 1f - \\ .gpword _DYNAMIC - \\ 1: - \\ lw %[ret], 0($ra) - \\ addu %[ret], %[ret], $gp - : [ret] "=r" (-> [*]elf.Dyn), - : - : "lr" - ), - .mips64, .mips64el => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ .balign 8 - \\ bal 1f - \\ .gpdword _DYNAMIC - \\ 1: - \\ ld %[ret], 0($ra) - \\ daddu %[ret], %[ret], $gp - : [ret] "=r" (-> [*]elf.Dyn), - : - : "lr" - ), - .powerpc, .powerpcle => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ bl 1f - \\ .long _DYNAMIC - . - \\ 1: - \\ mflr %[ret] - \\ lwz 4, 0(%[ret]) - \\ add %[ret], 4, %[ret] - : [ret] "=r" (-> [*]elf.Dyn), - : - : "lr", "r4" - ), - .powerpc64, .powerpc64le => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ bl 1f - \\ .quad _DYNAMIC - . - \\ 1: - \\ mflr %[ret] - \\ ld 4, 0(%[ret]) - \\ add %[ret], 4, %[ret] - : [ret] "=r" (-> [*]elf.Dyn), - : - : "lr", "r4" - ), - .riscv32, .riscv64 => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ lla %[ret], _DYNAMIC - : [ret] "=r" (-> [*]elf.Dyn), - ), - .s390x => asm volatile ( - \\ .weak _DYNAMIC - \\ .hidden _DYNAMIC - \\ larl %[ret], 1f - \\ ag %[ret], 0(%[ret]) - \\ b 2f - \\ 1: .quad _DYNAMIC - . - \\ 2: - : [ret] "=r" (-> [*]elf.Dyn), - ), - // The compiler does not necessarily have any obligation to load the `l7` register (pointing - // to the GOT), so do it ourselves just in case. - .sparc, .sparc64 => asm volatile ( - \\ sethi %%hi(_GLOBAL_OFFSET_TABLE_ - 4), %%l7 - \\ call 1f - \\ add %%l7, %%lo(_GLOBAL_OFFSET_TABLE_ + 4), %%l7 - \\ 1: - \\ add %%l7, %%o7, %[ret] - : [ret] "=r" (-> [*]elf.Dyn), - ), - else => { - @compileError("PIE startup is not yet supported for this target!"); - }, - }; -} - -pub fn relocate(phdrs: []elf.Phdr) void { - @setRuntimeSafety(false); - @disableInstrumentation(); - - const dynv = getDynamicSymbol(); - - // Recover the delta applied by the loader by comparing the effective and - // the theoretical load addresses for the `_DYNAMIC` symbol. - const base_addr = base: { - for (phdrs) |*phdr| { - if (phdr.p_type != elf.PT_DYNAMIC) continue; - break :base @intFromPtr(dynv) - phdr.p_vaddr; - } - // This is not supposed to happen for well-formed binaries. - @trap(); - }; - - var sorted_dynv: [elf.DT_NUM]elf.Addr = undefined; - - // Zero-initialized this way to prevent the compiler from turning this into - // `memcpy` or `memset` calls (which can require relocations). - for (&sorted_dynv) |*dyn| { - const pdyn: *volatile elf.Addr = @ptrCast(dyn); - pdyn.* = 0; - } - - { - // `dynv` has no defined order. Fix that. - var i: usize = 0; - while (dynv[i].d_tag != elf.DT_NULL) : (i += 1) { - if (dynv[i].d_tag < elf.DT_NUM) sorted_dynv[@bitCast(dynv[i].d_tag)] = dynv[i].d_val; - } - } - - // Deal with the GOT relocations that MIPS uses first. - if (builtin.cpu.arch.isMIPS()) { - const count: elf.Addr = blk: { - // This is an architecture-specific tag, so not part of `sorted_dynv`. - var i: usize = 0; - while (dynv[i].d_tag != elf.DT_NULL) : (i += 1) { - if (dynv[i].d_tag == elf.DT_MIPS_LOCAL_GOTNO) break :blk dynv[i].d_val; - } - - break :blk 0; - }; - - const got: [*]usize = @ptrFromInt(base_addr + sorted_dynv[elf.DT_PLTGOT]); - - for (0..count) |i| { - got[i] += base_addr; - } - } - - // Apply normal relocations. - - const rel = sorted_dynv[elf.DT_REL]; - if (rel != 0) { - const rels = @call(.always_inline, std.mem.bytesAsSlice, .{ - elf.Rel, - @as([*]u8, @ptrFromInt(base_addr + rel))[0..sorted_dynv[elf.DT_RELSZ]], - }); - for (rels) |r| { - if (r.r_type() != R_RELATIVE) continue; - @as(*usize, @ptrFromInt(base_addr + r.r_offset)).* += base_addr; - } - } - - const rela = sorted_dynv[elf.DT_RELA]; - if (rela != 0) { - const relas = @call(.always_inline, std.mem.bytesAsSlice, .{ - elf.Rela, - @as([*]u8, @ptrFromInt(base_addr + rela))[0..sorted_dynv[elf.DT_RELASZ]], - }); - for (relas) |r| { - if (r.r_type() != R_RELATIVE) continue; - @as(*usize, @ptrFromInt(base_addr + r.r_offset)).* = base_addr + @as(usize, @bitCast(r.r_addend)); - } - } - - const relr = sorted_dynv[elf.DT_RELR]; - if (relr != 0) { - const relrs = @call(.always_inline, std.mem.bytesAsSlice, .{ - elf.Relr, - @as([*]u8, @ptrFromInt(base_addr + relr))[0..sorted_dynv[elf.DT_RELRSZ]], - }); - var current: [*]usize = undefined; - for (relrs) |r| { - if ((r & 1) == 0) { - current = @ptrFromInt(base_addr + r); - current[0] += base_addr; - current += 1; - } else { - // Skip the first bit; there are 63 locations in the bitmap. - var i: if (@sizeOf(usize) == 8) u6 else u5 = 1; - while (i < @bitSizeOf(elf.Relr)) : (i += 1) { - if (((r >> i) & 1) != 0) current[i] += base_addr; - } - - current += @bitSizeOf(elf.Relr) - 1; - } - } - } -} diff --git a/lib/std/os/linux/syscalls.zig b/lib/std/os/linux/syscalls.zig index d08a77b47c5587959ceee09b4c4d8e54ab7c884a..ef04387ea62d8e6ba87c0ad25d10fa8ae99003c7 100644 --- a/lib/std/os/linux/syscalls.zig +++ b/lib/std/os/linux/syscalls.zig @@ -6852,7 +6852,7 @@ pub const Arc = enum(usize) { keyctl = 219, clone = 220, execve = 221, - mmap_pgoff = 222, + mmap2 = 222, fadvise64_64 = 223, swapon = 224, swapoff = 225, @@ -7538,7 +7538,7 @@ pub const Hexagon = enum(usize) { keyctl = 219, clone = 220, execve = 221, - mmap_pgoff = 222, + mmap2 = 222, fadvise64_64 = 223, swapon = 224, swapoff = 225, diff --git a/lib/std/os/linux/thumb.zig b/lib/std/os/linux/thumb.zig index baaf130578d9205b540aea12d75f490aedeba9e1..a464030858b2ed2366d32c3b6d4e9092d0bfb138 100644 --- a/lib/std/os/linux/thumb.zig +++ b/lib/std/os/linux/thumb.zig @@ -141,7 +141,7 @@ pub fn syscall6( ); } -pub const clone = @import("arm-eabi.zig").clone; +pub const clone = @import("arm.zig").clone; pub fn restore() callconv(.Naked) noreturn { asm volatile ( diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index bf12cc28c12f3535ded008a13f99895f7a8c3cd7..5feb08ab28a8cfa223f9997236b2cba3b4e3dcf9 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -386,6 +386,16 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { query.cpu_features_sub, ); + if (cpu_arch == .hexagon) { + // Both LLVM and LLD have broken support for the small data area. Yet LLVM has the feature + // on by default for all Hexagon CPUs. Clang sort of solves this by defaulting the `-gpsize` + // command line parameter for the Hexagon backend to 0, so that no constants get placed in + // the SDA. (This of course breaks down if the user passes `-G ` to Clang...) We can't do + // the `-gpsize` hack because we can have multiple concurrent LLVM emit jobs, and command + // line options in LLVM are shared globally. So just force this feature off. Lovely stuff. + result.cpu.features.removeFeature(@intFromEnum(Target.hexagon.Feature.small_data)); + } + // https://github.com/llvm/llvm-project/issues/105978 if (result.cpu.arch.isArmOrThumb() and result.floatAbi() == .soft) { result.cpu.features.removeFeature(@intFromEnum(Target.arm.Feature.vfp2)); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 119097523884078da41d5e290eb6d14a165aa908..1201c41486a46fcb34b01c375a8b8b1cf03b682b 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -12444,6 +12444,7 @@ fn backendSupportsF80(target: std.Target) bool { /// if it produces miscompilations. fn backendSupportsF16(target: std.Target) bool { return switch (target.cpu.arch) { + .hexagon, .powerpc, .powerpcle, .powerpc64, diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 00ea5a778d87bd8734be6279325e6344087e127e..a0ec37668e3866f58c48b28f41504a6d6c20fa12 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -189,7 +189,7 @@ pub fn createEmpty( }; const page_size: u32 = switch (target.cpu.arch) { - .aarch64, .powerpc64le => 0x10000, + .aarch64, .hexagon, .powerpc64le => 0x10000, .sparc64 => 0x2000, else => 0x1000, }; diff --git a/tools/generate_linux_syscalls.zig b/tools/generate_linux_syscalls.zig index f11633491e9bcec1c7c058a76ba096a2ccf575cf..df1b5127dfb8735082b6dc58c04aa342e59b5a23 100644 --- a/tools/generate_linux_syscalls.zig +++ b/tools/generate_linux_syscalls.zig @@ -22,6 +22,8 @@ const stdlib_renames = std.StaticStringMap([]const u8).initComptime(.{ // ARM EABI/Thumb. .{ "arm_sync_file_range", "sync_file_range" }, .{ "arm_fadvise64_64", "fadvise64_64" }, + // ARC and Hexagon. + .{ "mmap_pgoff", "mmap2" }, }); // Only for newer architectures where we use the C preprocessor.