Mpersify parsers of readdir and getdents syscalls
* defs.h (dirent_types): New xlat prototype. * dirent.c: Stop including "xlat/direnttypes.h". (kernel_dirent): New typedef. Mpersify it. (print_old_dirent): Use it instead of old_dirent_t. (SYS_FUNC(getdents)): Use it instead of struct kernel_dirent. Rename direnttypes to dirent_types. (SYS_FUNC(getdents64)): Move ... * dirent64.c: ... here. Rename direnttypes to dirent_types. Include "xlat/dirent_types.h". * Makefile.am (strace_SOURCES): Add dirent64.c. * xlat/direnttypes.in: Rename to xlat/dirent_types.in.
This commit is contained in:
parent
a2df1c12de
commit
a367db8e5b
@ -49,6 +49,7 @@ strace_SOURCES = \
|
||||
count.c \
|
||||
desc.c \
|
||||
dirent.c \
|
||||
dirent64.c \
|
||||
empty.h \
|
||||
epoll.c \
|
||||
evdev.c \
|
||||
|
1
defs.h
1
defs.h
@ -413,6 +413,7 @@ extern const struct xlat addrfams[];
|
||||
extern const struct xlat adjtimex_modes[];
|
||||
extern const struct xlat adjtimex_status[];
|
||||
extern const struct xlat at_flags[];
|
||||
extern const struct xlat dirent_types[];
|
||||
extern const struct xlat open_access_modes[];
|
||||
extern const struct xlat open_mode_flags[];
|
||||
extern const struct xlat resource_flags[];
|
||||
|
165
dirent.c
165
dirent.c
@ -1,29 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
|
||||
* Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
|
||||
* Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
|
||||
* Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
|
||||
* Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#include DEF_MPERS_TYPE(kernel_dirent)
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
#define D_NAME_LEN_MAX 256
|
||||
|
||||
struct kernel_dirent {
|
||||
typedef struct {
|
||||
unsigned long d_ino;
|
||||
unsigned long d_off;
|
||||
unsigned short d_reclen;
|
||||
char d_name[1];
|
||||
};
|
||||
} kernel_dirent;
|
||||
|
||||
#include MPERS_DEFS
|
||||
|
||||
#define D_NAME_LEN_MAX 256
|
||||
|
||||
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;
|
||||
kernel_dirent d;
|
||||
|
||||
if (umove_or_printaddr(tcp, addr, &d))
|
||||
return;
|
||||
@ -32,7 +58,7 @@ print_old_dirent(struct tcb *tcp, long addr)
|
||||
(unsigned long) d.d_ino, (unsigned 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(old_dirent_t, d_name), d.d_reclen);
|
||||
printpathn(tcp, addr + offsetof(kernel_dirent, d_name), d.d_reclen);
|
||||
tprints("}");
|
||||
}
|
||||
|
||||
@ -53,8 +79,6 @@ SYS_FUNC(readdir)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "xlat/direnttypes.h"
|
||||
|
||||
SYS_FUNC(getdents)
|
||||
{
|
||||
unsigned int i, len, dents = 0;
|
||||
@ -74,7 +98,7 @@ SYS_FUNC(getdents)
|
||||
/* 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))
|
||||
else if (tcp->u_rval < (int) sizeof(kernel_dirent))
|
||||
len = 0;
|
||||
else
|
||||
len = tcp->u_rval;
|
||||
@ -93,19 +117,20 @@ SYS_FUNC(getdents)
|
||||
|
||||
if (!abbrev(tcp))
|
||||
tprints("[");
|
||||
for (i = 0; len && i <= len - sizeof(struct kernel_dirent); ) {
|
||||
struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
|
||||
for (i = 0; len && i <= len - sizeof(kernel_dirent); ) {
|
||||
kernel_dirent *d = (kernel_dirent *) &buf[i];
|
||||
|
||||
if (!abbrev(tcp)) {
|
||||
int oob = d->d_reclen < sizeof(struct kernel_dirent) ||
|
||||
int oob = d->d_reclen < sizeof(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;
|
||||
d_name_len -= offsetof(kernel_dirent, d_name) + 1;
|
||||
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 ? ", " : "", d->d_ino, d->d_off, d->d_reclen);
|
||||
i ? ", " : "", (unsigned long) d->d_ino,
|
||||
(unsigned long) d->d_off, d->d_reclen);
|
||||
|
||||
if (print_quoted_string(d->d_name, d_name_len,
|
||||
QUOTE_0_TERMINATED) > 0) {
|
||||
@ -116,12 +141,12 @@ SYS_FUNC(getdents)
|
||||
if (oob)
|
||||
tprints("?");
|
||||
else
|
||||
printxval(direnttypes, buf[i + d->d_reclen - 1], "DT_???");
|
||||
printxval(dirent_types, buf[i + d->d_reclen - 1], "DT_???");
|
||||
tprints("}");
|
||||
}
|
||||
dents++;
|
||||
if (d->d_reclen < sizeof(struct kernel_dirent)) {
|
||||
tprints("/* d_reclen < sizeof(struct kernel_dirent) */");
|
||||
if (d->d_reclen < sizeof(kernel_dirent)) {
|
||||
tprints("/* d_reclen < sizeof(kernel_dirent) */");
|
||||
break;
|
||||
}
|
||||
i += d->d_reclen;
|
||||
@ -134,89 +159,3 @@ SYS_FUNC(getdents)
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_FUNC(getdents64)
|
||||
{
|
||||
/* 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)) {
|
||||
printaddr(tcp->u_arg[1]);
|
||||
tprintf(", %lu", 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 || umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
|
||||
printaddr(tcp->u_arg[1]);
|
||||
tprintf(", %lu", 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;
|
||||
}
|
||||
if (d_name_len > D_NAME_LEN_MAX)
|
||||
d_name_len = D_NAME_LEN_MAX;
|
||||
|
||||
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_???");
|
||||
|
||||
tprints(", d_name=");
|
||||
if (print_quoted_string(d->d_name, d_name_len,
|
||||
QUOTE_0_TERMINATED) > 0) {
|
||||
tprints("...");
|
||||
}
|
||||
|
||||
tprints("}");
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
123
dirent64.c
Normal file
123
dirent64.c
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
|
||||
* Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
|
||||
* Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
|
||||
* Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
|
||||
* Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
#include <dirent.h>
|
||||
|
||||
#include "xlat/dirent_types.h"
|
||||
|
||||
#define D_NAME_LEN_MAX 256
|
||||
|
||||
SYS_FUNC(getdents64)
|
||||
{
|
||||
/* 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)) {
|
||||
printaddr(tcp->u_arg[1]);
|
||||
tprintf(", %lu", 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) d_name_offset)
|
||||
len = 0;
|
||||
else
|
||||
len = tcp->u_rval;
|
||||
|
||||
if (len) {
|
||||
buf = malloc(len);
|
||||
if (!buf || umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
|
||||
printaddr(tcp->u_arg[1]);
|
||||
tprintf(", %lu", 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;
|
||||
}
|
||||
if (d_name_len > D_NAME_LEN_MAX)
|
||||
d_name_len = D_NAME_LEN_MAX;
|
||||
|
||||
tprintf("%s{d_ino=%" PRIu64 ", d_off=%" PRId64
|
||||
", d_reclen=%u, d_type=",
|
||||
i ? ", " : "",
|
||||
d->d_ino,
|
||||
d->d_off,
|
||||
d->d_reclen);
|
||||
printxval(dirent_types, d->d_type, "DT_???");
|
||||
|
||||
tprints(", d_name=");
|
||||
if (print_quoted_string(d->d_name, d_name_len,
|
||||
QUOTE_0_TERMINATED) > 0) {
|
||||
tprints("...");
|
||||
}
|
||||
|
||||
tprints("}");
|
||||
}
|
||||
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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user