x32: fix struct dirent decoding
* kernel_types.h: New file. * Makefile.am (strace_SOURCES): Add it. * configure.ac (AC_CHECK_TYPES): Check for __kernel_long_t and __kernel_ulong_t in <asm/posix_types.h>. * dirent.c: Stop including <dirent.h>. (kernel_dirent): Remove. Include "kernel_types.h". (print_old_dirent, SYS_FUNC(getdents)): Print variables of kernel_ulong_t type using %Lu format. * syscall.c (kernel_long_t, kernel_ulong_t): Remove. Include "kernel_types.h". * tests/getdents.c (kernel_dirent): Remove. Include "kernel_types.h". (print_dirent): Print variables of kernel_ulong_t type using %Lu format.
This commit is contained in:
parent
a2fdfe96d5
commit
bdb07e38dd
@ -86,6 +86,7 @@ strace_SOURCES = \
|
||||
ipc_shm.c \
|
||||
ipc_shmctl.c \
|
||||
kcmp.c \
|
||||
kernel_types.h \
|
||||
kexec.c \
|
||||
keyctl.c \
|
||||
ldt.c \
|
||||
|
@ -343,6 +343,8 @@ AC_CHECK_TYPES([struct flock,
|
||||
struct __kernel_flock,
|
||||
struct __kernel_flock64],,, [#include <linux/fcntl.h>])
|
||||
|
||||
AC_CHECK_TYPES([__kernel_long_t, __kernel_ulong_t],,, [#include <asm/posix_types.h>])
|
||||
|
||||
AC_CHECK_MEMBERS([struct timex.tai],,, [#include <sys/timex.h>])
|
||||
|
||||
AC_CHECK_HEADERS([linux/input.h], [
|
||||
|
23
dirent.c
23
dirent.c
@ -33,14 +33,7 @@
|
||||
|
||||
#include DEF_MPERS_TYPE(kernel_dirent)
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned long d_ino;
|
||||
unsigned long d_off;
|
||||
unsigned short d_reclen;
|
||||
char d_name[1];
|
||||
} kernel_dirent;
|
||||
#include "kernel_types.h"
|
||||
|
||||
#include MPERS_DEFS
|
||||
|
||||
@ -54,8 +47,9 @@ print_old_dirent(struct tcb *tcp, long addr)
|
||||
if (umove_or_printaddr(tcp, addr, &d))
|
||||
return;
|
||||
|
||||
tprintf("{d_ino=%lu, d_off=%lu, d_reclen=%u, d_name=",
|
||||
(unsigned long) d.d_ino, (unsigned long) d.d_off, d.d_reclen);
|
||||
tprintf("{d_ino=%Lu, d_off=%Lu, d_reclen=%u, d_name=",
|
||||
(unsigned long long) d.d_ino,
|
||||
(unsigned long long) d.d_off, d.d_reclen);
|
||||
if (d.d_reclen > D_NAME_LEN_MAX)
|
||||
d.d_reclen = D_NAME_LEN_MAX;
|
||||
printpathn(tcp, addr + offsetof(kernel_dirent, d_name), d.d_reclen);
|
||||
@ -128,9 +122,10 @@ SYS_FUNC(getdents)
|
||||
if (d_name_len > D_NAME_LEN_MAX)
|
||||
d_name_len = D_NAME_LEN_MAX;
|
||||
|
||||
tprintf("%s{d_ino=%lu, d_off=%lu, d_reclen=%u, d_name=",
|
||||
i ? ", " : "", (unsigned long) d->d_ino,
|
||||
(unsigned long) d->d_off, d->d_reclen);
|
||||
tprintf("%s{d_ino=%Lu, d_off=%Lu, d_reclen=%u"
|
||||
", d_name=", i ? ", " : "",
|
||||
(unsigned long long) d->d_ino,
|
||||
(unsigned long long) d->d_off, d->d_reclen);
|
||||
|
||||
if (print_quoted_string(d->d_name, d_name_len,
|
||||
QUOTE_0_TERMINATED) > 0) {
|
||||
@ -146,7 +141,7 @@ SYS_FUNC(getdents)
|
||||
}
|
||||
dents++;
|
||||
if (d->d_reclen < sizeof(kernel_dirent)) {
|
||||
tprints("/* d_reclen < sizeof(kernel_dirent) */");
|
||||
tprints("/* d_reclen < sizeof(struct dirent) */");
|
||||
break;
|
||||
}
|
||||
i += d->d_reclen;
|
||||
|
25
kernel_types.h
Normal file
25
kernel_types.h
Normal file
@ -0,0 +1,25 @@
|
||||
#if defined HAVE___KERNEL_LONG_T && defined HAVE___KERNEL_ULONG_T
|
||||
|
||||
#include <asm/posix_types.h>
|
||||
|
||||
typedef __kernel_long_t kernel_long_t;
|
||||
typedef __kernel_ulong_t kernel_ulong_t;
|
||||
|
||||
#elif defined __x86_64__ && defined __ILP32__
|
||||
|
||||
typedef long long kernel_long_t;
|
||||
typedef unsigned long long kernel_ulong_t;
|
||||
|
||||
#else
|
||||
|
||||
typedef long kernel_long_t;
|
||||
typedef unsigned long kernel_ulong_t;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
kernel_ulong_t d_ino;
|
||||
kernel_ulong_t d_off;
|
||||
unsigned short d_reclen;
|
||||
char d_name[1];
|
||||
} kernel_dirent;
|
17
syscall.c
17
syscall.c
@ -1156,22 +1156,7 @@ restore_cleared_syserror(struct tcb *tcp)
|
||||
tcp->u_error = saved_u_error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cannot rely on __kernel_[u]long_t being defined,
|
||||
* it is quite a recent feature of <asm/posix_types.h>.
|
||||
*/
|
||||
#ifdef __kernel_long_t
|
||||
typedef __kernel_long_t kernel_long_t;
|
||||
typedef __kernel_ulong_t kernel_ulong_t;
|
||||
#else
|
||||
# ifdef X32
|
||||
typedef long long kernel_long_t;
|
||||
typedef unsigned long long kernel_ulong_t;
|
||||
# else
|
||||
typedef long kernel_long_t;
|
||||
typedef unsigned long kernel_ulong_t;
|
||||
# endif
|
||||
#endif
|
||||
#include "kernel_types.h"
|
||||
|
||||
/*
|
||||
* Check the syscall return value register value for whether it is
|
||||
|
@ -41,6 +41,8 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "kernel_types.h"
|
||||
|
||||
static const char fname[] =
|
||||
"A\nA\nA\nA\nA\nA\nA\nA\nA\nA\nA\nA\nA\nA\nA\nA\n"
|
||||
"A\nA\nA\nA\nA\nA\nA\nA\nA\nA\nA\nA\nA\nA\nA\nA\n"
|
||||
@ -60,13 +62,6 @@ static const char qname[] =
|
||||
"A\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\n"
|
||||
"A\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nA\\nZ";
|
||||
|
||||
typedef struct {
|
||||
unsigned long d_ino;
|
||||
unsigned long d_off;
|
||||
unsigned short d_reclen;
|
||||
char d_name[256];
|
||||
} kernel_dirent;
|
||||
|
||||
static char buf[8192];
|
||||
|
||||
static const char *
|
||||
@ -88,8 +83,9 @@ print_dirent(const kernel_dirent *d)
|
||||
int d_name_len = d->d_reclen - d_name_offset - 1;
|
||||
assert(d_name_len > 0);
|
||||
|
||||
printf("{d_ino=%lu, d_off=%lu, d_reclen=%u, d_name=",
|
||||
d->d_ino, d->d_off, d->d_reclen);
|
||||
printf("{d_ino=%Lu, d_off=%Lu, d_reclen=%u, d_name=",
|
||||
(unsigned long long) d->d_ino,
|
||||
(unsigned long long) d->d_off, d->d_reclen);
|
||||
|
||||
if (d->d_name[0] == '.')
|
||||
printf("\"%.*s\"", d_name_len, d->d_name);
|
||||
|
Loading…
x
Reference in New Issue
Block a user