diff options
author | Waldemar Brodkorb <wbx@openadk.org> | 2019-10-23 13:57:27 +0200 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2020-02-03 11:50:54 +0100 |
commit | 8a04c4d84c8a1a1297ec0c5cec5522112981e0c0 (patch) | |
tree | 80f637db2009956f5c5bfad7f413580af466e3e5 /ldso | |
parent | 6b21a5a5bd895e16ef57c4d0d89c806b2e0c22e8 (diff) |
csky: add statx conditionals
Similar to glibc commit
https://sourceware.org/git/?p=glibc.git;a=commit;h=6bbfc5c09fc5b5e3d4a0cddbbd4e2e457767dae7
we need to handle Linux kernel change, which removed stat64 family from default syscall set.
Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>
Signed-off-by: Waldemar Brodkorb <wbrodkorb@conet.de>
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/include/dl-syscall.h | 64 | ||||
-rw-r--r-- | ldso/ldso/csky/elfinterp.c | 10 |
2 files changed, 65 insertions, 9 deletions
diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h index 9d80c6a26..55688e1c1 100644 --- a/ldso/include/dl-syscall.h +++ b/ldso/include/dl-syscall.h @@ -36,9 +36,37 @@ extern int _dl_errno; /* 1. common-generic ABI doesn't need kernel_stat translation * 3. S_IS?ID already provided by stat.h */ +#include <fcntl.h> #include <sys/stat.h> +#include <dl-string.h> + +static __always_inline void +__cp_stat_statx (struct stat *to, struct statx *from) +{ + _dl_memset (to, 0, sizeof (struct stat)); + to->st_dev = ((from->stx_dev_minor & 0xff) | (from->stx_dev_major << 8) + | ((from->stx_dev_minor & ~0xff) << 12)); + to->st_rdev = ((from->stx_rdev_minor & 0xff) | (from->stx_rdev_major << 8) + | ((from->stx_rdev_minor & ~0xff) << 12)); + to->st_ino = from->stx_ino; + to->st_mode = from->stx_mode; + to->st_nlink = from->stx_nlink; + to->st_uid = from->stx_uid; + to->st_gid = from->stx_gid; + to->st_atime = from->stx_atime.tv_sec; + to->st_atim.tv_nsec = from->stx_atime.tv_nsec; + to->st_mtime = from->stx_mtime.tv_sec; + to->st_mtim.tv_nsec = from->stx_mtime.tv_nsec; + to->st_ctime = from->stx_ctime.tv_sec; + to->st_ctim.tv_nsec = from->stx_ctime.tv_nsec; + to->st_size = from->stx_size; + to->st_blocks = from->stx_blocks; + to->st_blksize = from->stx_blksize; +} #endif +#define AT_NO_AUTOMOUNT 0x800 +#define AT_EMPTY_PATH 0x1000 /* Here are the definitions for some syscalls that are used by the dynamic linker. The idea is that we want to be able @@ -109,14 +137,48 @@ static __always_inline int _dl_stat(const char *file_name, # define __NR__dl_stat __NR_stat static __always_inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf) + +#elif defined __NR_statx && defined __UCLIBC_HAVE_STATX__ +# define __NR__dl_statx __NR_statx +# include <fcntl.h> +# include <statx_cp.h> + +static __always_inline _syscall5(int, _dl_statx, int, fd, const char *, file_name, int, flags, + unsigned int, mask, struct statx *, buf); + +static __always_inline int _dl_stat(const char *file_name, + struct stat *buf) +{ + struct statx tmp; + int rc = _dl_statx(AT_FDCWD, file_name, AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &tmp); + if (rc == 0) + __cp_stat_statx ((struct stat *)buf, &tmp); + return rc; +} #endif #if defined __NR_fstat64 && !defined __NR_fstat # define __NR__dl_fstat __NR_fstat64 +static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf) #elif defined __NR_fstat # define __NR__dl_fstat __NR_fstat -#endif static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf) +#elif defined __NR_statx && defined __UCLIBC_HAVE_STATX__ +# define __NR__dl_fstatx __NR_statx +static __always_inline _syscall5(int, _dl_fstatx, int, fd, const char *, file_name, int, flags, unsigned int, mask, struct stat *, buf); + +static __always_inline int _dl_fstat(int fd, + struct stat *buf) +{ + struct statx tmp; + int rc = _dl_fstatx(fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS, &tmp); + if (rc == 0) + __cp_stat_statx ((struct stat *)buf, &tmp); + return rc; +} +#else +static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf) +#endif #define __NR__dl_munmap __NR_munmap static __always_inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length) diff --git a/ldso/ldso/csky/elfinterp.c b/ldso/ldso/csky/elfinterp.c index 9dba2a041..49cdaa39b 100644 --- a/ldso/ldso/csky/elfinterp.c +++ b/ldso/ldso/csky/elfinterp.c @@ -79,17 +79,11 @@ _dl_parse(struct elf_resolve *tpnt, struct r_scope_elem*scope, strtab + symtab[symtab_index].st_name); if (unlikely(res < 0)) { int reloc_type = ELF32_R_TYPE(rpnt->r_info); - -#if defined (__SUPPORT_LD_DEBUG__) - _dl_dprintf(2, "2can't handle reloc type '%s' in lib '%s'\n", - _dl_reltypes(reloc_type), tpnt->libname); -#else - _dl_dprintf(2, "3can't handle reloc type %x in lib '%s'\n", + _dl_dprintf(2, "2can't handle reloc type %x in lib '%s'\n", reloc_type, tpnt->libname); -#endif return res; } else if (unlikely(res > 0)) { - _dl_dprintf(2, "4can't resolve symbol in lib '%s'.\n", tpnt->libname); + _dl_dprintf(2, "3can't resolve symbol in lib '%s'.\n", tpnt->libname); return res; } } |