Message ID | 20230530113302.1473632-1-zhangjialing@loongson.cn |
---|---|
State | New |
Headers | show |
Series | [v4] Fixes pseudo build in loongarch64 | expand |
Hi JiaLing On 30.05.23 at 13:33, zhangjialing@loongson.cn wrote: > From: JiaLing Zhang <zhangjialing@loongson.cn> > > Fixes [YOCTO #15110] > > Some functions used in the project have been removed from glibc. After the removal of these functions, > the architecture in glibc will not include the removed functions. > This patch resolves the usage and compilation issues on the loongarch64 architecture > > Signed-off-by: JiaLing Zhang <zhangjialing@loongson.cn> The patch looks perfect, thanks! I trust you on the contents ;-) Cheers Michael.
On Tue, 2023-05-30 at 19:33 +0800, zhangjialing@loongson.cn wrote: > From: JiaLing Zhang <zhangjialing@loongson.cn> > > Fixes [YOCTO #15110] > > Some functions used in the project have been removed from glibc. After the removal of these functions, > the architecture in glibc will not include the removed functions. > This patch resolves the usage and compilation issues on the loongarch64 architecture Whilst this might make things compile, I'm not convinced this is right. I suspect that with this patch applied, you'd miss intercepting some function calls that need intercepting. As far as I can tell, the __fxstat64() function and friends should exist even on a new architecture like loongarch64. Are you sure these don't exist in a loongarch64 glibc? Cheers, Richard
On Tue, 30 May 2023 19:33:03 +0800 zhangjialing@loongson.cn wrote: > +#ifdef __loongarch64 No. Use the configuration mechanisms or whatever to determine the *actual distinction you care about*, which is "does glibc have __xstat64", give that a name, and use the name. Some day, someone else will make a glibc that doesn't have __xstat64. The change to adopt that should be one line in configure or the like, not hundreds of changes scattered throughout the code. > + int existed = (real_stat64(path, &buf) != -1); > +#else > int existed = (real___xstat64(_STAT_VER, path, &buf) != -1); > - > +#endif This looks suspiciously similar to the logic you introduce elsewhere for base_stat, base_fstat, etcetera. Reproducing that up here: > +#ifdef __loongarch64 > +#define base_fstatat(dirfd, path, buf, flags) real_fstatat64( dirfd, > path, buf, flags) > +#else > #define base_fstatat(dirfd, path, buf, flags) > real___fxstatat64(_STAT_VER, dirfd, path, buf, flags) > +#endif Again, shouldn't be using a specific arch flag, should be using a symbolic flag, but: Given this, maybe we should just be using base_fstatat, base_stat, etcetera, in these lines, rather than calling a specific real___foo function directly. Or alternatively, we should be using pseudo_stat, etcetera, which also exist, and I honestly don't remember why there are two sets of those. So the change should look something like - int existed = ((real___xstat64(_STAT_VER, path, &buf) != -1); + int existed = ((base_stat(path, &buf) != -1); with suitable updates to the way we define the base_foo functions, making them contingent on something like HAVE_XSTAT. This would cover the vast majority of these changes, but not all of them. > --- a/ports/linux/guts/fstat.c > +++ b/ports/linux/guts/fstat.c > @@ -7,8 +7,17 @@ > * int fstat(int fd, struct stat *buf) > * int rc = -1; > */ > - > +#ifdef __loongarch64 > + struct stat64 buf64; > + /* populate buffer with complete data */ > + real_fstat(fd, buf); > + /* obtain fake data */ > + rc = wrap_fstat64(fd, &buf64); > + /* overwrite */ > + pseudo_stat32_from64(buf, &buf64); > +#else > rc = wrap___fxstat(_STAT_VER, fd, buf); > +#endif > > /* return rc; > * } Here, we really do have a meaningful change; in the standard linux port, we know that we can just forward fstat to __fxstat. Probably the best model for the canonical way to fix this is to look at the oldclone/newclone subports. When you have changes this substantive, we don't want to do them with large inline #ifdefs; we want to describe these as distinct subports, which have a different set of functions. So in the hypothetical new "xstat" port, we'd have the existing fstat and __fxstat wrappers, and in the new "noxstat" port, we'd just have an fstat wrapper that uses the same logic. > diff --git a/templates/wrapfuncs.c b/templates/wrapfuncs.c > index 93bb671..14a42e2 100644 > --- a/templates/wrapfuncs.c > +++ b/templates/wrapfuncs.c > @@ -13,7 +13,9 @@ > * script if you want to modify this. */ > @body > > +#ifndef __loongarch64 > static ${type} (*real_${name})(${decl_args}) = ${real_init}; > +#endif > > ${maybe_skip} I don't understand how this part can work at all; I was under the impression that we actually did in fact use these real_foo objects, and this seems to remove them all, so I don't even get how this is compiling or running, because after this, there's no real_foo function pointers at all? Unfortunately, it turns out bitrot has taken my laptop and I can't build pseudo on it natively because _STAT_VER no longer exists. So I think the hypothetical distant future in which we conceivably care about a system on which the real___xstatat(_STAT_VER, ...) calls fail and isn't __longarch64 actually happened over a year ago and we just didn't notice. "Oops." -s
I am working on changing the v4 into a more generic implementation based on Seebs' and others comments. I'll likely be sending something to the list as an RFC later today or tomorrow. --Mark On 5/30/23 11:43 AM, Seebs wrote: > On Tue, 30 May 2023 19:33:03 +0800 > zhangjialing@loongson.cn wrote: > >> +#ifdef __loongarch64 > > No. > > Use the configuration mechanisms or whatever to determine the *actual > distinction you care about*, which is "does glibc have __xstat64", give > that a name, and use the name. > > Some day, someone else will make a glibc that doesn't have __xstat64. > The change to adopt that should be one line in configure or the like, > not hundreds of changes scattered throughout the code. > >> + int existed = (real_stat64(path, &buf) != -1); >> +#else >> int existed = (real___xstat64(_STAT_VER, path, &buf) != -1); >> - >> +#endif > > This looks suspiciously similar to the logic you introduce elsewhere > for base_stat, base_fstat, etcetera. > > Reproducing that up here: > >> +#ifdef __loongarch64 >> +#define base_fstatat(dirfd, path, buf, flags) real_fstatat64( dirfd, >> path, buf, flags) >> +#else >> #define base_fstatat(dirfd, path, buf, flags) >> real___fxstatat64(_STAT_VER, dirfd, path, buf, flags) >> +#endif > > Again, shouldn't be using a specific arch flag, should be using a > symbolic flag, but: Given this, maybe we should just be using > base_fstatat, base_stat, etcetera, in these lines, rather than > calling a specific real___foo function directly. Or alternatively, > we should be using pseudo_stat, etcetera, which also exist, and > I honestly don't remember why there are two sets of those. > > So the change should look something like > > - int existed = ((real___xstat64(_STAT_VER, path, &buf) != -1); > + int existed = ((base_stat(path, &buf) != -1); > > with suitable updates to the way we define the base_foo functions, > making them contingent on something like HAVE_XSTAT. > > This would cover the vast majority of these changes, but not all of > them. > >> --- a/ports/linux/guts/fstat.c >> +++ b/ports/linux/guts/fstat.c >> @@ -7,8 +7,17 @@ >> * int fstat(int fd, struct stat *buf) >> * int rc = -1; >> */ >> - >> +#ifdef __loongarch64 >> + struct stat64 buf64; >> + /* populate buffer with complete data */ >> + real_fstat(fd, buf); >> + /* obtain fake data */ >> + rc = wrap_fstat64(fd, &buf64); >> + /* overwrite */ >> + pseudo_stat32_from64(buf, &buf64); >> +#else >> rc = wrap___fxstat(_STAT_VER, fd, buf); >> +#endif >> >> /* return rc; >> * } > > Here, we really do have a meaningful change; in the standard linux port, > we know that we can just forward fstat to __fxstat. > > Probably the best model for the canonical way to fix this is to look > at the oldclone/newclone subports. When you have changes this > substantive, we don't want to do them with large inline #ifdefs; we want > to describe these as distinct subports, which have a different set of > functions. So in the hypothetical new "xstat" port, we'd have the > existing fstat and __fxstat wrappers, and in the new "noxstat" port, > we'd just have an fstat wrapper that uses the same logic. > >> diff --git a/templates/wrapfuncs.c b/templates/wrapfuncs.c >> index 93bb671..14a42e2 100644 >> --- a/templates/wrapfuncs.c >> +++ b/templates/wrapfuncs.c >> @@ -13,7 +13,9 @@ >> * script if you want to modify this. */ >> @body >> >> +#ifndef __loongarch64 >> static ${type} (*real_${name})(${decl_args}) = ${real_init}; >> +#endif >> >> ${maybe_skip} > > I don't understand how this part can work at all; I was under the > impression that we actually did in fact use these real_foo objects, > and this seems to remove them all, so I don't even get how this > is compiling or running, because after this, there's no real_foo > function pointers at all? > > Unfortunately, it turns out bitrot has taken my laptop and I can't > build pseudo on it natively because _STAT_VER no longer exists. So > I think the hypothetical distant future in which we conceivably > care about a system on which the real___xstatat(_STAT_VER, ...) calls > fail and isn't __longarch64 actually happened over a year ago and > we just didn't notice. > > "Oops." > > -s > > > > -=-=-=-=-=-=-=-=-=-=-=- > Links: You receive all messages sent to this group. > View/Reply Online (#181938): https://lists.openembedded.org/g/openembedded-core/message/181938 > Mute This Topic: https://lists.openembedded.org/mt/99217464/3616948 > Group Owner: openembedded-core+owner@lists.openembedded.org > Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [mark.hatle@kernel.crashing.org] > -=-=-=-=-=-=-=-=-=-=-=- >
Hi, I'm sure in a loongarch64 glibc don't has these functions . We can find the libc.abilist file in the glibc source code . I found no __fxstat in loongarch eg:``` ➜ glibc git:(master) cat ./sysdeps/unix/sysv/linux/x86_64/64/libc.abilist |grep __fx GLIBC_2.2.5 __fxstat F GLIBC_2.2.5 __fxstat64 F GLIBC_2.4 __fxstatat F GLIBC_2.4 __fxstatat64 F ➜ glibc git:(master) cat ./sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist|grep __fx ``` 在 2023/5/30 20:23, Richard Purdie 写道: > On Tue, 2023-05-30 at 19:33 +0800, zhangjialing@loongson.cn wrote: >> From: JiaLing Zhang <zhangjialing@loongson.cn> >> >> Fixes [YOCTO #15110] >> >> Some functions used in the project have been removed from glibc. After the removal of these functions, >> the architecture in glibc will not include the removed functions. >> This patch resolves the usage and compilation issues on the loongarch64 architecture > Whilst this might make things compile, I'm not convinced this is right. > I suspect that with this patch applied, you'd miss intercepting some > function calls that need intercepting. > > As far as I can tell, the __fxstat64() function and friends should > exist even on a new architecture like loongarch64. Are you sure these > don't exist in a loongarch64 glibc? > > Cheers, > > Richard
diff --git a/ports/linux/guts/fopen64.c b/ports/linux/guts/fopen64.c index e76da69..db522a4 100644 --- a/ports/linux/guts/fopen64.c +++ b/ports/linux/guts/fopen64.c @@ -8,11 +8,13 @@ * wrap_fopen64(const char *path, const char *mode) { * FILE * rc = 0; */ - struct stat64 buf; - int save_errno; - + struct stat64 buf; + int save_errno; +#ifdef __loongarch64 + int existed = (real_stat64(path, &buf) != -1); +#else int existed = (real___xstat64(_STAT_VER, path, &buf) != -1); - +#endif rc = real_fopen64(path, mode); save_errno = errno; @@ -20,7 +22,11 @@ int fd = fileno(rc); pseudo_debug(PDBGF_FILE, "fopen64 '%s': fd %d <FILE %p>\n", path, fd, (void *) rc); +#ifdef __loongarch64 + if (real_fstat64( fd, &buf) != -1) { +#else if (real___fxstat64(_STAT_VER, fd, &buf) != -1) { +#endif if (!existed) { real_fchmod(fd, PSEUDO_FS_MODE(0666 & ~pseudo_umask, 0)); pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf); diff --git a/ports/linux/guts/freopen64.c b/ports/linux/guts/freopen64.c index 5fc9073..f249682 100644 --- a/ports/linux/guts/freopen64.c +++ b/ports/linux/guts/freopen64.c @@ -10,7 +10,11 @@ */ struct stat64 buf; int save_errno; +#ifdef __loongarch64 + int existed = (real_stat64(path, &buf) != -1); +#else int existed = (real___xstat64(_STAT_VER, path, &buf) != -1); +#endif rc = real_freopen64(path, mode, stream); save_errno = errno; @@ -19,7 +23,11 @@ int fd = fileno(rc); pseudo_debug(PDBGF_FILE, "freopen64 '%s': fd %d\n", path, fd); +#ifdef __loongarch64 + if (real_fstat64(fd, &buf) != -1) { +#else if (real___fxstat64(_STAT_VER, fd, &buf) != -1) { +#endif if (!existed) { real_fchmod(fd, PSEUDO_FS_MODE(0666 & ~pseudo_umask, 0)); pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf); diff --git a/ports/linux/guts/fstat.c b/ports/linux/guts/fstat.c index b089b15..35ef0ad 100644 --- a/ports/linux/guts/fstat.c +++ b/ports/linux/guts/fstat.c @@ -7,8 +7,17 @@ * int fstat(int fd, struct stat *buf) * int rc = -1; */ - +#ifdef __loongarch64 + struct stat64 buf64; + /* populate buffer with complete data */ + real_fstat(fd, buf); + /* obtain fake data */ + rc = wrap_fstat64(fd, &buf64); + /* overwrite */ + pseudo_stat32_from64(buf, &buf64); +#else rc = wrap___fxstat(_STAT_VER, fd, buf); +#endif /* return rc; * } diff --git a/ports/linux/guts/fstat64.c b/ports/linux/guts/fstat64.c index 6dd97da..77e1a00 100644 --- a/ports/linux/guts/fstat64.c +++ b/ports/linux/guts/fstat64.c @@ -7,8 +7,24 @@ * int fstat64(int fd, struct stat *buf) * int rc = -1; */ +#ifdef __loongarch64 + pseudo_msg_t *msg; + int save_errno; + rc = real_fstat64(fd, buf); + save_errno = errno; + if (rc == -1) { + return rc; + } + msg = pseudo_client_op(OP_FSTAT, 0, fd, -1, 0, buf); + if (msg && msg->result == RESULT_SUCCEED) { + pseudo_stat_msg(buf, msg); + } + + errno = save_errno; +#else rc = wrap___fxstat64(_STAT_VER, fd, buf); +#endif /* return rc; * } diff --git a/ports/linux/guts/fstatat.c b/ports/linux/guts/fstatat.c index 3267641..de69662 100644 --- a/ports/linux/guts/fstatat.c +++ b/ports/linux/guts/fstatat.c @@ -7,8 +7,14 @@ * int fstatat(int dirfd, const char *path, struct stat *buf, int flags) * int rc = -1; */ - +#ifdef __loongarch64 + struct stat64 buf64; + real_fstatat(dirfd,path,buf,flags); + rc = wrap_fstatat64(dirfd, path, &buf64, flags); + pseudo_stat32_from64(buf, &buf64); +#else rc = wrap___fxstatat(_STAT_VER, dirfd, path, buf, flags); +#endif /* return rc; * } diff --git a/ports/linux/guts/fstatat64.c b/ports/linux/guts/fstatat64.c index c981e14..f61d8aa 100644 --- a/ports/linux/guts/fstatat64.c +++ b/ports/linux/guts/fstatat64.c @@ -8,7 +8,50 @@ * int rc = -1; */ +#ifdef __loongarch64 + pseudo_msg_t *msg; + int save_errno; + +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + if (dirfd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } +#endif + if (flags & AT_SYMLINK_NOFOLLOW) { +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + rc = real_lstat64(path, buf); +#else + rc = real_fstatat64(dirfd, path, buf, flags); +#endif + if (rc == -1) { + return rc; + } + } else { +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + rc = real_stat64( path, buf); +#else + rc = real_fstatat64(dirfd, path, buf, flags); +#endif + if (rc == -1) { + return rc; + } + } + save_errno = errno; + + /* query database + * note that symlink canonicalizing is now automatic, so we + * don't need to check for a symlink on this end + */ + msg = pseudo_client_op(OP_STAT, 0, -1, dirfd, path, buf); + if (msg && msg->result == RESULT_SUCCEED) { + pseudo_stat_msg(buf, msg); + } + + errno = save_errno; +#else rc = wrap___fxstatat64(_STAT_VER, dirfd, path, buf, flags); +#endif /* return rc; * } diff --git a/ports/linux/guts/lstat.c b/ports/linux/guts/lstat.c index d2c4d50..da88a9b 100644 --- a/ports/linux/guts/lstat.c +++ b/ports/linux/guts/lstat.c @@ -7,8 +7,11 @@ * int lstat(const char *path, struct stat *buf) * int rc = -1; */ - +#ifdef __loongarch64 + rc = wrap_fstatat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW); +#else rc = wrap___fxstatat(_STAT_VER, AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW); +#endif /* return rc; * } diff --git a/ports/linux/guts/lstat64.c b/ports/linux/guts/lstat64.c index 43d0ce1..fbbe727 100644 --- a/ports/linux/guts/lstat64.c +++ b/ports/linux/guts/lstat64.c @@ -7,8 +7,11 @@ * int lstat64(const char *path, struct stat *buf) * int rc = -1; */ - +#ifdef __loongarch64 + rc = wrap_fstatat64( AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW); +#else rc = wrap___fxstatat64(_STAT_VER, AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW); +#endif /* return rc; * } diff --git a/ports/linux/guts/mknod.c b/ports/linux/guts/mknod.c index 61fd320..512e5bb 100644 --- a/ports/linux/guts/mknod.c +++ b/ports/linux/guts/mknod.c @@ -8,7 +8,11 @@ * int rc = -1; */ +#ifdef __loongarch64 + rc = wrap_mknodat(AT_FDCWD, path, mode, dev); +#else rc = wrap___xmknod(_MKNOD_VER, path, mode, &dev); +#endif /* return rc; * } diff --git a/ports/linux/guts/mknodat.c b/ports/linux/guts/mknodat.c index a7e4293..fb8c0c0 100644 --- a/ports/linux/guts/mknodat.c +++ b/ports/linux/guts/mknodat.c @@ -7,8 +7,80 @@ * int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev) * int rc = -1; */ +#ifdef __loongarch64 + pseudo_msg_t *msg; + struct stat64 buf; + /* mask out mode bits appropriately */ + mode = mode & ~pseudo_umask; + /* if you don't specify a type, assume regular file */ + if (!(mode & S_IFMT)) { + mode |= S_IFREG; + } + pseudo_debug(PDBGF_FILE, "mknodat creating '%s', mode 0%o\n", + path ? path : "<no name>", (int) mode); + + /* we don't use underlying call, so _ver is irrelevant to us */ +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + if (dirfd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } + rc = real_stat64( path, &buf); +#else + rc = real_fstatat64( dirfd, path, &buf, AT_SYMLINK_NOFOLLOW); +#endif + if (rc != -1) { + /* if we can stat the file, you can't mknod it */ + errno = EEXIST; + return -1; + } + if (!dev) { + errno = EINVAL; + return -1; + } +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + rc = real_open(path, O_CREAT | O_WRONLY | O_EXCL, + PSEUDO_FS_MODE(mode, 0)); +#else + rc = real_openat(dirfd, path, O_CREAT | O_WRONLY | O_EXCL, + PSEUDO_FS_MODE(mode, 0)); +#endif + if (rc == -1) { + return -1; + } + real_fchmod(rc, PSEUDO_FS_MODE(mode, 0)); + real_fstat64( rc, &buf); + /* mknod does not really open the file. We don't have + * to use wrap_close because we've never exposed this file + * descriptor to the client code. + */ + real_close(rc); + + /* mask in the mode type bits again */ + buf.st_mode = (PSEUDO_DB_MODE(buf.st_mode, mode) & 07777) | + (mode & ~07777); + buf.st_rdev = dev; + msg = pseudo_client_op(OP_MKNOD, 0, -1, dirfd, path, &buf); + if (msg && msg->result != RESULT_SUCCEED) { + errno = EPERM; + rc = -1; + } else { + /* just pretend we worked */ + rc = 0; + } + if (rc == -1) { + int save_errno = errno; +#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS + real_unlink(path); +#else + real_unlinkat(dirfd, path, AT_SYMLINK_NOFOLLOW); +#endif + errno = save_errno; + } +#else rc = wrap___xmknodat(_MKNOD_VER, dirfd, path, mode, &dev); +#endif /* return rc; * } diff --git a/ports/linux/guts/mkostemp64.c b/ports/linux/guts/mkostemp64.c index 502211b..41052c6 100644 --- a/ports/linux/guts/mkostemp64.c +++ b/ports/linux/guts/mkostemp64.c @@ -35,7 +35,11 @@ if (rc != -1) { save_errno = errno; +#ifdef __loongarch64 + if (real_fstat64(rc, &buf) != -1) { +#else if (real___fxstat64(_STAT_VER, rc, &buf) != -1) { +#endif real_fchmod(rc, PSEUDO_FS_MODE(0600, 0)); pseudo_client_op(OP_CREAT, 0, -1, -1, tmp_template, &buf); pseudo_client_op(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, &buf); diff --git a/ports/linux/guts/openat.c b/ports/linux/guts/openat.c index 656ac2b..86ad5e9 100644 --- a/ports/linux/guts/openat.c +++ b/ports/linux/guts/openat.c @@ -56,12 +56,24 @@ save_errno = errno; #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS if (flags & O_NOFOLLOW) { +#ifdef __loongarch64 + rc = real_lstat64(path,&buf); +#else rc = real___lxstat64(_STAT_VER, path, &buf); +#endif } else { +#ifdef __loongarch64 + rc = real_stat64(path,&buf); +#else rc = real___xstat64(_STAT_VER, path, &buf); +#endif } +#else +#ifdef __loongarch64 + rc = real_fstatat64(dirfd, path, &buf, (flags & O_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0); #else rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, (flags & O_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0); +#endif #endif existed = (rc != -1); if (!existed) @@ -77,12 +89,24 @@ save_errno = errno; #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS if (flags & O_NOFOLLOW) { +#ifdef __loongarch64 + rc = real_lstat64(path, &buf); +#else rc = real___lxstat64(_STAT_VER, path, &buf); +#endif } else { +#ifdef __loongarch64 + rc = real_stat64(path, &buf); +#else rc = real___xstat64(_STAT_VER, path, &buf); +#endif } +#else +#ifdef __loongarch64 + rc = real_fstatat64(dirfd, path, &buf, (flags & O_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0); #else rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, (flags & O_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0); +#endif #endif if (rc != -1 && S_ISFIFO(buf.st_mode)) { overly_magic_nonblocking = 1; @@ -135,12 +159,24 @@ #endif #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS if (flags & O_NOFOLLOW) { +#ifdef __loongarch64 + stat_rc = real_lstat64( path, &buf); +#else stat_rc = real___lxstat64(_STAT_VER, path, &buf); +#endif } else { +#ifdef __loongarch64 + stat_rc = real_stat64(path, &buf); +#else stat_rc = real___xstat64(_STAT_VER, path, &buf); +#endif } +#else +#ifdef __loongarch64 + stat_rc = real_fstatat64(dirfd, path, &buf, (flags & O_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0); #else stat_rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, (flags & O_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0); +#endif #endif pseudo_debug(PDBGF_FILE, "openat(path %s), flags %o, stat rc %d, stat mode %o\n", diff --git a/ports/linux/guts/stat.c b/ports/linux/guts/stat.c index f8c73f7..5a7b57b 100644 --- a/ports/linux/guts/stat.c +++ b/ports/linux/guts/stat.c @@ -7,8 +7,11 @@ * int stat(const char *path, struct stat *buf) * int rc = -1; */ - +#ifdef __loongarch64 + rc = wrap_fstatat(AT_FDCWD, path, buf, 0); +#else rc = wrap___fxstatat(_STAT_VER, AT_FDCWD, path, buf, 0); +#endif /* return rc; * } diff --git a/ports/linux/guts/stat64.c b/ports/linux/guts/stat64.c index d8b3f36..ee0583c 100644 --- a/ports/linux/guts/stat64.c +++ b/ports/linux/guts/stat64.c @@ -7,8 +7,11 @@ * int stat64(const char *path, struct stat *buf) * int rc = -1; */ - +#ifdef __loongarch64 + rc = wrap_fstatat64(AT_FDCWD, path, buf, 0); +#else rc = wrap___fxstatat64(_STAT_VER, AT_FDCWD, path, buf, 0); +#endif /* return rc; * } diff --git a/ports/linux/pseudo_wrappers.c b/ports/linux/pseudo_wrappers.c index 7659897..c0775b9 100644 --- a/ports/linux/pseudo_wrappers.c +++ b/ports/linux/pseudo_wrappers.c @@ -8,43 +8,75 @@ */ int pseudo_stat(const char *path, struct stat *buf) { +#ifdef __loongarch64 + return real_stat( path, buf); +#else return real___xstat(_STAT_VER, path, buf); +#endif } int pseudo_lstat(const char *path, struct stat *buf) { +#ifdef __loongarch64 + return real_lstat(path,buf); +#else return real___lxstat(_STAT_VER, path, buf); +#endif } int pseudo_fstat(int fd, struct stat *buf) { +#ifdef __loongarch64 + return real_fstat(fd,buf); +#else return real___fxstat(_STAT_VER, fd, buf); +#endif } int pseudo_stat64(const char *path, struct stat64 *buf) { +#ifdef __loongarch64 + return real_stat64(path,buf); +#else return real___xstat64(_STAT_VER, path, buf); +#endif } int pseudo_lstat64(const char *path, struct stat64 *buf) { +#ifdef __loongarch64 + return real_lstat64(path,buf); +#else return real___lxstat64(_STAT_VER, path, buf); +#endif } int pseudo_fstat64(int fd, struct stat64 *buf) { +#ifdef __loongarch64 + return real_fstat64(fd,buf); +#else return real___fxstat64(_STAT_VER, fd, buf); +#endif } /* similar thing happens with mknod */ int pseudo_mknod(const char *path, mode_t mode, dev_t dev) { +#ifdef __loongarch64 + return real_mknod(path,mode,dev); +#else return real___xmknod(_MKNOD_VER, path, mode, &dev); +#endif } int pseudo_mknodat(int dirfd, const char *path, mode_t mode, dev_t dev) { +#ifdef __loongarch64 + return real_mknodat(dirfd,path,mode,dev); +#else return real___xmknodat(_MKNOD_VER, dirfd, path, mode, &dev); +#endif } int pseudo_capset(cap_user_header_t hdrp, const cap_user_data_t datap) { diff --git a/pseudo_client.h b/pseudo_client.h index d7944ce..32dfe1a 100644 --- a/pseudo_client.h +++ b/pseudo_client.h @@ -14,13 +14,21 @@ extern void pseudo_client_linked_paths(const char *oldpath, const char *newpath) #define base_lstat real_lstat64 #define base_fstat real_fstat64 #define base_stat real_stat64 +#ifdef __loongarch64 +#define base_fstatat(dirfd, path, buf, flags) real_fstatat64( dirfd, path, buf, flags) +#else #define base_fstatat(dirfd, path, buf, flags) real___fxstatat64(_STAT_VER, dirfd, path, buf, flags) +#endif #else #define base_lstat real_lstat #define base_fstat real_fstat #define base_stat real_stat +#ifdef __loongarch64 +#define base_fstatat(dirfd, path, buf, flags) real_fstatat( dirfd, path, buf, flags +#else #define base_fstatat(dirfd, path, buf, flags) real___fxstatat(_STAT_VER, dirfd, path, buf, flags) #endif +#endif extern void pseudo_antimagic(void); extern void pseudo_magic(void); extern void pseudo_client_touchuid(void); diff --git a/templates/wrapfuncs.c b/templates/wrapfuncs.c index 93bb671..14a42e2 100644 --- a/templates/wrapfuncs.c +++ b/templates/wrapfuncs.c @@ -13,7 +13,9 @@ * script if you want to modify this. */ @body +#ifndef __loongarch64 static ${type} (*real_${name})(${decl_args}) = ${real_init}; +#endif ${maybe_skip}