Skip to content

Commit a367db8

Browse files
committed
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.
1 parent a2df1c1 commit a367db8

File tree

5 files changed

+177
-113
lines changed

5 files changed

+177
-113
lines changed

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ strace_SOURCES = \
4949
count.c \
5050
desc.c \
5151
dirent.c \
52+
dirent64.c \
5253
empty.h \
5354
epoll.c \
5455
evdev.c \

defs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ extern const struct xlat addrfams[];
413413
extern const struct xlat adjtimex_modes[];
414414
extern const struct xlat adjtimex_status[];
415415
extern const struct xlat at_flags[];
416+
extern const struct xlat dirent_types[];
416417
extern const struct xlat open_access_modes[];
417418
extern const struct xlat open_mode_flags[];
418419
extern const struct xlat resource_flags[];

dirent.c

Lines changed: 52 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,55 @@
1+
/*
2+
* Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3+
* Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4+
* Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5+
* Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6+
* Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
7+
* All rights reserved.
8+
*
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions
11+
* are met:
12+
* 1. Redistributions of source code must retain the above copyright
13+
* notice, this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright
15+
* notice, this list of conditions and the following disclaimer in the
16+
* documentation and/or other materials provided with the distribution.
17+
* 3. The name of the author may not be used to endorse or promote products
18+
* derived from this software without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23+
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
132
#include "defs.h"
2-
#include <dirent.h>
333

4-
#define D_NAME_LEN_MAX 256
34+
#include DEF_MPERS_TYPE(kernel_dirent)
35+
36+
#include <dirent.h>
537

6-
struct kernel_dirent {
38+
typedef struct {
739
unsigned long d_ino;
840
unsigned long d_off;
941
unsigned short d_reclen;
1042
char d_name[1];
11-
};
43+
} kernel_dirent;
44+
45+
#include MPERS_DEFS
46+
47+
#define D_NAME_LEN_MAX 256
1248

1349
static void
1450
print_old_dirent(struct tcb *tcp, long addr)
1551
{
16-
#ifdef SH64
17-
typedef struct kernel_dirent old_dirent_t;
18-
#else
19-
typedef struct {
20-
uint32_t d_ino;
21-
uint32_t d_off;
22-
unsigned short d_reclen;
23-
char d_name[1];
24-
} old_dirent_t;
25-
#endif
26-
old_dirent_t d;
52+
kernel_dirent d;
2753

2854
if (umove_or_printaddr(tcp, addr, &d))
2955
return;
@@ -32,7 +58,7 @@ print_old_dirent(struct tcb *tcp, long addr)
3258
(unsigned long) d.d_ino, (unsigned long) d.d_off, d.d_reclen);
3359
if (d.d_reclen > D_NAME_LEN_MAX)
3460
d.d_reclen = D_NAME_LEN_MAX;
35-
printpathn(tcp, addr + offsetof(old_dirent_t, d_name), d.d_reclen);
61+
printpathn(tcp, addr + offsetof(kernel_dirent, d_name), d.d_reclen);
3662
tprints("}");
3763
}
3864

@@ -53,8 +79,6 @@ SYS_FUNC(readdir)
5379
return 0;
5480
}
5581

56-
#include "xlat/direnttypes.h"
57-
5882
SYS_FUNC(getdents)
5983
{
6084
unsigned int i, len, dents = 0;
@@ -74,7 +98,7 @@ SYS_FUNC(getdents)
7498
/* Beware of insanely large or too small values in tcp->u_rval */
7599
if (tcp->u_rval > 1024*1024)
76100
len = 1024*1024;
77-
else if (tcp->u_rval < (int) sizeof(struct kernel_dirent))
101+
else if (tcp->u_rval < (int) sizeof(kernel_dirent))
78102
len = 0;
79103
else
80104
len = tcp->u_rval;
@@ -93,19 +117,20 @@ SYS_FUNC(getdents)
93117

94118
if (!abbrev(tcp))
95119
tprints("[");
96-
for (i = 0; len && i <= len - sizeof(struct kernel_dirent); ) {
97-
struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
120+
for (i = 0; len && i <= len - sizeof(kernel_dirent); ) {
121+
kernel_dirent *d = (kernel_dirent *) &buf[i];
98122

99123
if (!abbrev(tcp)) {
100-
int oob = d->d_reclen < sizeof(struct kernel_dirent) ||
124+
int oob = d->d_reclen < sizeof(kernel_dirent) ||
101125
i + d->d_reclen - 1 >= len;
102126
int d_name_len = oob ? len - i : d->d_reclen;
103-
d_name_len -= offsetof(struct kernel_dirent, d_name) + 1;
127+
d_name_len -= offsetof(kernel_dirent, d_name) + 1;
104128
if (d_name_len > D_NAME_LEN_MAX)
105129
d_name_len = D_NAME_LEN_MAX;
106130

107131
tprintf("%s{d_ino=%lu, d_off=%lu, d_reclen=%u, d_name=",
108-
i ? ", " : "", d->d_ino, d->d_off, d->d_reclen);
132+
i ? ", " : "", (unsigned long) d->d_ino,
133+
(unsigned long) d->d_off, d->d_reclen);
109134

110135
if (print_quoted_string(d->d_name, d_name_len,
111136
QUOTE_0_TERMINATED) > 0) {
@@ -116,101 +141,15 @@ SYS_FUNC(getdents)
116141
if (oob)
117142
tprints("?");
118143
else
119-
printxval(direnttypes, buf[i + d->d_reclen - 1], "DT_???");
144+
printxval(dirent_types, buf[i + d->d_reclen - 1], "DT_???");
120145
tprints("}");
121146
}
122147
dents++;
123-
if (d->d_reclen < sizeof(struct kernel_dirent)) {
124-
tprints("/* d_reclen < sizeof(struct kernel_dirent) */");
125-
break;
126-
}
127-
i += d->d_reclen;
128-
}
129-
if (!abbrev(tcp))
130-
tprints("]");
131-
else
132-
tprintf("/* %u entries */", dents);
133-
tprintf(", %lu", tcp->u_arg[2]);
134-
free(buf);
135-
return 0;
136-
}
137-
138-
SYS_FUNC(getdents64)
139-
{
140-
/* the minimum size of a valid dirent64 structure */
141-
const unsigned int d_name_offset = offsetof(struct dirent64, d_name);
142-
143-
unsigned int i, len, dents = 0;
144-
char *buf;
145-
146-
if (entering(tcp)) {
147-
printfd(tcp, tcp->u_arg[0]);
148-
tprints(", ");
149-
return 0;
150-
}
151-
if (syserror(tcp) || !verbose(tcp)) {
152-
printaddr(tcp->u_arg[1]);
153-
tprintf(", %lu", tcp->u_arg[2]);
154-
return 0;
155-
}
156-
157-
/* Beware of insanely large or too small tcp->u_rval */
158-
if (tcp->u_rval > 1024*1024)
159-
len = 1024*1024;
160-
else if (tcp->u_rval < (int) d_name_offset)
161-
len = 0;
162-
else
163-
len = tcp->u_rval;
164-
165-
if (len) {
166-
buf = malloc(len);
167-
if (!buf || umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
168-
printaddr(tcp->u_arg[1]);
169-
tprintf(", %lu", tcp->u_arg[2]);
170-
free(buf);
171-
return 0;
172-
}
173-
} else {
174-
buf = NULL;
175-
}
176-
177-
if (!abbrev(tcp))
178-
tprints("[");
179-
for (i = 0; len && i <= len - d_name_offset; ) {
180-
struct dirent64 *d = (struct dirent64 *) &buf[i];
181-
if (!abbrev(tcp)) {
182-
int d_name_len;
183-
if (d->d_reclen >= d_name_offset
184-
&& i + d->d_reclen <= len) {
185-
d_name_len = d->d_reclen - d_name_offset;
186-
} else {
187-
d_name_len = len - i - d_name_offset;
188-
}
189-
if (d_name_len > D_NAME_LEN_MAX)
190-
d_name_len = D_NAME_LEN_MAX;
191-
192-
tprintf("%s{d_ino=%" PRIu64 ", d_off=%" PRId64
193-
", d_reclen=%u, d_type=",
194-
i ? ", " : "",
195-
d->d_ino,
196-
d->d_off,
197-
d->d_reclen);
198-
printxval(direnttypes, d->d_type, "DT_???");
199-
200-
tprints(", d_name=");
201-
if (print_quoted_string(d->d_name, d_name_len,
202-
QUOTE_0_TERMINATED) > 0) {
203-
tprints("...");
204-
}
205-
206-
tprints("}");
207-
}
208-
if (d->d_reclen < d_name_offset) {
209-
tprints("/* d_reclen < offsetof(struct dirent64, d_name) */");
148+
if (d->d_reclen < sizeof(kernel_dirent)) {
149+
tprints("/* d_reclen < sizeof(kernel_dirent) */");
210150
break;
211151
}
212152
i += d->d_reclen;
213-
dents++;
214153
}
215154
if (!abbrev(tcp))
216155
tprints("]");

dirent64.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3+
* Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4+
* Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5+
* Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6+
* Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
7+
* All rights reserved.
8+
*
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions
11+
* are met:
12+
* 1. Redistributions of source code must retain the above copyright
13+
* notice, this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright
15+
* notice, this list of conditions and the following disclaimer in the
16+
* documentation and/or other materials provided with the distribution.
17+
* 3. The name of the author may not be used to endorse or promote products
18+
* derived from this software without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23+
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
#include "defs.h"
33+
#include <dirent.h>
34+
35+
#include "xlat/dirent_types.h"
36+
37+
#define D_NAME_LEN_MAX 256
38+
39+
SYS_FUNC(getdents64)
40+
{
41+
/* the minimum size of a valid dirent64 structure */
42+
const unsigned int d_name_offset = offsetof(struct dirent64, d_name);
43+
44+
unsigned int i, len, dents = 0;
45+
char *buf;
46+
47+
if (entering(tcp)) {
48+
printfd(tcp, tcp->u_arg[0]);
49+
tprints(", ");
50+
return 0;
51+
}
52+
if (syserror(tcp) || !verbose(tcp)) {
53+
printaddr(tcp->u_arg[1]);
54+
tprintf(", %lu", tcp->u_arg[2]);
55+
return 0;
56+
}
57+
58+
/* Beware of insanely large or too small values in tcp->u_rval */
59+
if (tcp->u_rval > 1024*1024)
60+
len = 1024*1024;
61+
else if (tcp->u_rval < (int) d_name_offset)
62+
len = 0;
63+
else
64+
len = tcp->u_rval;
65+
66+
if (len) {
67+
buf = malloc(len);
68+
if (!buf || umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
69+
printaddr(tcp->u_arg[1]);
70+
tprintf(", %lu", tcp->u_arg[2]);
71+
free(buf);
72+
return 0;
73+
}
74+
} else {
75+
buf = NULL;
76+
}
77+
78+
if (!abbrev(tcp))
79+
tprints("[");
80+
for (i = 0; len && i <= len - d_name_offset; ) {
81+
struct dirent64 *d = (struct dirent64 *) &buf[i];
82+
if (!abbrev(tcp)) {
83+
int d_name_len;
84+
if (d->d_reclen >= d_name_offset
85+
&& i + d->d_reclen <= len) {
86+
d_name_len = d->d_reclen - d_name_offset;
87+
} else {
88+
d_name_len = len - i - d_name_offset;
89+
}
90+
if (d_name_len > D_NAME_LEN_MAX)
91+
d_name_len = D_NAME_LEN_MAX;
92+
93+
tprintf("%s{d_ino=%" PRIu64 ", d_off=%" PRId64
94+
", d_reclen=%u, d_type=",
95+
i ? ", " : "",
96+
d->d_ino,
97+
d->d_off,
98+
d->d_reclen);
99+
printxval(dirent_types, d->d_type, "DT_???");
100+
101+
tprints(", d_name=");
102+
if (print_quoted_string(d->d_name, d_name_len,
103+
QUOTE_0_TERMINATED) > 0) {
104+
tprints("...");
105+
}
106+
107+
tprints("}");
108+
}
109+
if (d->d_reclen < d_name_offset) {
110+
tprints("/* d_reclen < offsetof(struct dirent64, d_name) */");
111+
break;
112+
}
113+
i += d->d_reclen;
114+
dents++;
115+
}
116+
if (!abbrev(tcp))
117+
tprints("]");
118+
else
119+
tprintf("/* %u entries */", dents);
120+
tprintf(", %lu", tcp->u_arg[2]);
121+
free(buf);
122+
return 0;
123+
}

0 commit comments

Comments
 (0)