Comments (4)
I ran into (what I think is) a similar issue with struct epoll_event
, which differs in size between x86_64
and aarch64
due to different structure-packing settings. Chiefly, on x86_64
, the kernel expects a 12-byte struct; on aarch64
, the kernel expects a 16-byte struct.
The issue I ran into -- and that I suspect you might run into here -- is that changing the kernel's definition of struct stat
will break every existing program; however, changing the user's definition will break Popcorn applications on the aarch64
kernel only.
My ad-hoc solution involved declaring the "kernel-correct" version of the structure inside musl's epoll.c
file and copying each field from the "user-correct" version into the corresponding field of the "kernel-correct" structure, using temporary stack-allocated variables. Needless to say, this is a terrible workaround:
diff --git a/lib/musl-1.1.18/src/linux/epoll.c b/lib/musl-1.1.18/src/linux/epoll.c
index deff5b1..0df118e 100644
--- a/lib/musl-1.1.18/src/linux/epoll.c
+++ b/lib/musl-1.1.18/src/linux/epoll.c
@@ -1,8 +1,19 @@
#include <sys/epoll.h>
#include <signal.h>
#include <errno.h>
+#if !defined(__x86_64__)
+#include <string.h>
+#endif
#include "syscall.h"
+#if !defined(__x86_64__)
+struct epoll_event16 {
+ uint32_t events;
+ char pad[4];
+ epoll_data_t data;
+};
+#endif
+
int epoll_create(int size)
{
return epoll_create1(0);
@@ -19,16 +30,42 @@ int epoll_create1(int flags)
int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev)
{
+#if !defined(__x86_64__)
+ struct epoll_event16 ev16;
+ if (ev) {
+ memcpy(&ev16.events, &ev->events, sizeof (uint32_t));
+ memcpy(&ev16.data, &ev->data, sizeof (epoll_data_t));
+ return syscall(SYS_epoll_ctl, fd, op, fd2, &ev16);
+ }
+ else {
+ return syscall(SYS_epoll_ctl, fd, op, fd2, NULL);
+ }
+#else
return syscall(SYS_epoll_ctl, fd, op, fd2, ev);
+#endif
}
int epoll_pwait(int fd, struct epoll_event *ev, int cnt, int to, const sigset_t *sigs)
{
+#if !defined(__x86_64__)
+ struct epoll_event16 ev16[cnt]; //VLAs are evil!
+ memset(ev16, 0, sizeof ev16[0] * cnt);
+ int r = __syscall(SYS_epoll_pwait, fd, ev16, cnt, to, sigs, _NSIG/8);
+#ifdef SYS_epoll_wait
+ if (r==-ENOSYS && !sigs) r = __syscall(SYS_epoll_wait, fd, ev16, cnt, to);
+#endif
+ for (int i = 0; i < cnt; ++i) {
+ memcpy(&ev[i].events, &ev16[i].events, sizeof (uint32_t));
+ memcpy(&ev[i].data, &ev16[i].data, sizeof (epoll_data_t));
+ }
+ return __syscall_ret(r);
+#else
int r = __syscall(SYS_epoll_pwait, fd, ev, cnt, to, sigs, _NSIG/8);
#ifdef SYS_epoll_wait
if (r==-ENOSYS && !sigs) r = __syscall(SYS_epoll_wait, fd, ev, cnt, to);
#endif
return __syscall_ret(r);
+#endif
}
int epoll_wait(int fd, struct epoll_event *ev, int cnt, int to)
from popcorn-compiler.
Thank Anthony for the comment. Do you mean I should modify the popcorn-compiler musl source to adjust to the kernel's declaration? I thought this is a problem caused by the different header files of x86/arm.
from popcorn-compiler.
Before I answer that, let me ask this question to clarify:
-- Are the x86/arm kernel declarations the same?
-- If so, do the popcorn-compiler musl headers match either of the kernel declarations, or none of them?
from popcorn-compiler.
Hey guys. [Good news] I wrote a patch inmusl-1.1.18/src/stat/fstat.c
to marshal the struct stat
from x86 to aarch64, it solves the tiny web server problem right now. [Bad news] It still has wrong result when passing the struct stat
as a parameter to another function. I'll write another issue for that.
The patch for fstat
is:
$ git diff 4ffd16e00d70a40b4cdde9507f6eddadffef62b8
diff --git a/lib/musl-1.1.18/src/stat/fstat.c b/lib/musl-1.1.18/src/stat/fstat.c
index ab4afc0..d3b47ad 100644
--- a/lib/musl-1.1.18/src/stat/fstat.c
+++ b/lib/musl-1.1.18/src/stat/fstat.c
@@ -4,10 +4,95 @@
#include "syscall.h"
#include "libc.h"
+#if defined(__x86_64__)
+#include <string.h>
+
+// The syscall on x86 returns the x86 version of struct stat.
+// But the x86 binary actually uses the arm version of stat.
+// copied from arch/x86_64/bits/stat.h
+struct stat_x86 {
+ dev_t st_dev;
+ ino_t st_ino;
+ nlink_t st_nlink;
+
+ mode_t st_mode;
+ uid_t st_uid;
+ gid_t st_gid;
+ unsigned int __pad0;
+ dev_t st_rdev;
+ off_t st_size;
+ blksize_t st_blksize;
+ blkcnt_t st_blocks;
+
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+ long __unused[3];
+};
+
+// Copied from arch/aarch64/bits/stat.h
+struct stat_arm {
+ dev_t st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ nlink_t st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+ dev_t st_rdev;
+ unsigned long __pad;
+ off_t st_size;
+ blksize_t st_blksize;
+ int __pad2;
+ blkcnt_t st_blocks;
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+ unsigned __unused[2];
+};
+
+#define MARSHALLING_STAT(st, st_x86) \
+ memcpy(st, &st_x86, sizeof(struct stat)); \
+ st->st_mode = st_x86.st_mode; \
+ st->st_nlink = (unsigned)(st_x86.st_nlink);\
+ st->st_uid = st_x86.st_uid; \
+ st->st_gid = st_x86.st_gid; \
+ st->st_rdev = st_x86.st_rdev;
+
+#endif
void __procfdname(char *, unsigned);
int fstat(int fd, struct stat *st)
{
+#if defined(__x86_64__)
+ struct stat_x86 st_x86;
+ int ret = __syscall(SYS_fstat, fd, &st_x86);
+
+ // convert a "kernel stat (x86_64)" to "musl stat (aarch64)"
+ MARSHALLING_STAT(((struct stat_arm *)st), st_x86)
+
+ if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) {
+ return __syscall_ret(ret);
+ }
+
+ char buf[15+3*sizeof(int)];
+ __procfdname(buf, fd);
+#ifdef SYS_stat
+ ret = syscall(SYS_stat, buf, &st_x86);
+
+ // convert a "kernel stat (x86_64)" to "musl stat (aarch64)"
+ MARSHALLING_STAT(((struct stat_arm *)st), st_x86)
+
+ return ret;
+#else
+ ret = syscall(SYS_fstatat, AT_FDCWD, buf, &st_x86, 0);
+
+ // convert a "kernel stat (x86_64)" to "musl stat (aarch64)"
+ MARSHALLING_STAT(((struct stat_arm *)st), st_x86)
+
+ return ret;
+#endif
+
+#else // aarch64 default code
int ret = __syscall(SYS_fstat, fd, st);
if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
return __syscall_ret(ret);
@@ -19,6 +104,7 @@ int fstat(int fd, struct stat *st)
#else
return syscall(SYS_fstatat, AT_FDCWD, buf, st, 0);
#endif
+#endif // end if define(__x86_64__)
}
LFS64(fstat);
from popcorn-compiler.
Related Issues (20)
- Segmentation fault during homogeneous execution on aarch64 HOT 2
- pyalign script bugs HOT 2
- Failed assertion in CodeGen/UnwindInfo.cpp HOT 2
- Soft floating-point emulation routines leaking into aarch64 HOT 9
- Unable to build bodytrack with clang HOT 1
- Unhandled level 2 translation fault HOT 1
- Segfault when compiling bzlib.c (bzip2 SPEC-2006) HOT 1
- Compilation fails with backend ran out of registers HOT 1
- number of records for stackmap ... doesn't match HOT 1
- Argv argument table corruption HOT 2
- Cannot Build libopenpop HOT 2
- libelf: different code paths on aarch64 compared to x86-64 HOT 1
- GCC constructor/destructor attributes do not execute on AArch64
- SIGRTMIN does not induce migration
- Wrong value when passing "struct stat" as a parameter to a function
- Stack transform timing utility architecture mismatch HOT 2
- Changing musl Makefile to use -O0 explicitly causes arm64 STLXR -> LDAXR pair to fail on real machines
- ./install_compiler.py error on Ubuntu 20.04 HOT 2
- libevent configure failed
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from popcorn-compiler.