Move dirent related parsers to a separate file
* dirent.c: New file. * Makefile.am (strace_SOURCES): Add it. * file.c (print_old_dirent, sys_readdir, sys_getdents, sys_getdents64): Move to dirent.c.
This commit is contained in:
parent
68d64241ac
commit
2ed2cc743d
@ -22,6 +22,7 @@ strace_SOURCES = \
|
||||
block.c \
|
||||
count.c \
|
||||
desc.c \
|
||||
dirent.c \
|
||||
fanotify.c \
|
||||
file.c \
|
||||
inotify.c \
|
||||
|
210
dirent.c
Normal file
210
dirent.c
Normal file
@ -0,0 +1,210 @@
|
||||
#include "defs.h"
|
||||
#include <dirent.h>
|
||||
|
||||
struct kernel_dirent {
|
||||
unsigned long d_ino;
|
||||
unsigned long d_off;
|
||||
unsigned short d_reclen;
|
||||
char d_name[1];
|
||||
};
|
||||
|
||||
static void
|
||||
print_old_dirent(struct tcb *tcp, long addr)
|
||||
{
|
||||
#ifdef SH64
|
||||
typedef struct kernel_dirent old_dirent_t;
|
||||
#else
|
||||
typedef struct {
|
||||
uint32_t d_ino;
|
||||
uint32_t d_off;
|
||||
unsigned short d_reclen;
|
||||
char d_name[1];
|
||||
} old_dirent_t;
|
||||
#endif
|
||||
old_dirent_t d;
|
||||
|
||||
if (!verbose(tcp) || umove(tcp, addr, &d) < 0) {
|
||||
tprintf("%#lx", addr);
|
||||
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);
|
||||
if (d.d_reclen > 256)
|
||||
d.d_reclen = 256;
|
||||
printpathn(tcp, addr + offsetof(old_dirent_t, d_name), d.d_reclen);
|
||||
tprints("\"}");
|
||||
}
|
||||
|
||||
int
|
||||
sys_readdir(struct tcb *tcp)
|
||||
{
|
||||
if (entering(tcp)) {
|
||||
printfd(tcp, tcp->u_arg[0]);
|
||||
tprints(", ");
|
||||
} else {
|
||||
if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp))
|
||||
tprintf("%#lx", tcp->u_arg[1]);
|
||||
else
|
||||
print_old_dirent(tcp, tcp->u_arg[1]);
|
||||
/* Not much point in printing this out, it is always 1. */
|
||||
if (tcp->u_arg[2] != 1)
|
||||
tprintf(", %lu", tcp->u_arg[2]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "xlat/direnttypes.h"
|
||||
|
||||
int
|
||||
sys_getdents(struct tcb *tcp)
|
||||
{
|
||||
unsigned int i, len, dents = 0;
|
||||
char *buf;
|
||||
|
||||
if (entering(tcp)) {
|
||||
printfd(tcp, tcp->u_arg[0]);
|
||||
tprints(", ");
|
||||
return 0;
|
||||
}
|
||||
if (syserror(tcp) || !verbose(tcp)) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Beware of insanely large or too small values in tcp->u_rval */
|
||||
if (tcp->u_rval > 1024*1024)
|
||||
len = 1024*1024;
|
||||
else if (tcp->u_rval < (int) sizeof(struct kernel_dirent))
|
||||
len = 0;
|
||||
else
|
||||
len = tcp->u_rval;
|
||||
|
||||
if (len) {
|
||||
buf = malloc(len);
|
||||
if (!buf)
|
||||
die_out_of_memory();
|
||||
if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
if (!abbrev(tcp))
|
||||
tprints("{");
|
||||
for (i = 0; len && i <= len - sizeof(struct kernel_dirent); ) {
|
||||
struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
|
||||
|
||||
if (!abbrev(tcp)) {
|
||||
int oob = d->d_reclen < sizeof(struct kernel_dirent) ||
|
||||
i + d->d_reclen - 1 >= len;
|
||||
int d_name_len = oob ? len - i : d->d_reclen;
|
||||
d_name_len -= offsetof(struct kernel_dirent, d_name) + 1;
|
||||
|
||||
tprintf("%s{d_ino=%lu, d_off=%lu, ",
|
||||
i ? " " : "", d->d_ino, d->d_off);
|
||||
tprintf("d_reclen=%u, d_name=\"%.*s\", d_type=",
|
||||
d->d_reclen, d_name_len, d->d_name);
|
||||
if (oob)
|
||||
tprints("?");
|
||||
else
|
||||
printxval(direnttypes, buf[i + d->d_reclen - 1], "DT_???");
|
||||
tprints("}");
|
||||
}
|
||||
dents++;
|
||||
if (d->d_reclen < sizeof(struct kernel_dirent)) {
|
||||
tprints("/* d_reclen < sizeof(struct kernel_dirent) */");
|
||||
break;
|
||||
}
|
||||
i += d->d_reclen;
|
||||
}
|
||||
if (!abbrev(tcp))
|
||||
tprints("}");
|
||||
else
|
||||
tprintf("/* %u entries */", dents);
|
||||
tprintf(", %lu", tcp->u_arg[2]);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sys_getdents64(struct tcb *tcp)
|
||||
{
|
||||
/* the minimum size of a valid dirent64 structure */
|
||||
const unsigned int d_name_offset = offsetof(struct dirent64, d_name);
|
||||
|
||||
unsigned int i, len, dents = 0;
|
||||
char *buf;
|
||||
|
||||
if (entering(tcp)) {
|
||||
printfd(tcp, tcp->u_arg[0]);
|
||||
tprints(", ");
|
||||
return 0;
|
||||
}
|
||||
if (syserror(tcp) || !verbose(tcp)) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Beware of insanely large or too small tcp->u_rval */
|
||||
if (tcp->u_rval > 1024*1024)
|
||||
len = 1024*1024;
|
||||
else if (tcp->u_rval < (int) d_name_offset)
|
||||
len = 0;
|
||||
else
|
||||
len = tcp->u_rval;
|
||||
|
||||
if (len) {
|
||||
buf = malloc(len);
|
||||
if (!buf)
|
||||
die_out_of_memory();
|
||||
if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
if (!abbrev(tcp))
|
||||
tprints("{");
|
||||
for (i = 0; len && i <= len - d_name_offset; ) {
|
||||
struct dirent64 *d = (struct dirent64 *) &buf[i];
|
||||
if (!abbrev(tcp)) {
|
||||
int d_name_len;
|
||||
if (d->d_reclen >= d_name_offset
|
||||
&& i + d->d_reclen <= len) {
|
||||
d_name_len = d->d_reclen - d_name_offset;
|
||||
} else {
|
||||
d_name_len = len - i - d_name_offset;
|
||||
}
|
||||
|
||||
tprintf("%s{d_ino=%" PRIu64 ", d_off=%" PRId64
|
||||
", d_reclen=%u, d_type=",
|
||||
i ? " " : "",
|
||||
d->d_ino,
|
||||
d->d_off,
|
||||
d->d_reclen);
|
||||
printxval(direnttypes, d->d_type, "DT_???");
|
||||
tprintf(", d_name=\"%.*s\"}",
|
||||
d_name_len, d->d_name);
|
||||
}
|
||||
if (d->d_reclen < d_name_offset) {
|
||||
tprints("/* d_reclen < offsetof(struct dirent64, d_name) */");
|
||||
break;
|
||||
}
|
||||
i += d->d_reclen;
|
||||
dents++;
|
||||
}
|
||||
if (!abbrev(tcp))
|
||||
tprints("}");
|
||||
else
|
||||
tprintf("/* %u entries */", dents);
|
||||
tprintf(", %lu", tcp->u_arg[2]);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
209
file.c
209
file.c
@ -29,7 +29,6 @@
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
#include <dirent.h>
|
||||
#include <sys/swap.h>
|
||||
|
||||
#if defined(SPARC) || defined(SPARC64)
|
||||
@ -204,13 +203,6 @@ struct __old_kernel_stat {
|
||||
# include <sys/asynch.h>
|
||||
#endif
|
||||
|
||||
struct kernel_dirent {
|
||||
unsigned long d_ino;
|
||||
unsigned long d_off;
|
||||
unsigned short d_reclen;
|
||||
char d_name[1];
|
||||
};
|
||||
|
||||
#ifdef O_LARGEFILE
|
||||
# if O_LARGEFILE == 0 /* biarch platforms in 64-bit mode */
|
||||
# undef O_LARGEFILE
|
||||
@ -2009,207 +2001,6 @@ sys_mknodat(struct tcb *tcp)
|
||||
return decode_mknod(tcp, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
print_old_dirent(struct tcb *tcp, long addr)
|
||||
{
|
||||
#ifdef SH64
|
||||
typedef struct kernel_dirent old_dirent_t;
|
||||
#else
|
||||
typedef struct {
|
||||
uint32_t d_ino;
|
||||
uint32_t d_off;
|
||||
unsigned short d_reclen;
|
||||
char d_name[1];
|
||||
} old_dirent_t;
|
||||
#endif
|
||||
old_dirent_t d;
|
||||
|
||||
if (!verbose(tcp) || umove(tcp, addr, &d) < 0) {
|
||||
tprintf("%#lx", addr);
|
||||
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);
|
||||
if (d.d_reclen > 256)
|
||||
d.d_reclen = 256;
|
||||
printpathn(tcp, addr + offsetof(old_dirent_t, d_name), d.d_reclen);
|
||||
tprints("\"}");
|
||||
}
|
||||
|
||||
int
|
||||
sys_readdir(struct tcb *tcp)
|
||||
{
|
||||
if (entering(tcp)) {
|
||||
printfd(tcp, tcp->u_arg[0]);
|
||||
tprints(", ");
|
||||
} else {
|
||||
if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp))
|
||||
tprintf("%#lx", tcp->u_arg[1]);
|
||||
else
|
||||
print_old_dirent(tcp, tcp->u_arg[1]);
|
||||
/* Not much point in printing this out, it is always 1. */
|
||||
if (tcp->u_arg[2] != 1)
|
||||
tprintf(", %lu", tcp->u_arg[2]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "xlat/direnttypes.h"
|
||||
|
||||
int
|
||||
sys_getdents(struct tcb *tcp)
|
||||
{
|
||||
unsigned int i, len, dents = 0;
|
||||
char *buf;
|
||||
|
||||
if (entering(tcp)) {
|
||||
printfd(tcp, tcp->u_arg[0]);
|
||||
tprints(", ");
|
||||
return 0;
|
||||
}
|
||||
if (syserror(tcp) || !verbose(tcp)) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Beware of insanely large or too small values in tcp->u_rval */
|
||||
if (tcp->u_rval > 1024*1024)
|
||||
len = 1024*1024;
|
||||
else if (tcp->u_rval < (int) sizeof(struct kernel_dirent))
|
||||
len = 0;
|
||||
else
|
||||
len = tcp->u_rval;
|
||||
|
||||
if (len) {
|
||||
buf = malloc(len);
|
||||
if (!buf)
|
||||
die_out_of_memory();
|
||||
if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
if (!abbrev(tcp))
|
||||
tprints("{");
|
||||
for (i = 0; len && i <= len - sizeof(struct kernel_dirent); ) {
|
||||
struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
|
||||
|
||||
if (!abbrev(tcp)) {
|
||||
int oob = d->d_reclen < sizeof(struct kernel_dirent) ||
|
||||
i + d->d_reclen - 1 >= len;
|
||||
int d_name_len = oob ? len - i : d->d_reclen;
|
||||
d_name_len -= offsetof(struct kernel_dirent, d_name) + 1;
|
||||
|
||||
tprintf("%s{d_ino=%lu, d_off=%lu, ",
|
||||
i ? " " : "", d->d_ino, d->d_off);
|
||||
tprintf("d_reclen=%u, d_name=\"%.*s\", d_type=",
|
||||
d->d_reclen, d_name_len, d->d_name);
|
||||
if (oob)
|
||||
tprints("?");
|
||||
else
|
||||
printxval(direnttypes, buf[i + d->d_reclen - 1], "DT_???");
|
||||
tprints("}");
|
||||
}
|
||||
dents++;
|
||||
if (d->d_reclen < sizeof(struct kernel_dirent)) {
|
||||
tprints("/* d_reclen < sizeof(struct kernel_dirent) */");
|
||||
break;
|
||||
}
|
||||
i += d->d_reclen;
|
||||
}
|
||||
if (!abbrev(tcp))
|
||||
tprints("}");
|
||||
else
|
||||
tprintf("/* %u entries */", dents);
|
||||
tprintf(", %lu", tcp->u_arg[2]);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sys_getdents64(struct tcb *tcp)
|
||||
{
|
||||
/* the minimum size of a valid dirent64 structure */
|
||||
const unsigned int d_name_offset = offsetof(struct dirent64, d_name);
|
||||
|
||||
unsigned int i, len, dents = 0;
|
||||
char *buf;
|
||||
|
||||
if (entering(tcp)) {
|
||||
printfd(tcp, tcp->u_arg[0]);
|
||||
tprints(", ");
|
||||
return 0;
|
||||
}
|
||||
if (syserror(tcp) || !verbose(tcp)) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Beware of insanely large or too small tcp->u_rval */
|
||||
if (tcp->u_rval > 1024*1024)
|
||||
len = 1024*1024;
|
||||
else if (tcp->u_rval < (int) d_name_offset)
|
||||
len = 0;
|
||||
else
|
||||
len = tcp->u_rval;
|
||||
|
||||
if (len) {
|
||||
buf = malloc(len);
|
||||
if (!buf)
|
||||
die_out_of_memory();
|
||||
if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
if (!abbrev(tcp))
|
||||
tprints("{");
|
||||
for (i = 0; len && i <= len - d_name_offset; ) {
|
||||
struct dirent64 *d = (struct dirent64 *) &buf[i];
|
||||
if (!abbrev(tcp)) {
|
||||
int d_name_len;
|
||||
if (d->d_reclen >= d_name_offset
|
||||
&& i + d->d_reclen <= len) {
|
||||
d_name_len = d->d_reclen - d_name_offset;
|
||||
} else {
|
||||
d_name_len = len - i - d_name_offset;
|
||||
}
|
||||
|
||||
tprintf("%s{d_ino=%" PRIu64 ", d_off=%" PRId64
|
||||
", d_reclen=%u, d_type=",
|
||||
i ? " " : "",
|
||||
d->d_ino,
|
||||
d->d_off,
|
||||
d->d_reclen);
|
||||
printxval(direnttypes, d->d_type, "DT_???");
|
||||
tprintf(", d_name=\"%.*s\"}",
|
||||
d_name_len, d->d_name);
|
||||
}
|
||||
if (d->d_reclen < d_name_offset) {
|
||||
tprints("/* d_reclen < offsetof(struct dirent64, d_name) */");
|
||||
break;
|
||||
}
|
||||
i += d->d_reclen;
|
||||
dents++;
|
||||
}
|
||||
if (!abbrev(tcp))
|
||||
tprints("}");
|
||||
else
|
||||
tprintf("/* %u entries */", dents);
|
||||
tprintf(", %lu", tcp->u_arg[2]);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sys_getcwd(struct tcb *tcp)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user