diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 037c7efab5c996..3f67d536f16475 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,13 @@ jobs: build_options: "LLVM=1 CROSS_COMPILE=x86_64-unknown-freebsd SYSROOT=~/freebsd-sysroot" make_sysroot: "./tools/lkl/scripts/freebsd-make-sysroot.sh" run_qemu: true + - displayTargetName: win64 + os: unix + runs_on: ubuntu-24.04 + pip_option: --break-system-packages + shell: bash + build_options: "CROSS_COMPILE=x86_64-w64-mingw32-" + make_sysroot: "./tools/lkl/scripts/win64-toolchain.sh" - displayTargetName: fuzzers os: unix runs_on: ubuntu-22.04 @@ -123,6 +130,15 @@ jobs: qemu-utils sshpass cloud-image-utils binutils cmake ninja-build liblzma-dev libz-dev \ pkg-config autoconf libtool + - name: Install wine + if: matrix.displayTargetName == 'win64' + run: | + sudo apt install -y wine wine64 + echo "WINEDEBUG=-all" >> $GITHUB_ENV + # skip the Mono and Gecko installers, they hang without a display + echo "WINEDLLOVERRIDES=mscoree=;mshtml=" >> $GITHUB_ENV + WINEDEBUG=-all WINEDLLOVERRIDES="mscoree=;mshtml=" wineboot -i + - name: Install patched binutils for Windows if: runner.os == 'Windows' run: | diff --git a/arch/lkl/include/uapi/asm/lkl_long.h b/arch/lkl/include/uapi/asm/lkl_long.h new file mode 100644 index 00000000000000..91adf0451e38e8 --- /dev/null +++ b/arch/lkl/include/uapi/asm/lkl_long.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _ASM_UAPI_LKL_LONG_H +#define _ASM_UAPI_LKL_LONG_H + +/* + * lkl_long_t / lkl_ulong_t: pointer-width integer types for the + * LKL cross-world interface (host_ops, syscall dispatch, UAPI structs). + * + * These must be the same size on both sides of the kernel<->host boundary: + * - Kernel side: long = 8 bytes (on Windows the kernel is built with an LP64 + * x86_64-pc-cygwin compiler, see tools/lkl/bin/x86_64-w64-mingw32-gcc) + * - Host side (LLP64 MinGW-w64): long = 4 bytes, need long long + * - Host side (LP64 Linux/Cygwin/macOS): long = 8 bytes + * + * The headers_install.py script replaces all 'long' in generated user + * headers with these types to ensure ABI compatibility across data models. + */ +#if defined(_WIN64) && !defined(__LP64__) +/* LLP64: MinGW-w64 x64 user-space */ +typedef long long lkl_long_t; +typedef unsigned long long lkl_ulong_t; +#else +/* LP64: kernel side, Linux, Cygwin, macOS, or any ILP32 system */ +typedef long lkl_long_t; +typedef unsigned long lkl_ulong_t; +#endif + +#endif /* _ASM_UAPI_LKL_LONG_H */ diff --git a/arch/lkl/scripts/headers_install.py b/arch/lkl/scripts/headers_install.py index 7d3a889bfa2d5f..0075585edf91f1 100755 --- a/arch/lkl/scripts/headers_install.py +++ b/arch/lkl/scripts/headers_install.py @@ -107,6 +107,7 @@ def lkl_prefix(self, w): def install_headers(self): self.find_headers("arch/lkl/include/uapi/asm/syscalls.h") self.headers.add("arch/lkl/include/uapi/asm/host_ops.h") + self.headers.add("arch/lkl/include/uapi/asm/lkl_long.h") self.find_headers("include/uapi/linux/android/binder.h") self.find_headers("include/uapi/linux/uhid.h") self.find_headers("include/uapi/linux/mman.h") @@ -166,6 +167,37 @@ def find_all_symbols(self): # needed for i386 self.defines.add("__NR_stime") + + def replace_long_types(self, content, h): + """Replace 'long' and 'unsigned long' with lkl_long_t/lkl_ulong_t + for LLP64 compatibility, preserving 'long long' and 'long double'.""" + # Skip lkl_long.h itself + if 'lkl_long.h' in h: + return content + # Step 1: protect 'long long' and 'long double' with placeholders + content = re.sub(r'\blong\s+long\b', '__LKLPH_LONGLONG__', content) + content = re.sub(r'\blong\s+double\b', '__LKLPH_LONGDOUBLE__', content) + # Step 2: replace 'unsigned long [int]' (now safe, no 'long long' present) + content = re.sub(r'\bunsigned\s+long(?:\s+int)?\b', 'lkl_ulong_t', content) + # Step 3: replace remaining 'long [int]' + content = re.sub(r'\blong(?:\s+int)?\b', 'lkl_long_t', content) + # Step 4: restore placeholders + content = content.replace('__LKLPH_LONGLONG__', 'long long') + content = content.replace('__LKLPH_LONGDOUBLE__', 'long double') + # Step 5: add include for lkl_long_t definition if replacements were made + if 'lkl_long_t' in content or 'lkl_ulong_t' in content: + # Insert after the first #ifndef/#define guard or at the top + include_line = '#include \n' + if include_line not in content: + # Insert after the header guard #define + m = re.search(r'(#ifndef\s+\w+\s*\n#define\s+\w+\s*\n)', content) + if m: + pos = m.end() + content = content[:pos] + '\n' + include_line + '\n' + content[pos:] + else: + content = include_line + content + return content + def update_header(self, h): # h is a .raw tmp file produced by install_headers(); the final # destination is h without the .raw suffix. @@ -192,6 +224,8 @@ def update_header(self, h): search_str = r"(\W?union\s+)" + s + r"(\W)" replace_str = "\\1" + self.lkl_prefix(s) + "\\2" content = re.sub(search_str, replace_str, content, flags = re.MULTILINE) + # Replace long/unsigned long with lkl_long_t/lkl_ulong_t + content = self.replace_long_types(content, h) content = content.encode() existing = None if os.path.exists(dst) and os.stat(dst).st_size == len(content): diff --git a/tools/lkl/bin/x86_64-w64-mingw32-cc b/tools/lkl/bin/x86_64-w64-mingw32-cc new file mode 120000 index 00000000000000..9113d989a69fe1 --- /dev/null +++ b/tools/lkl/bin/x86_64-w64-mingw32-cc @@ -0,0 +1 @@ +../scripts/win64-cc.sh \ No newline at end of file diff --git a/tools/lkl/bin/x86_64-w64-mingw32-gcc b/tools/lkl/bin/x86_64-w64-mingw32-gcc new file mode 120000 index 00000000000000..9113d989a69fe1 --- /dev/null +++ b/tools/lkl/bin/x86_64-w64-mingw32-gcc @@ -0,0 +1 @@ +../scripts/win64-cc.sh \ No newline at end of file diff --git a/tools/lkl/include/lkl.h b/tools/lkl/include/lkl.h index eaf6c4ceebc929..3929847f7d613e 100644 --- a/tools/lkl/include/lkl.h +++ b/tools/lkl/include/lkl.h @@ -21,6 +21,7 @@ extern "C" { #undef __unused #include +#include #pragma pop_macro("__unused") @@ -67,7 +68,7 @@ static inline int lkl_sys_fstatfs(unsigned int fd, struct lkl_statfs *buf) static inline int lkl_sys_nanosleep(struct __lkl__kernel_timespec *rqtp, struct __lkl__kernel_timespec *rmtp) { - long p[6] = {LKL_CLOCK_MONOTONIC, 0, (long)rqtp, (long)rmtp, 0}; + lkl_long_t p[6] = {LKL_CLOCK_MONOTONIC, 0, (lkl_long_t)rqtp, (lkl_long_t)rmtp, 0}; return lkl_syscall(__lkl__NR_clock_nanosleep_time64, p); } @@ -93,7 +94,7 @@ static inline long long lkl_sys_lseek(unsigned int fd, __lkl__kernel_loff_t off, unsigned int whence) { long long res; - long ret = lkl_sys_llseek(fd, off >> 32, off & 0xffffffff, &res, whence); + lkl_long_t ret = lkl_sys_llseek(fd, off >> 32, off & 0xffffffff, &res, whence); return ret < 0 ? ret : res; } @@ -102,7 +103,7 @@ static inline long long lkl_sys_lseek(unsigned int fd, __lkl__kernel_loff_t off, static inline void *lkl_sys_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) { - return (void *)lkl_sys_mmap_pgoff((long)addr, length, prot, flags, fd, + return (void *)lkl_sys_mmap_pgoff((lkl_long_t)addr, length, prot, flags, fd, offset >> 12); } @@ -112,7 +113,7 @@ static inline void *lkl_sys_mmap(void *addr, size_t length, int prot, int flags, /** * lkl_sys_open - wrapper for lkl_sys_openat */ -static inline long lkl_sys_open(const char *file, int flags, int mode) +static inline lkl_long_t lkl_sys_open(const char *file, int flags, int mode) { return lkl_sys_openat(LKL_AT_FDCWD, file, flags, mode); } @@ -120,7 +121,7 @@ static inline long lkl_sys_open(const char *file, int flags, int mode) /** * lkl_sys_creat - wrapper for lkl_sys_openat */ -static inline long lkl_sys_creat(const char *file, int mode) +static inline lkl_long_t lkl_sys_creat(const char *file, int mode) { return lkl_sys_openat(LKL_AT_FDCWD, file, LKL_O_CREAT|LKL_O_WRONLY|LKL_O_TRUNC, mode); @@ -132,7 +133,7 @@ static inline long lkl_sys_creat(const char *file, int mode) /** * lkl_sys_access - wrapper for lkl_sys_faccessat */ -static inline long lkl_sys_access(const char *file, int mode) +static inline lkl_long_t lkl_sys_access(const char *file, int mode) { return lkl_sys_faccessat(LKL_AT_FDCWD, file, mode); } @@ -142,7 +143,7 @@ static inline long lkl_sys_access(const char *file, int mode) /** * lkl_sys_chown - wrapper for lkl_sys_fchownat */ -static inline long lkl_sys_chown(const char *path, lkl_uid_t uid, lkl_gid_t gid) +static inline lkl_long_t lkl_sys_chown(const char *path, lkl_uid_t uid, lkl_gid_t gid) { return lkl_sys_fchownat(LKL_AT_FDCWD, path, uid, gid, 0); } @@ -152,7 +153,7 @@ static inline long lkl_sys_chown(const char *path, lkl_uid_t uid, lkl_gid_t gid) /** * lkl_sys_chmod - wrapper for lkl_sys_fchmodat */ -static inline long lkl_sys_chmod(const char *path, mode_t mode) +static inline lkl_long_t lkl_sys_chmod(const char *path, mode_t mode) { return lkl_sys_fchmodat(LKL_AT_FDCWD, path, mode); } @@ -162,7 +163,7 @@ static inline long lkl_sys_chmod(const char *path, mode_t mode) /** * lkl_sys_link - wrapper for lkl_sys_linkat */ -static inline long lkl_sys_link(const char *existing, const char *new) +static inline lkl_long_t lkl_sys_link(const char *existing, const char *new) { return lkl_sys_linkat(LKL_AT_FDCWD, existing, LKL_AT_FDCWD, new, 0); } @@ -172,7 +173,7 @@ static inline long lkl_sys_link(const char *existing, const char *new) /** * lkl_sys_unlink - wrapper for lkl_sys_unlinkat */ -static inline long lkl_sys_unlink(const char *path) +static inline lkl_long_t lkl_sys_unlink(const char *path) { return lkl_sys_unlinkat(LKL_AT_FDCWD, path, 0); } @@ -182,7 +183,7 @@ static inline long lkl_sys_unlink(const char *path) /** * lkl_sys_symlink - wrapper for lkl_sys_symlinkat */ -static inline long lkl_sys_symlink(const char *existing, const char *new) +static inline lkl_long_t lkl_sys_symlink(const char *existing, const char *new) { return lkl_sys_symlinkat(existing, LKL_AT_FDCWD, new); } @@ -192,7 +193,7 @@ static inline long lkl_sys_symlink(const char *existing, const char *new) /** * lkl_sys_readlink - wrapper for lkl_sys_readlinkat */ -static inline long lkl_sys_readlink(const char *path, char *buf, size_t bufsize) +static inline lkl_long_t lkl_sys_readlink(const char *path, char *buf, size_t bufsize) { return lkl_sys_readlinkat(LKL_AT_FDCWD, path, buf, bufsize); } @@ -202,7 +203,7 @@ static inline long lkl_sys_readlink(const char *path, char *buf, size_t bufsize) /** * lkl_sys_rename - wrapper for lkl_sys_renameat */ -static inline long lkl_sys_rename(const char *old, const char *new) +static inline lkl_long_t lkl_sys_rename(const char *old, const char *new) { return lkl_sys_renameat(LKL_AT_FDCWD, old, LKL_AT_FDCWD, new); } @@ -212,7 +213,7 @@ static inline long lkl_sys_rename(const char *old, const char *new) /** * lkl_sys_mkdir - wrapper for lkl_sys_mkdirat */ -static inline long lkl_sys_mkdir(const char *path, mode_t mode) +static inline lkl_long_t lkl_sys_mkdir(const char *path, mode_t mode) { return lkl_sys_mkdirat(LKL_AT_FDCWD, path, mode); } @@ -222,7 +223,7 @@ static inline long lkl_sys_mkdir(const char *path, mode_t mode) /** * lkl_sys_rmdir - wrapper for lkl_sys_unlinkrat */ -static inline long lkl_sys_rmdir(const char *path) +static inline lkl_long_t lkl_sys_rmdir(const char *path) { return lkl_sys_unlinkat(LKL_AT_FDCWD, path, LKL_AT_REMOVEDIR); } @@ -232,7 +233,7 @@ static inline long lkl_sys_rmdir(const char *path) /** * lkl_sys_mknod - wrapper for lkl_sys_mknodat */ -static inline long lkl_sys_mknod(const char *path, mode_t mode, dev_t dev) +static inline lkl_long_t lkl_sys_mknod(const char *path, mode_t mode, dev_t dev) { return lkl_sys_mknodat(LKL_AT_FDCWD, path, mode, dev); } @@ -242,7 +243,7 @@ static inline long lkl_sys_mknod(const char *path, mode_t mode, dev_t dev) /** * lkl_sys_pipe - wrapper for lkl_sys_pipe2 */ -static inline long lkl_sys_pipe(int fd[2]) +static inline lkl_long_t lkl_sys_pipe(int fd[2]) { return lkl_sys_pipe2(fd, 0); } @@ -252,7 +253,7 @@ static inline long lkl_sys_pipe(int fd[2]) /** * lkl_sys_send - wrapper for lkl_sys_sendto */ -static inline long lkl_sys_send(int fd, void *buf, size_t len, int flags) +static inline lkl_long_t lkl_sys_send(int fd, void *buf, size_t len, int flags) { return lkl_sys_sendto(fd, buf, len, flags, 0, 0); } @@ -262,7 +263,7 @@ static inline long lkl_sys_send(int fd, void *buf, size_t len, int flags) /** * lkl_sys_recv - wrapper for lkl_sys_recvfrom */ -static inline long lkl_sys_recv(int fd, void *buf, size_t len, int flags) +static inline lkl_long_t lkl_sys_recv(int fd, void *buf, size_t len, int flags) { return lkl_sys_recvfrom(fd, buf, len, flags, 0, 0); } @@ -272,10 +273,10 @@ static inline long lkl_sys_recv(int fd, void *buf, size_t len, int flags) /** * lkl_sys_select - wrapper for lkl_sys_pselect */ -static inline long lkl_sys_select(int n, lkl_fd_set *rfds, lkl_fd_set *wfds, +static inline lkl_long_t lkl_sys_select(int n, lkl_fd_set *rfds, lkl_fd_set *wfds, lkl_fd_set *efds, struct lkl_timeval *tv) { - long data[2] = { 0, _LKL_NSIG/8 }; + lkl_long_t data[2] = { 0, _LKL_NSIG/8 }; struct __lkl__kernel_timespec ts; if (tv) { @@ -293,7 +294,7 @@ static inline long lkl_sys_select(int n, lkl_fd_set *rfds, lkl_fd_set *wfds, /** * lkl_sys_poll - wrapper for lkl_sys_ppoll */ -static inline long lkl_sys_poll(struct lkl_pollfd *fds, int n, int timeout) +static inline lkl_long_t lkl_sys_poll(struct lkl_pollfd *fds, int n, int timeout) { struct __lkl__kernel_timespec ts; @@ -311,7 +312,7 @@ static inline long lkl_sys_poll(struct lkl_pollfd *fds, int n, int timeout) /** * lkl_sys_epoll_create - wrapper for lkl_sys_epoll_create1 */ -static inline long lkl_sys_epoll_create(int size) +static inline lkl_long_t lkl_sys_epoll_create(int size) { return lkl_sys_epoll_create1(0); } @@ -321,7 +322,7 @@ static inline long lkl_sys_epoll_create(int size) /** * lkl_sys_epoll_wait - wrapper for lkl_sys_epoll_pwait */ -static inline long lkl_sys_epoll_wait(int fd, struct lkl_epoll_event *ev, +static inline lkl_long_t lkl_sys_epoll_wait(int fd, struct lkl_epoll_event *ev, int cnt, int to) { return lkl_sys_epoll_pwait(fd, ev, cnt, to, 0, _LKL_NSIG/8); @@ -428,7 +429,7 @@ int lkl_get_virtio_blkdev(int disk_id, unsigned int part, uint32_t *pdevid); * @mnt_str_len - size of mnt_str * @returns - 0 on success, a negative value on error */ -long lkl_mount_dev(unsigned int disk_id, unsigned int part, const char *fs_type, +lkl_long_t lkl_mount_dev(unsigned int disk_id, unsigned int part, const char *fs_type, int flags, const char *opts, char *mnt_str, unsigned int mnt_str_len); @@ -447,7 +448,7 @@ long lkl_mount_dev(unsigned int disk_id, unsigned int part, const char *fs_type, * @mnt_str_len - size of mnt_str * @returns - 0 on success, a negative value on error */ -long lkl_mount_blkdev(unsigned int dev, const char *fs_type, int flags, +lkl_long_t lkl_mount_blkdev(unsigned int dev, const char *fs_type, int flags, const char *opts, char *mnt_str, unsigned int mnt_str_len); @@ -464,8 +465,8 @@ long lkl_mount_blkdev(unsigned int dev, const char *fs_type, int flags, * umount can succeed * @returns - 0 on success, a negative value on error */ -long lkl_umount_dev(unsigned int disk_id, unsigned int part, int flags, - long timeout_ms); +lkl_long_t lkl_umount_dev(unsigned int disk_id, unsigned int part, int flags, + lkl_long_t timeout_ms); /** * lkl_umount_blkdev - umount a block device @@ -478,7 +479,7 @@ long lkl_umount_dev(unsigned int disk_id, unsigned int part, int flags, * umount can succeed * @returns - 0 on success, a negative value on error */ -long lkl_umount_blkdev(unsigned int dev, int flags, long timeout_ms); +lkl_long_t lkl_umount_blkdev(unsigned int dev, int flags, lkl_long_t timeout_ms); /** * lkl_umount_timeout - umount filesystem with timeout @@ -489,7 +490,7 @@ long lkl_umount_blkdev(unsigned int dev, int flags, long timeout_ms); * umount can succeed * @returns - 0 on success, a negative value on error */ -long lkl_umount_timeout(char *path, int flags, long timeout_ms); +lkl_long_t lkl_umount_timeout(char *path, int flags, lkl_long_t timeout_ms); /** * lkl_opendir - open a directory diff --git a/tools/lkl/lib/fs.c b/tools/lkl/lib/fs.c index 8bd8092fd355a7..39ed7f83042575 100644 --- a/tools/lkl/lib/fs.c +++ b/tools/lkl/lib/fs.c @@ -77,7 +77,7 @@ static int get_node_with_prefix(const char *path, const char *prefix, int lkl_encode_dev_from_sysfs(const char *sysfs_path, uint32_t *pdevid) { int ret; - long fd; + lkl_long_t fd; int major, minor; char buf[16] = { 0, }; char *bufptr; @@ -200,7 +200,7 @@ int lkl_get_virtio_blkdev(int disk_id, unsigned int part, uint32_t *pdevid) return lkl_encode_dev_from_sysfs(sysfs_path, pdevid); } -long lkl_mount_blkdev(unsigned int dev, const char *fs_type, int flags, +lkl_long_t lkl_mount_blkdev(unsigned int dev, const char *fs_type, int flags, const char *data, char *mnt_str, unsigned int mnt_str_len) { char dev_str[] = { "/dev/xxxxxxxx" }; @@ -257,7 +257,7 @@ long lkl_mount_blkdev(unsigned int dev, const char *fs_type, int flags, return 0; } -long lkl_mount_dev(unsigned int disk_id, unsigned int part, +lkl_long_t lkl_mount_dev(unsigned int disk_id, unsigned int part, const char *fs_type, int flags, const char *data, char *mnt_str, unsigned int mnt_str_len) { @@ -272,14 +272,14 @@ long lkl_mount_dev(unsigned int disk_id, unsigned int part, mnt_str_len); } -long lkl_umount_timeout(char *path, int flags, long timeout_ms) +lkl_long_t lkl_umount_timeout(char *path, int flags, lkl_long_t timeout_ms) { - long incr = 10000000; /* 10 ms */ + lkl_long_t incr = 10000000; /* 10 ms */ struct __lkl__kernel_timespec ts = { .tv_sec = 0, .tv_nsec = incr, }; - long err; + lkl_long_t err; do { err = lkl_sys_umount(path, flags); @@ -292,7 +292,7 @@ long lkl_umount_timeout(char *path, int flags, long timeout_ms) return err; } -long lkl_umount_blkdev(unsigned int dev, int flags, long timeout_ms) +lkl_long_t lkl_umount_blkdev(unsigned int dev, int flags, lkl_long_t timeout_ms) { char dev_str[] = { "/dev/xxxxxxxx" }; char mnt_str[] = { "/mnt/xxxxxxxx" }; @@ -312,8 +312,8 @@ long lkl_umount_blkdev(unsigned int dev, int flags, long timeout_ms) return lkl_sys_rmdir(mnt_str); } -long lkl_umount_dev(unsigned int disk_id, unsigned int part, int flags, - long timeout_ms) +lkl_long_t lkl_umount_dev(unsigned int disk_id, unsigned int part, int flags, + lkl_long_t timeout_ms) { unsigned int dev; int err; diff --git a/tools/lkl/lib/iomem.c b/tools/lkl/lib/iomem.c index f7dfe094ac10fe..c020b1b138c359 100644 --- a/tools/lkl/lib/iomem.c +++ b/tools/lkl/lib/iomem.c @@ -53,7 +53,7 @@ void unregister_iomem(void *base) iomem_regions[index].ops = NULL; } -void *lkl_ioremap(long addr, int size) +void *lkl_ioremap(lkl_long_t addr, int size) { int index = IOMEM_ADDR_TO_INDEX(addr); int offset = IOMEM_ADDR_TO_OFFSET(addr); diff --git a/tools/lkl/lib/iomem.h b/tools/lkl/lib/iomem.h index 42b1d6a0f10d34..5282c35dbb660a 100644 --- a/tools/lkl/lib/iomem.h +++ b/tools/lkl/lib/iomem.h @@ -8,7 +8,7 @@ struct lkl_iomem_ops { void* register_iomem(void *data, int size, const struct lkl_iomem_ops *ops); void unregister_iomem(void *iomem_base); -void *lkl_ioremap(long addr, int size); +void *lkl_ioremap(lkl_long_t addr, int size); int lkl_iomem_access(const volatile void *addr, void *res, int size, int write); #endif /* _LKL_LIB_IOMEM_H */ diff --git a/tools/lkl/lib/jmp_buf.c b/tools/lkl/lib/jmp_buf.c index 4cce84b751302d..79dc3829bba9aa 100644 --- a/tools/lkl/lib/jmp_buf.c +++ b/tools/lkl/lib/jmp_buf.c @@ -1,13 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifdef _WIN64 +/* + * The Win64 longjmp() unwinds the stack with RtlUnwindEx(), which fails when + * LKL jumps between the stacks of different threads. Without a frame, i.e. + * _setjmp(buf, NULL), longjmp() only restores the registers. + */ +#define __USE_MINGW_SETJMP_NON_SEH +#endif #include +#include #include +static jmp_buf *get_jmp_buf(struct lkl_jmp_buf *jmpb) +{ +#ifdef _WIN64 + /* the Win64 jmp_buf holds xmm registers and must be 16 bytes aligned */ + _Static_assert(sizeof(jmp_buf) + 15 <= sizeof(jmpb->buf), + "lkl_jmp_buf is too small"); + return (jmp_buf *)(((uintptr_t)jmpb->buf + 15) & ~(uintptr_t)15); +#else + return (jmp_buf *)jmpb->buf; +#endif +} + void jmp_buf_set(struct lkl_jmp_buf *jmpb, void (*f)(void)) { - if (!setjmp(*((jmp_buf *)jmpb->buf))) + if (!setjmp(*get_jmp_buf(jmpb))) f(); } void jmp_buf_longjmp(struct lkl_jmp_buf *jmpb, int val) { - longjmp(*((jmp_buf *)jmpb->buf), val); + longjmp(*get_jmp_buf(jmpb), val); } diff --git a/tools/lkl/lib/net.c b/tools/lkl/lib/net.c index 8c4f692308c5c8..8d337fe778778e 100644 --- a/tools/lkl/lib/net.c +++ b/tools/lkl/lib/net.c @@ -44,7 +44,7 @@ int lkl_inet_pton(int af, const char *src, void *dst) static inline int ifindex_to_name(int sock, struct lkl_ifreq *ifr, int ifindex) { ifr->lkl_ifr_ifindex = ifindex; - return lkl_sys_ioctl(sock, LKL_SIOCGIFNAME, (long)ifr); + return lkl_sys_ioctl(sock, LKL_SIOCGIFNAME, (lkl_long_t)ifr); } int lkl_ifname_to_ifindex(const char *name) @@ -58,7 +58,7 @@ int lkl_ifname_to_ifindex(const char *name) strcpy(ifr.lkl_ifr_name, name); - ret = lkl_sys_ioctl(fd, LKL_SIOCGIFINDEX, (long)&ifr); + ret = lkl_sys_ioctl(fd, LKL_SIOCGIFINDEX, (lkl_long_t)&ifr); if (ret < 0) return ret; @@ -76,10 +76,10 @@ int lkl_if_up(int ifindex) if (err < 0) return err; - err = lkl_sys_ioctl(sock, LKL_SIOCGIFFLAGS, (long)&ifr); + err = lkl_sys_ioctl(sock, LKL_SIOCGIFFLAGS, (lkl_long_t)&ifr); if (!err) { ifr.lkl_ifr_flags |= LKL_IFF_UP; - err = lkl_sys_ioctl(sock, LKL_SIOCSIFFLAGS, (long)&ifr); + err = lkl_sys_ioctl(sock, LKL_SIOCSIFFLAGS, (lkl_long_t)&ifr); } lkl_sys_close(sock); @@ -100,10 +100,10 @@ int lkl_if_down(int ifindex) if (err < 0) return err; - err = lkl_sys_ioctl(sock, LKL_SIOCGIFFLAGS, (long)&ifr); + err = lkl_sys_ioctl(sock, LKL_SIOCGIFFLAGS, (lkl_long_t)&ifr); if (!err) { ifr.lkl_ifr_flags &= ~LKL_IFF_UP; - err = lkl_sys_ioctl(sock, LKL_SIOCSIFFLAGS, (long)&ifr); + err = lkl_sys_ioctl(sock, LKL_SIOCSIFFLAGS, (lkl_long_t)&ifr); } lkl_sys_close(sock); @@ -126,7 +126,7 @@ int lkl_if_set_mtu(int ifindex, int mtu) ifr.lkl_ifr_mtu = mtu; - err = lkl_sys_ioctl(sock, LKL_SIOCSIFMTU, (long)&ifr); + err = lkl_sys_ioctl(sock, LKL_SIOCSIFMTU, (lkl_long_t)&ifr); lkl_sys_close(sock); @@ -146,10 +146,10 @@ int lkl_if_set_mac(int ifindex, void *addr) if (err < 0) goto out; - err = lkl_sys_ioctl(sock, LKL_SIOCGIFHWADDR, (long)&ifr); + err = lkl_sys_ioctl(sock, LKL_SIOCGIFHWADDR, (lkl_long_t)&ifr); if (!err) { memcpy(ifr.lkl_ifr_hwaddr.sa_data, addr, LKL_ETH_ALEN); - err = lkl_sys_ioctl(sock, LKL_SIOCSIFHWADDR, (long)&ifr); + err = lkl_sys_ioctl(sock, LKL_SIOCSIFHWADDR, (lkl_long_t)&ifr); } out: @@ -193,7 +193,7 @@ int lkl_netdev_get_ifindex(int id) return sock; snprintf(ifr.lkl_ifr_name, sizeof(ifr.lkl_ifr_name), "eth%d", id); - ret = lkl_sys_ioctl(sock, LKL_SIOCGIFINDEX, (long)&ifr); + ret = lkl_sys_ioctl(sock, LKL_SIOCGIFINDEX, (lkl_long_t)&ifr); lkl_sys_close(sock); return ret < 0 ? ret : ifr.lkl_ifr_ifindex; diff --git a/tools/lkl/lib/nt-host.c b/tools/lkl/lib/nt-host.c index 1d643da4168f9d..e75de674e3911e 100644 --- a/tools/lkl/lib/nt-host.c +++ b/tools/lkl/lib/nt-host.c @@ -208,7 +208,7 @@ static void CALLBACK timer_callback(void *arg, BOOLEAN TimerOrWaitFired) t->callback(); } -static int timer_set_oneshot(void *timer, unsigned long ns) +static int timer_set_oneshot(void *timer, lkl_ulong_t ns) { struct timer *t = (struct timer *)timer; HANDLE tmp; @@ -241,13 +241,31 @@ static void print(const char *str, int len) write(1, str, len); } -static void *mem_alloc(unsigned long size) +static void *mem_alloc(lkl_ulong_t size) { return malloc(size); } +static void *nt_memcpy(void *dest, const void *src, lkl_ulong_t n) +{ + return memcpy(dest, src, (size_t)n); +} + +static void *nt_memset(void *s, int c, lkl_ulong_t n) +{ + return memset(s, c, (size_t)n); +} + +static void *nt_memmove(void *dest, const void *src, lkl_ulong_t n) +{ + return memmove(dest, src, (size_t)n); +} + struct lkl_host_operations lkl_host_ops = { .panic = panic, + .memcpy = nt_memcpy, + .memset = nt_memset, + .memmove = nt_memmove, .thread_create = thread_create, .thread_detach = thread_detach, .thread_exit = thread_exit, diff --git a/tools/lkl/lib/posix-host.c b/tools/lkl/lib/posix-host.c index 2f4e0191dd78a7..4b80376a33c596 100644 --- a/tools/lkl/lib/posix-host.c +++ b/tools/lkl/lib/posix-host.c @@ -260,7 +260,7 @@ static int thread_equal(lkl_thread_t a, lkl_thread_t b) #define pthread_getattr_np pthread_attr_get_np #endif -void *thread_stack(unsigned long *size) +void *thread_stack(lkl_ulong_t *size) { pthread_attr_t thread_attr; size_t stack_size; @@ -426,7 +426,7 @@ static void *timer_alloc(void (*fn)(void)) return (void *)(long)timer; } -static int timer_set_oneshot(void *_timer, unsigned long ns) +static int timer_set_oneshot(void *_timer, lkl_ulong_t ns) { timer_t timer = (timer_t)(long)_timer; struct itimerspec ts = { @@ -451,7 +451,7 @@ static void panic(void) assert(0); } -static void *page_alloc(unsigned long size) +static void *page_alloc(lkl_ulong_t size) { void *addr; @@ -464,7 +464,7 @@ static void *page_alloc(unsigned long size) return addr; } -static void page_free(void *addr, unsigned long size) +static void page_free(void *addr, lkl_ulong_t size) { munmap((void *)addr, size); } @@ -495,7 +495,7 @@ static inline int get_prot(enum lkl_prot lkl_prot) #endif #endif -static void *lkl_mmap(void *addr, unsigned long size, enum lkl_prot prot) +static void *lkl_mmap(void *addr, lkl_ulong_t size, enum lkl_prot prot) { void *ret; int fl = MAP_ANON | MAP_PRIVATE | MAP_FIXED_NOREPLACE | MAP_NORESERVE; @@ -510,7 +510,7 @@ static void *lkl_mmap(void *addr, unsigned long size, enum lkl_prot prot) return ret; } -static int lkl_munmap(void *addr, unsigned long size) +static int lkl_munmap(void *addr, lkl_ulong_t size) { return munmap(addr, size); } @@ -521,9 +521,9 @@ extern struct lkl_dev_pci_ops vfio_pci_ops; #ifdef LKL_HOST_CONFIG_MMU static int shared_mem_fd = -1; -static unsigned long shared_mem_size; +static lkl_ulong_t shared_mem_size; -static void shmem_init(unsigned long size) +static void shmem_init(lkl_ulong_t size) { int rwx = 00700; char lkl_shmem_id[NAME_MAX]; @@ -535,8 +535,8 @@ static void shmem_init(unsigned long size) assert(ftruncate(shared_mem_fd, shared_mem_size) == 0); } -static void *lkl_shmem_mmap(void *addr, unsigned long pg_off, - unsigned long size, enum lkl_prot mem_prot_flags) +static void *lkl_shmem_mmap(void *addr, lkl_ulong_t pg_off, + lkl_ulong_t size, enum lkl_prot mem_prot_flags) { int prot = get_prot(mem_prot_flags); int flags = MAP_SHARED | MAP_FIXED_NOREPLACE; @@ -548,22 +548,22 @@ static void *lkl_shmem_mmap(void *addr, unsigned long pg_off, } #endif // LKL_HOST_CONFIG_MMU -static void *posix_malloc(unsigned long size) +static void *posix_malloc(lkl_ulong_t size) { return malloc((size_t)size); } -static void *posix_memcpy(void *dest, const void *src, unsigned long n) +static void *posix_memcpy(void *dest, const void *src, lkl_ulong_t n) { return memcpy(dest, src, (size_t)n); } -static void *posix_memset(void *s, int c, unsigned long n) +static void *posix_memset(void *s, int c, lkl_ulong_t n) { return memset(s, c, (size_t)n); } -static void *posix_memmove(void *dest, const void *src, unsigned long n) +static void *posix_memmove(void *dest, const void *src, lkl_ulong_t n) { return memmove(dest, src, (size_t)n); } diff --git a/tools/lkl/lib/vfio_pci.c b/tools/lkl/lib/vfio_pci.c index b68f904253a5eb..49deabd4091615 100644 --- a/tools/lkl/lib/vfio_pci.c +++ b/tools/lkl/lib/vfio_pci.c @@ -56,7 +56,7 @@ struct lkl_pci_dev { */ static struct lkl_pci_dev *vfio_pci_add(const char *name, void *kernel_ram, - unsigned long ram_size) + lkl_ulong_t ram_size) { struct lkl_pci_dev *dev; char path[128], link[128], *l; @@ -605,13 +605,13 @@ static void vfio_pci_remove(struct lkl_pci_dev *dev) } static unsigned long long vfio_map_page(struct lkl_pci_dev *dev, void *vaddr, - unsigned long size) + lkl_ulong_t size) { return (unsigned long long)vaddr - dev->dma_map.vaddr; } static void vfio_unmap_page(struct lkl_pci_dev *dev, - unsigned long long dma_handle, unsigned long size) + unsigned long long dma_handle, lkl_ulong_t size) { } @@ -716,7 +716,7 @@ static const struct lkl_iomem_ops pci_resource_ops = { #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) static void *vfio_resource_alloc(struct lkl_pci_dev *dev, - unsigned long resource_size, + lkl_ulong_t resource_size, int resource_index) { unsigned int region_index_list[] = { diff --git a/tools/lkl/lib/virtio.c b/tools/lkl/lib/virtio.c index a83dde5258897f..bf296aece14c35 100644 --- a/tools/lkl/lib/virtio.c +++ b/tools/lkl/lib/virtio.c @@ -405,7 +405,7 @@ static inline void set_ptr_low(void **ptr, uint32_t val) uint64_t tmp = (uintptr_t)*ptr; tmp = (tmp & 0xFFFFFFFF00000000) | val; - *ptr = (void *)(long)tmp; + *ptr = (void *)(lkl_long_t)tmp; } static inline void set_ptr_high(void **ptr, uint32_t val) @@ -413,7 +413,7 @@ static inline void set_ptr_high(void **ptr, uint32_t val) uint64_t tmp = (uintptr_t)*ptr; tmp = (tmp & 0x00000000FFFFFFFF) | ((uint64_t)val << 32); - *ptr = (void *)(long)tmp; + *ptr = (void *)(lkl_long_t)tmp; } static inline void set_status(struct virtio_dev *dev, uint32_t val) @@ -562,7 +562,7 @@ int virtio_dev_setup(struct virtio_dev *dev, int queues, int num_max) dev->virtio_mmio_id = lkl_num_virtio_boot_devs++; } else { ret = - lkl_sys_virtio_mmio_device_add((long)dev->base, mmio_size, + lkl_sys_virtio_mmio_device_add((lkl_long_t)dev->base, mmio_size, dev->irq); if (ret < 0) { lkl_printf("can't register mmio device\n"); @@ -577,8 +577,8 @@ int virtio_dev_setup(struct virtio_dev *dev, int queues, int num_max) int virtio_dev_cleanup(struct virtio_dev *dev) { char devname[100]; - long fd, ret; - long mount_ret; + lkl_long_t fd, ret; + lkl_long_t mount_ret; if (!lkl_is_running()) goto skip_unbind; diff --git a/tools/lkl/lib/virtio_net_wintap.c b/tools/lkl/lib/virtio_net_wintap.c index 5f29737094ecf2..e49764553e9043 100644 --- a/tools/lkl/lib/virtio_net_wintap.c +++ b/tools/lkl/lib/virtio_net_wintap.c @@ -6,8 +6,8 @@ * Author: Hajime Tazaki * */ -#include -#include +#include +#include #include #include #include diff --git a/tools/lkl/scripts/binutils-build.sh b/tools/lkl/scripts/binutils-build.sh new file mode 100755 index 00000000000000..dc8267e339a04b --- /dev/null +++ b/tools/lkl/scripts/binutils-build.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Build GNU binutils with the PE/COFF NT weak externals fixes needed to +# link LKL for Windows hosts. The patches live in binutils-patches/. +# +# usage: binutils-build.sh [target...] +# +# The default target is x86_64-w64-mingw32. The tools are installed in +# $BINUTILS_PREFIX (default: $HOME/lkl-binutils); put $BINUTILS_PREFIX/bin +# in PATH before building LKL. + +set -e + +version=2.47 +sha256=154ab23b60070e8f27013c22977f1129425d67d1e8acd6e13010e617811e4cff +mirror=${GNU_MIRROR:-https://ftpmirror.gnu.org/gnu} + +patches=$(cd "$(dirname "$0")/binutils-patches" && pwd) +prefix=${BINUTILS_PREFIX:-$HOME/lkl-binutils} +targets=${*:-x86_64-w64-mingw32} +jobs=$(nproc 2>/dev/null || echo 4) + +tmp=$(mktemp -d) +trap 'rm -rf "$tmp"' EXIT +cd "$tmp" + +curl -fsSL --retry 3 -o binutils-$version.tar.xz \ + $mirror/binutils/binutils-$version.tar.xz +echo "$sha256 binutils-$version.tar.xz" | sha256sum -c - +tar -xf binutils-$version.tar.xz + +for p in "$patches"/*.patch; do + patch -d binutils-$version -p1 < "$p" +done + +for target in $targets; do + mkdir build-$target + cd build-$target + ../binutils-$version/configure --target=$target --prefix="$prefix" \ + --disable-nls --disable-werror --disable-gdb --disable-gdbserver \ + --disable-sim --disable-gprof --disable-gprofng + make -j$jobs all-gas all-ld all-binutils + make install-gas install-ld install-binutils + cd .. +done diff --git a/tools/lkl/scripts/binutils-patches/.gitignore b/tools/lkl/scripts/binutils-patches/.gitignore new file mode 100644 index 00000000000000..69f1bf45309577 --- /dev/null +++ b/tools/lkl/scripts/binutils-patches/.gitignore @@ -0,0 +1 @@ +!*.patch diff --git a/tools/lkl/scripts/binutils-patches/0001-Relocate-aux-entries-for-NT-weak-externals.patch b/tools/lkl/scripts/binutils-patches/0001-Relocate-aux-entries-for-NT-weak-externals.patch new file mode 100644 index 00000000000000..0a906749c7f0fc --- /dev/null +++ b/tools/lkl/scripts/binutils-patches/0001-Relocate-aux-entries-for-NT-weak-externals.patch @@ -0,0 +1,123 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Octavian Purdila +Date: Mon, 26 Oct 2015 15:57:34 +0200 +Subject: [PATCH 1/3] Relocate aux entries for NT weak externals + +Currently the tagndx for NT weak externals are not relocated when +creating a relocatable object which breaks relocations when doing the +final link of the relocatable object. + +For the following example: + + a.c: + void foo(void); + + int main() + { + foo(); + return 0; + } + + b.c: + #include + + void __attribute__((weak)) foo(void) + { + printf("%s weak\n", __func__); + } + +$ i686-w64-mingw32-ld -r -o r.o a.o b.o + +This is how the symbol table looks for b.o: + +$ i686-w64-mingw32-objdump -x b.o | grep -A 1 foo +[ 23](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 .weak._foo. +[ 24](sec 0)(fl 0x00)(ty 20)(scl 105) (nx 1) 0x00000000 _foo + +And this is how the symbol table looks for r.o: + +$ i686-w64-mingw32-objdump -x r.o | grep -A 1 foo +[ 45](sec 0)(fl 0x00)(ty 20)(scl 105) (nx 1) 0x00000000 _foo +AUX lnno 1 size 0x0 tagndx 23 +... +[ 48](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 .weak._foo. + +As you can see the AUX entry for _foo is wrong in r.o, it should be 48 +but it is 23. + +The patch uses the sym_indices array to relocate the AUX entries for +weak externals in _bfd_coff_link_input_bfd. + +In order to do so we need the .weak. counterpart symbol to be loaded +before the weak external symbol. This is prevented by the ISFCN() +check _bfd_coff_link_input_bfd and is caused by the fact that the AUX +entry type is 0. To fix this issue we patch gas to propagate the type +of external weak symbols to its .weak. counterpart symbol. + +Note that we perform the AUX tag relocations only int the case of +relocatable output because weak external relocation handling +(_bfd_coff_generic_relocate_section) uses the tagndx relative to the +input object. + +bfd/ + +2015-10-26 Octavian Purdila + + * cofflink.c (_bfd_coff_link_input_bfd): relocate AUX entries for + weak externals when generating relocatable objects + +gas/ + +2015-10-26 Octavian Purdila + + * obj-coff.c (coff_frob_symbol): propagate the type of external + weak symbol to its .weak. counterpart +--- + bfd/cofflink.c | 14 +++++++++++--- + gas/config/obj-coff.c | 1 + + 2 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/bfd/cofflink.c b/bfd/cofflink.c +index d029bec..bc7820f 100644 +--- a/bfd/cofflink.c ++++ b/bfd/cofflink.c +@@ -2124,7 +2124,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) + if ((*indexp < 0 + || (bfd_size_type) *indexp < syment_base) + && (*sym_hash == NULL +- || (*sym_hash)->auxbfd != input_bfd)) ++ || (*sym_hash)->auxbfd != input_bfd) ++ && isymp->n_sclass != C_NT_WEAK) + esym += add * isymesz; + else + { +@@ -2194,8 +2195,15 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) + auxp->x_file.x_n.x_n.x_offset = STRING_SIZE_SIZE + indx; + } + } +- else if ((isymp->n_sclass != C_STAT || isymp->n_type != T_NULL) +- && isymp->n_sclass != C_NT_WEAK) ++ else if (isymp->n_sclass == C_NT_WEAK) ++ { ++ unsigned int *tagndx = &auxp->x_sym.x_tagndx.u32; ++ ++ if (bfd_link_relocatable (flaginfo->info) && ++ flaginfo->sym_indices[*tagndx] > 0) ++ *tagndx = flaginfo->sym_indices[*tagndx]; ++ } ++ else if (isymp->n_sclass != C_STAT || isymp->n_type != T_NULL) + { + unsigned long indx; + +diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c +index 7732c0a..5df3940 100644 +--- a/gas/config/obj-coff.c ++++ b/gas/config/obj-coff.c +@@ -1259,6 +1259,7 @@ coff_frob_symbol (symbolS *symp, int *punt) + symbol_get_value_expression (weakp)); + symbol_set_frag (symp, symbol_get_frag (weakp)); + S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp)); ++ S_SET_DATA_TYPE (symp, S_GET_DATA_TYPE (weakp)); + } + else + { diff --git a/tools/lkl/scripts/binutils-patches/0002-Convert-NT-weak-externals-to-locals.patch b/tools/lkl/scripts/binutils-patches/0002-Convert-NT-weak-externals-to-locals.patch new file mode 100644 index 00000000000000..a279be446b9c33 --- /dev/null +++ b/tools/lkl/scripts/binutils-patches/0002-Convert-NT-weak-externals-to-locals.patch @@ -0,0 +1,139 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Octavian Purdila +Date: Mon, 26 Oct 2015 15:57:35 +0200 +Subject: [PATCH 2/3] Convert NT weak externals to locals + +This patch allows converting a weak external symbol to a local symbol +by setting up its section and value to the ones of the alternate +symbol. This is useful when we want to make only a few selected +symbols visible (e.g. objcopy -G). + +The conversion is triggered when an NT weak external symbol has been +marked with BSF_LOCAL. + +bfd/ + +2015-10-22 Octavian Purdila + + * coffgen.c: add coff_nt_weak_to_local() that implements weak + external to local symbol conversion + * coffcode.h (coff_write_object_contents): call + coff_nt_weak_to_local() + * libcoff.h: add coff_nt_weak_to_local() declaration + +binutils/ + +2015-10-26 Octavian Purdila + + * objcopy.c (filter_symbols): allow converting undefined weak + symbols to local symbols for PE objects (as PE weak externals are + implemented as undefined weak symbols) +--- + bfd/coffcode.h | 1 + + bfd/coffgen.c | 43 +++++++++++++++++++++++++++++++++++++++++++ + bfd/libcoff.h | 2 ++ + binutils/objcopy.c | 12 +++++++++++- + 4 files changed, 57 insertions(+), 1 deletion(-) + +diff --git a/bfd/coffcode.h b/bfd/coffcode.h +index 12cc7c3..719e5fc 100644 +--- a/bfd/coffcode.h ++++ b/bfd/coffcode.h +@@ -4157,6 +4157,7 @@ coff_write_object_contents (bfd * abfd) + { + int firstundef; + ++ coff_nt_weak_to_local(abfd); + if (!coff_renumber_symbols (abfd, &firstundef)) + return false; + coff_mangle_symbols (abfd); +diff --git a/bfd/coffgen.c b/bfd/coffgen.c +index f306064..23b4ec8 100644 +--- a/bfd/coffgen.c ++++ b/bfd/coffgen.c +@@ -890,6 +890,49 @@ coff_renumber_symbols (bfd *bfd_ptr, int *first_undef) + return true; + } + ++/* Transform weak externals to local symbols if requested (e.g. objcopy). */ ++void coff_nt_weak_to_local(bfd *abfd) ++{ ++ unsigned int symbol_count = bfd_get_symcount (abfd); ++ asymbol **symbol_ptr_ptr = abfd->outsymbols; ++ unsigned int symbol_index; ++ ++ for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) ++ { ++ asymbol *symbol = symbol_ptr_ptr[symbol_index]; ++ coff_symbol_type *coff_symbol_ptr; ++ combined_entry_type *native; ++ struct internal_syment *sym; ++ ++ coff_symbol_ptr = coff_symbol_from (symbol); ++ if (!coff_symbol_ptr) ++ continue; ++ ++ native = coff_symbol_ptr->native; ++ if (!native) ++ continue; ++ ++ sym = &native->u.syment; ++ ++ if ((symbol->flags & BSF_LOCAL) && sym->n_sclass == C_NT_WEAK ++ && sym->n_numaux == 1) { ++ union internal_auxent *aux = &native[1].u.auxent; ++ struct internal_syment *wsym = &aux->x_sym.x_tagndx.p->u.syment; ++ ++ if (!wsym) { ++ symbol->flags &= BSF_LOCAL; ++ continue; ++ } ++ ++ symbol->flags &= ~BSF_WEAK; ++ symbol->value = wsym->n_value; ++ symbol->section = coff_section_from_bfd_index (abfd, wsym->n_scnum); ++ symbol->section->output_section = symbol->section; ++ sym->n_numaux = 0; ++ } ++ } ++} ++ + /* Run thorough the symbol table again, and fix it so that all + pointers to entries are changed to the entries' index in the output + symbol table. */ +diff --git a/bfd/libcoff.h b/bfd/libcoff.h +index 8d918ba..a852fd7 100644 +--- a/bfd/libcoff.h ++++ b/bfd/libcoff.h +@@ -368,6 +368,8 @@ extern int coff_count_linenumbers + (bfd *) ATTRIBUTE_HIDDEN; + extern bool coff_renumber_symbols + (bfd *, int *) ATTRIBUTE_HIDDEN; ++extern void coff_nt_weak_to_local ++ (bfd *) ATTRIBUTE_HIDDEN; + extern void coff_mangle_symbols + (bfd *) ATTRIBUTE_HIDDEN; + extern bool coff_write_symbols +diff --git a/binutils/objcopy.c b/binutils/objcopy.c +index 4ab7e89..afb55b8 100644 +--- a/binutils/objcopy.c ++++ b/binutils/objcopy.c +@@ -1765,7 +1765,17 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms, + + if (keep) + { +- if (!undefined ++ if ((flags & BSF_GLOBAL) != 0 ++ && (weaken || is_specified_symbol (name, weaken_specific_htab))) ++ { ++ sym->flags &= ~ BSF_GLOBAL; ++ sym->flags |= BSF_WEAK; ++ } ++ ++ /* We want to check even undefined weak symbols in the case of PE, ++ * since weak externals are classified as undefined. */ ++ if ((!undefined || (bfd_get_flavour (abfd) == bfd_target_coff_flavour && ++ startswith ((abfd)->xvec->name, "pe"))) + && (flags & (BSF_GLOBAL | BSF_WEAK)) + && (is_specified_symbol (name, localize_specific_htab) + || (htab_elements (keepglobal_specific_htab) != 0 diff --git a/tools/lkl/scripts/binutils-patches/0003-Resolve-weak-externals-by-name-rather-than-stale-tag.patch b/tools/lkl/scripts/binutils-patches/0003-Resolve-weak-externals-by-name-rather-than-stale-tag.patch new file mode 100644 index 00000000000000..fc1411b3e7437d --- /dev/null +++ b/tools/lkl/scripts/binutils-patches/0003-Resolve-weak-externals-by-name-rather-than-stale-tag.patch @@ -0,0 +1,148 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sheldon Qi <3365420+xdqi@users.noreply.github.com> +Date: Thu, 30 Apr 2026 22:18:21 +0800 +Subject: [PATCH 3/3] Resolve weak externals by name rather than stale tagndx + +When ld -r creates a relocatable object (e.g. vmlinux), the tagndx +field in weak external aux entries is not relocated and points to the +wrong symbol. All 352 C_NT_WEAK symbols in vmlinux have incorrect +tagndx values -- some point to non-code sections (e.g. .data section +symbols) while others point to completely unrelated code symbols +(e.g. bpf_arena_get_user_vm_start tagndx -> cmd_line_append). + +The previous implementation only fell back to name-based lookup when +tagndx pointed to a non-code section, which missed the case where +tagndx points to a wrong but valid code symbol. This caused objcopy +-G to resolve weak externals to incorrect addresses, leading to +runtime crashes (e.g. ktime_get dereferencing NULL through +tk_core->clock, or lkl_start_kernel calling the wrong functions). + +Fix coff_nt_weak_to_local() to always search for the .weak.. +implementation by name first, since PE COFF weak external naming is +deterministic. Only fall back to the tagndx pointer when no name match +is found. + +Co-Authored-By: Claude Opus 4.7 +--- + bfd/coffgen.c | 93 ++++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 77 insertions(+), 16 deletions(-) + +diff --git a/bfd/coffgen.c b/bfd/coffgen.c +index 23b4ec8..0cefa34 100644 +--- a/bfd/coffgen.c ++++ b/bfd/coffgen.c +@@ -890,7 +890,12 @@ coff_renumber_symbols (bfd *bfd_ptr, int *first_undef) + return true; + } + +-/* Transform weak externals to local symbols if requested (e.g. objcopy). */ ++/* Transform weak externals to local symbols if requested (e.g. objcopy). ++ When ld -r creates a relocatable object, the tagndx field in the weak ++ external's aux entry may point to the wrong symbol due to unrelocated ++ symbol indices. We always search for the .weak. counterpart by name, ++ which is reliable, and only fall back to the tagndx pointer when no ++ .weak. match is found. */ + void coff_nt_weak_to_local(bfd *abfd) + { + unsigned int symbol_count = bfd_get_symcount (abfd); +@@ -906,29 +911,85 @@ void coff_nt_weak_to_local(bfd *abfd) + + coff_symbol_ptr = coff_symbol_from (symbol); + if (!coff_symbol_ptr) +- continue; ++ continue; + + native = coff_symbol_ptr->native; + if (!native) +- continue; ++ continue; + + sym = &native->u.syment; + + if ((symbol->flags & BSF_LOCAL) && sym->n_sclass == C_NT_WEAK + && sym->n_numaux == 1) { +- union internal_auxent *aux = &native[1].u.auxent; +- struct internal_syment *wsym = &aux->x_sym.x_tagndx.p->u.syment; +- +- if (!wsym) { +- symbol->flags &= BSF_LOCAL; +- continue; +- } +- +- symbol->flags &= ~BSF_WEAK; +- symbol->value = wsym->n_value; +- symbol->section = coff_section_from_bfd_index (abfd, wsym->n_scnum); +- symbol->section->output_section = symbol->section; +- sym->n_numaux = 0; ++ union internal_auxent *aux = &native[1].u.auxent; ++ const char *weakname = bfd_asymbol_name (symbol); ++ char leading = bfd_get_symbol_leading_char (abfd); ++ const char *stripped = weakname; ++ unsigned int j; ++ int found = 0; ++ ++ if (leading && stripped[0] == leading) ++ stripped++; ++ size_t nlen = strlen (stripped); ++ ++ /* Always search for the .weak. implementation by name. ++ The tagndx field is unreliable after ld -r. */ ++ for (j = 0; j < symbol_count; j++) ++ { ++ asymbol *wsym_ptr = symbol_ptr_ptr[j]; ++ const char *wname = bfd_asymbol_name (wsym_ptr); ++ const char *wstripped = wname; ++ size_t wslen; ++ if (leading && wstripped[0] == leading) ++ wstripped++; ++ wslen = strlen (wstripped); ++ /* .weak. symbols: ".weak.." */ ++ if (wslen > 6 + nlen + 1 ++ && strncmp (wstripped, ".weak.", 6) == 0 ++ && wstripped[6 + nlen] == '.' ++ && strncmp (wstripped + 6, stripped, nlen) == 0) ++ { ++ asection *s = wsym_ptr->section; ++ if (s && (s->flags & SEC_CODE)) ++ { ++ symbol->value = bfd_asymbol_value (wsym_ptr); ++ symbol->section = s; ++ symbol->section->output_section = s; ++ symbol->flags &= ~BSF_WEAK; ++ sym->n_numaux = 0; ++ found = 1; ++ break; ++ } ++ } ++ } ++ ++ if (!found) ++ { ++ /* No .weak. code counterpart found by name; check if the ++ tagndx pointer points somewhere usable. */ ++ struct internal_syment *wsym; ++ asection *wsec; ++ ++ wsym = &aux->x_sym.x_tagndx.p->u.syment; ++ wsec = coff_section_from_bfd_index (abfd, wsym->n_scnum); ++ ++ if (wsec && wsec != bfd_abs_section_ptr ++ && !bfd_is_und_section (wsec) ++ && !bfd_is_com_section (wsec) ++ && (wsec->flags & SEC_CODE)) ++ { ++ symbol->flags &= ~BSF_WEAK; ++ symbol->value = wsym->n_value; ++ symbol->section = wsec; ++ symbol->section->output_section = wsec; ++ sym->n_numaux = 0; ++ } ++ else ++ { ++ /* No usable target; just mark local */ ++ symbol->flags &= BSF_LOCAL; ++ } ++ } + } + } + } diff --git a/tools/lkl/scripts/win64-cc.sh b/tools/lkl/scripts/win64-cc.sh new file mode 100755 index 00000000000000..9d408822161b7d --- /dev/null +++ b/tools/lkl/scripts/win64-cc.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Win64 compiler shim, used as x86_64-w64-mingw32-gcc through the links in +# tools/lkl/bin, which is in PATH for the kernel build. The kernel must be +# built for LP64 (long is 64 bit) while Win64 is LLP64 (long is 32 bit), so: +# +# - kernel code and any link is routed to x86_64-pc-cygwin-gcc: same MS x64 +# calling convention and PE/COFF output as MinGW, but LP64; MinGW ld also +# overflows IMAGE_REL_AMD64_REL32 relocations on the large kernel object +# - user space code is compiled with the real x86_64-w64-mingw32-gcc +# +# The LKL API uses lkl_long_t (always 64 bit) to bridge the difference. + +LKL_BIN_DIR="$(cd "$(dirname "$0")" && pwd)" + +for arg in "$@"; do + if [[ "$arg" == "-D__KERNEL__" || "$arg" == *lkl.o ]]; then + exec x86_64-pc-cygwin-gcc "$@" + fi +done + +case " $* " in +*" -c "*|*" -S "*|*" -E "*) ;; +*) exec x86_64-pc-cygwin-gcc "$@" ;; +esac + +# Find the real MinGW gcc, skipping this shim +for gcc in $(which -a x86_64-w64-mingw32-gcc); do + if [[ "$(cd "$(dirname "$gcc")" && pwd)" != "$LKL_BIN_DIR" ]]; then + exec "$gcc" "$@" + fi +done + +echo "$0: x86_64-w64-mingw32-gcc not found" >&2 +exit 1 diff --git a/tools/lkl/scripts/win64-toolchain.sh b/tools/lkl/scripts/win64-toolchain.sh new file mode 100755 index 00000000000000..e93f9122ca69ac --- /dev/null +++ b/tools/lkl/scripts/win64-toolchain.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Install a Linux hosted toolchain for Win64 (x86_64-w64-mingw32) builds: +# +# - x86_64-pc-cygwin-gcc (kernel, LP64) and x86_64-w64-mingw32-gcc (user +# space, LLP64) from msys2-cross (https://github.com/xdqi/msys-cross) +# - binutils with the NT weak externals fixes, see binutils-build.sh +# +# Then build with patched binutils first in PATH: +# +# PATH=$BINUTILS_PREFIX/bin:$MSYS_CROSS_PREFIX/bin:$PATH \ +# make -C tools/lkl CROSS_COMPILE=x86_64-w64-mingw32- +# +# When running in GitHub Actions the directories are added to $GITHUB_PATH. + +set -e + +release=${MSYS_CROSS_RELEASE:-build-20261001.1} +url=https://github.com/xdqi/msys-cross/releases/download/$release +prefix=${MSYS_CROSS_PREFIX:-/opt/msys2-cross} +binutils_prefix=${BINUTILS_PREFIX:-$HOME/lkl-binutils} +script_dir=$(cd "$(dirname "$0")" && pwd) + +if ! mkdir -p "$prefix" 2>/dev/null; then + sudo mkdir -p "$prefix" + sudo chown "$(id -u):$(id -g)" "$prefix" +fi + +if [ ! -x "$prefix/bin/msys-pacman" ]; then + curl -fsSL --retry 3 $url/bootstrap.tar.xz | + tar -xJ -C "$prefix" --strip-components=1 +fi + +# Serve the package database locally and download the packages from the +# release assets: pacman tries the servers in order for each file. +repo=$prefix/var/lib/msys-cross-repo +mkdir -p "$repo" +curl -fsSL --retry 3 -o "$repo/msys-cross.db" $url/msys-cross.db.tar.gz +sed -i -e '/^\[msys-cross\]/,/^\[/ { /^Server = /d }' \ + -e "/^\[msys-cross\]/a Server = file://$repo\nServer = $url" \ + "$prefix/etc/pacman.d/pacman.conf" + +"$prefix/bin/msys-pacman" -Sy --noconfirm --needed \ + msys-cross-cygwin-gcc msys-cross-mingw64-gcc + +if [ ! -x "$binutils_prefix/bin/x86_64-w64-mingw32-ld" ]; then + BINUTILS_PREFIX=$binutils_prefix "$script_dir/binutils-build.sh" \ + x86_64-w64-mingw32 +fi + +# Entries added later take precedence +if [ -n "$GITHUB_PATH" ]; then + echo "$prefix/bin" >> "$GITHUB_PATH" + echo "$binutils_prefix/bin" >> "$GITHUB_PATH" +fi diff --git a/tools/lkl/tests/boot.c b/tools/lkl/tests/boot.c index f7b7d4fa0a360e..7f746d0c3d9e87 100644 --- a/tools/lkl/tests/boot.c +++ b/tools/lkl/tests/boot.c @@ -32,8 +32,8 @@ int lkl_test_nanosleep(void) .tv_nsec = sleep_ns, }; struct timespec start, stop; - long delta; - long ret; + lkl_long_t delta; + lkl_long_t ret; clock_gettime(CLOCK_MONOTONIC, &start); ret = lkl_sys_nanosleep(&ts, NULL); @@ -54,12 +54,12 @@ int lkl_test_nanosleep(void) LKL_TEST_CALL(getpid, lkl_sys_getpid, 1) -void check_latency(long (*f)(void), long *min, long *max, long *avg) +void check_latency(lkl_long_t (*f)(void), lkl_long_t *min, lkl_long_t *max, lkl_long_t *avg) { int i; unsigned long long start, stop, sum = 0; static const int count = 1000; - long delta; + lkl_long_t delta; *min = 1000000000; *max = -1; @@ -78,7 +78,7 @@ void check_latency(long (*f)(void), long *min, long *max, long *avg) *avg = sum / count; } -static long native_getpid(void) +static lkl_long_t native_getpid(void) { #ifdef __MINGW32__ GetCurrentProcessId(); @@ -90,17 +90,19 @@ static long native_getpid(void) int lkl_test_syscall_latency(void) { - long min, max, avg; + lkl_long_t min, max, avg; lkl_test_logf("avg/min/max: "); check_latency(lkl_sys_getpid, &min, &max, &avg); - lkl_test_logf("lkl:%ld/%ld/%ld ", avg, min, max); + lkl_test_logf("lkl:%lld/%lld/%lld ", (long long)avg, (long long)min, + (long long)max); check_latency(native_getpid, &min, &max, &avg); - lkl_test_logf("native:%ld/%ld/%ld\n", avg, min, max); + lkl_test_logf("native:%lld/%lld/%lld\n", (long long)avg, (long long)min, + (long long)max); return TEST_SUCCESS; } @@ -122,11 +124,11 @@ LKL_TEST_CALL(lseek_set, lkl_sys_lseek, 0, 0, 0, LKL_SEEK_SET); int lkl_test_read(void) { char buf[10] = { 0, }; - long ret; + lkl_long_t ret; ret = lkl_sys_read(0, buf, sizeof(buf)); - lkl_test_logf("lkl_sys_read=%ld buf=%s\n", ret, buf); + lkl_test_logf("lkl_sys_read=%lld buf=%s\n", (long long)ret, buf); if (ret == sizeof(wrbuf) && !strcmp(wrbuf, buf)) return TEST_SUCCESS; @@ -137,12 +139,12 @@ int lkl_test_read(void) int lkl_test_fstat(void) { struct lkl_stat stat; - long ret; + lkl_long_t ret; ret = lkl_sys_fstat(0, &stat); - lkl_test_logf("lkl_sys_fstat=%ld mode=%o size=%zd\n", ret, stat.st_mode, - stat.st_size); + lkl_test_logf("lkl_sys_fstat=%lld mode=%o size=%lld\n", (long long)ret, + stat.st_mode, (long long)stat.st_size); if (ret == 0 && stat.st_size == sizeof(wrbuf) && stat.st_mode == (access_rights | LKL_S_IFREG)) @@ -156,11 +158,11 @@ LKL_TEST_CALL(mkdir, lkl_sys_mkdir, 0, "/mnt", access_rights) int lkl_test_stat(void) { struct lkl_stat stat; - long ret; + lkl_long_t ret; ret = lkl_sys_stat("/mnt", &stat); - lkl_test_logf("lkl_sys_stat(\"/mnt\")=%ld mode=%o\n", ret, + lkl_test_logf("lkl_sys_stat(\"/mnt\")=%lld mode=%o\n", (long long)ret, stat.st_mode); if (ret == 0 && stat.st_mode == (access_rights | LKL_S_IFDIR)) @@ -177,7 +179,7 @@ static int lkl_test_pipe2(void) char str[20]; int msg_len_bytes = strlen(msg) + 1; int cmp_res; - long ret; + lkl_long_t ret; ret = lkl_sys_pipe2(pipe_fds, LKL_O_NONBLOCK); if (ret) { @@ -190,7 +192,7 @@ static int lkl_test_pipe2(void) if (ret < 0) lkl_test_logf("write error: %s\n", lkl_strerror(ret)); else - lkl_test_logf("short write: %ld\n", ret); + lkl_test_logf("short write: %lld\n", (long long)ret); return TEST_FAILURE; } @@ -199,7 +201,7 @@ static int lkl_test_pipe2(void) if (ret < 0) lkl_test_logf("read error: %s\n", lkl_strerror(ret)); else - lkl_test_logf("short read: %ld\n", ret); + lkl_test_logf("short read: %lld\n", (long long)ret); return TEST_FAILURE; } @@ -230,7 +232,7 @@ static int lkl_test_epoll(void) int READ_IDX = 0, WRITE_IDX = 1; struct lkl_epoll_event wait_on, read_result; const char msg[] = "Hello world!"; - long ret; + lkl_long_t ret; memset(&wait_on, 0, sizeof(wait_on)); memset(&read_result, 0, sizeof(read_result)); @@ -264,7 +266,7 @@ static int lkl_test_epoll(void) lkl_test_logf("epoll_wait error: %s\n", lkl_strerror(ret)); else - lkl_test_logf("epoll_wait: bad event: 0x%lx\n", ret); + lkl_test_logf("epoll_wait: bad event: 0x%llx\n", (long long)ret); return TEST_FAILURE; } @@ -281,7 +283,7 @@ static int lkl_test_epoll(void) lkl_test_logf("epoll_wait error: %s\n", lkl_strerror(ret)); else - lkl_test_logf("epoll_wait: bad ev no %ld\n", ret); + lkl_test_logf("epoll_wait: bad ev no %lld\n", (long long)ret); return TEST_FAILURE; } @@ -312,7 +314,7 @@ static int lkl_test_open_cwd(void) static int lkl_test_getdents64(void) { - long ret; + lkl_long_t ret; char buf[1024], *pos; struct lkl_linux_dirent64 *de; int wr; @@ -346,7 +348,7 @@ LKL_TEST_CALL(lo_ifup, lkl_if_up, 0, 1); static int lkl_test_mutex(void) { - long ret = TEST_SUCCESS; + lkl_long_t ret = TEST_SUCCESS; /* * Can't do much to verify that this works, so we'll just let Valgrind * warn us on CI if we've made bad memory accesses. @@ -371,7 +373,7 @@ static int lkl_test_mutex(void) static int lkl_test_semaphore(void) { - long ret = TEST_SUCCESS; + lkl_long_t ret = TEST_SUCCESS; /* * Can't do much to verify that this works, so we'll just let Valgrind * warn us on CI if we've made bad memory accesses. @@ -400,7 +402,7 @@ static int lkl_test_syscall_thread(void) { int pipe_fds[2]; char tmp[LKL_PIPE_BUF+1]; - long ret; + lkl_long_t ret; lkl_thread_t tid; ret = lkl_sys_pipe2(pipe_fds, 0); @@ -426,7 +428,7 @@ static int lkl_test_syscall_thread(void) if (ret < 0) lkl_test_logf("write error: %s\n", lkl_strerror(ret)); else - lkl_test_logf("short write: %ld\n", ret); + lkl_test_logf("short write: %lld\n", (long long)ret); return TEST_FAILURE; } @@ -468,8 +470,8 @@ static int lkl_test_many_syscall_threads(void) } struct lkl_test_tgid { - long tgid; - long parent_pid; + lkl_long_t tgid; + lkl_long_t parent_pid; int new_thread_group_leader_result; }; @@ -489,7 +491,7 @@ static void thread_get_tgid(void *arg) static int lkl_test_new_tgid_threads(void) { lkl_thread_t tid; - long current_pid; + lkl_long_t current_pid; int count = 65, ret; struct lkl_test_tgid test_tgid; @@ -545,10 +547,10 @@ static int lkl_test_join(void) int ret = lkl_host_ops.thread_join(tid); if (ret == 0) { - lkl_test_logf("joined %ld\n", tid); + lkl_test_logf("joined %lld\n", (long long)tid); return TEST_SUCCESS; } else { - lkl_test_logf("failed joining %ld\n", tid); + lkl_test_logf("failed joining %lld\n", (long long)tid); return TEST_FAILURE; } } @@ -599,7 +601,7 @@ static int lkl_test_shared_mmap(void) if (fd < 0) return TEST_FAILURE; - unsigned long mem_size = 15 * 4096; + lkl_ulong_t mem_size = 15 * 4096; if (lkl_sys_ftruncate(fd, mem_size) < 0) return TEST_FAILURE; @@ -627,10 +629,10 @@ static int lkl_test_shared_mmap(void) if (memcmp(mem1, mem2, mem_size) != 0) return TEST_FAILURE; - if (lkl_sys_munmap((unsigned long)mem1, mem_size) != 0) + if (lkl_sys_munmap((lkl_ulong_t)mem1, mem_size) != 0) return TEST_FAILURE; - if (lkl_sys_munmap((unsigned long)mem2, mem_size) != 0) + if (lkl_sys_munmap((lkl_ulong_t)mem2, mem_size) != 0) return TEST_FAILURE; return TEST_SUCCESS; @@ -638,7 +640,7 @@ static int lkl_test_shared_mmap(void) static int lkl_test_private_mmap(void) { - unsigned long mem_size = 3 * 4096; + lkl_ulong_t mem_size = 3 * 4096; int mem_prot = LKL_PROT_WRITE | LKL_PROT_READ; // Super important to use LKL_MAP_POPULATE to force populating pages in the // mapping as in the LKL context we don't have a way to fault in the pages. @@ -650,7 +652,7 @@ static int lkl_test_private_mmap(void) *(unsigned int *)mem = 13; - if (lkl_sys_munmap((unsigned long)mem, mem_size) < 0) + if (lkl_sys_munmap((lkl_ulong_t)mem, mem_size) < 0) return TEST_FAILURE; return TEST_SUCCESS; diff --git a/tools/lkl/tests/disk-vfio-pci.c b/tools/lkl/tests/disk-vfio-pci.c index 8779f59bf2e5d5..bf5b9b7a3d6be5 100644 --- a/tools/lkl/tests/disk-vfio-pci.c +++ b/tools/lkl/tests/disk-vfio-pci.c @@ -6,7 +6,9 @@ #include #include #include +#ifndef __MINGW32__ #include +#endif #include #include @@ -120,7 +122,7 @@ static int lkl_test_blkdev(void) return TEST_FAILURE; } - err = lkl_sys_ioctl(fd, LKL_BLKGETSIZE64, (unsigned long)&size); + err = lkl_sys_ioctl(fd, LKL_BLKGETSIZE64, (lkl_ulong_t)&size); if (err < 0) { lkl_test_logf("BLKGETSIZE64 failed: %s\n", lkl_strerror(fd)); lkl_sys_close(fd); diff --git a/tools/lkl/tests/disk.c b/tools/lkl/tests/disk.c index 5e1a6113bfa72f..bfa008a1a021e9 100644 --- a/tools/lkl/tests/disk.c +++ b/tools/lkl/tests/disk.c @@ -104,13 +104,13 @@ LKL_TEST_CALL(mount_dev, lkl_mount_dev, 0, disk_id, cla.partition, cla.fstype, static int lkl_test_umount_dev(void) { - long ret, ret2; + lkl_long_t ret, ret2; ret = lkl_sys_chdir("/"); ret2 = lkl_umount_dev(disk_id, cla.partition, 0, 1000); - lkl_test_logf("%ld %ld", ret, ret2); + lkl_test_logf("%lld %lld", (long long)ret, (long long)ret2); if (!ret && !ret2) return TEST_SUCCESS; diff --git a/tools/lkl/tests/net.sh b/tools/lkl/tests/net.sh index 05bb2843a9d439..e7b9c40dc74a41 100755 --- a/tools/lkl/tests/net.sh +++ b/tools/lkl/tests/net.sh @@ -82,6 +82,9 @@ setup_backend() export_vars work_dir fifo1 fifo2 ;; "tap") + if [ -n "$LKL_HOST_CONFIG_NT" ]; then + return $TEST_SKIP + fi tap_prepare if ! lkl_test_cmd test -c /dev/net/tun; then if [ -z "$LKL_HOST_CONFIG_BSD" ]; then @@ -121,6 +124,10 @@ setup_backend() echo "skipping on non-windows 64-bits host" return $TEST_SKIP fi + if ! command -v netsh > /dev/null; then + echo "no netsh command (running under wine?)" + return $TEST_SKIP + fi netsh interface ip set address \ "OpenVPN TAP-Windows6" static $(ip_host) 255.255.255.0 0.0.0.0 netsh advfirewall set allprofiles state off diff --git a/tools/lkl/tests/test-dlmopen.c b/tools/lkl/tests/test-dlmopen.c index 292eec7094a832..2257dfd2420bb0 100644 --- a/tools/lkl/tests/test-dlmopen.c +++ b/tools/lkl/tests/test-dlmopen.c @@ -24,13 +24,13 @@ static int lkl_test_dlmopen(void) { void *handle; - long ret; + lkl_long_t ret; char *filename = "liblkl.so"; - long params[6] = {0}; + lkl_long_t params[6] = {0}; int (*fn_init)(struct lkl_host_operations *ops); int (*fn_start)(char *fmt, ...); - long (*fn_syscall)(long no, long *params); - long (*fn_sys_halt)(void); + lkl_long_t (*fn_syscall)(lkl_long_t no, lkl_long_t *params); + lkl_long_t (*fn_sys_halt)(void); void (*fn_tls_mode)(void); struct lkl_host_operations *lkl_host_ops;