Skip to content

Commit 6b47181

Browse files
committed
Alpha version of utimensat, more utime calls incoming
1 parent bae754d commit 6b47181

File tree

6 files changed

+103
-38
lines changed

6 files changed

+103
-38
lines changed

examples/src/linux/Makefile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ TARGETS = \
2323
arm64_hello_static \
2424
arm64_sleep_hello \
2525
mips32el_hello \
26-
mips32el_hello_static \
27-
x86_hello \
26+
mips32el_hello_static \
27+
x86_hello \
2828
x86_hello_static \
2929
x86_hello_cpp \
30-
x86_hello_cpp_static \
30+
x86_hello_cpp_static \
31+
x86_linux_utime \
3132
x8664_hello \
3233
x8664_hello_static \
3334
x8664_hello_cpp \
@@ -127,7 +128,9 @@ x8664_epoll_0: x8664_epoll_0.c
127128
x8664_onestraw_server: x8664_onestraw_server.c
128129
$(CC) $(CPPFLAGS) $(CFLAGS) -m64 -static -o $@ $<
129130
x8664_linux_utime: x8664_linux_utime.c
130-
$(CC) $(CPPFLAGS) $(CFLAGS) -m64 -o $@ $<
131+
$(CC) $(CPPFLAGS) $(CFLAGS) -m64 -o $@ $<
132+
x86_linux_utime: x8664_linux_utime.c
133+
$(CC) $(CPPFLAGS) $(CFLAGS) -m32 -o x86_linux_utime $<
131134

132135

133136
libpatch_test.so: patch_test.so.h patch_test.so.c

examples/src/linux/hello_mips32.s

Lines changed: 0 additions & 16 deletions
This file was deleted.

examples/src/linux/hello_riscv.s

Lines changed: 0 additions & 16 deletions
This file was deleted.

qiling/os/linux/syscall.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
from qiling import Qiling
77
from qiling.arch.x86_const import *
88
from qiling.const import QL_ARCH
9-
9+
from qiling.os import struct
10+
from qiling.os.posix.structs import *
1011
from datetime import datetime
1112
from math import floor
1213
import ctypes
14+
import os
1315

1416
def __get_timespec_struct(archbits: int):
1517
long = getattr(ctypes, f'c_int{archbits}')
@@ -90,3 +92,68 @@ def ql_syscall_gettimeofday(ql: Qiling, tv: int, tz: int):
9092
ql.mem.write(tz, b'\x00' * 8)
9193

9294
return 0
95+
96+
'''
97+
TODO
98+
int futimens(int fd, const struct timespec times[_Nullable 2]);
99+
100+
'''
101+
102+
'''
103+
TODO
104+
int utime(const char *filename,
105+
const struct utimbuf *_Nullable times);
106+
107+
'''
108+
109+
'''
110+
TODO: This is considered deprecated,
111+
but should there be a wrapper added for legacy code?
112+
int futimesat(int dirfd, const char *pathname,
113+
const struct timeval times[2]);
114+
115+
'''
116+
117+
'''
118+
TODO: int utimes(const char *filename,
119+
const struct timeval times[_Nullable 2]);
120+
121+
'''
122+
123+
'''
124+
sys_utimensat int dfd const char *filename struct timespec *utimes int flags
125+
'''
126+
def ql_syscall_utimensat(ql:qiling.Qiling, dfd: int, filename:POINTER, utimes: POINTER, flags: int):
127+
path = ''
128+
if dfd == AT_FDCWD:
129+
ql.emu_stop()
130+
ql.log.debug("inside hook")
131+
if filename == 0:
132+
return EACCES
133+
if utimes == 0:
134+
return EACCES
135+
ql.log.debug(hex(filename))
136+
unpacked_filename = ql.mem.string(filename)
137+
if unpacked_filename.find("/") == 0: # starts with /, assumed to be absolute path
138+
dfd = None
139+
timespec_struct = make_timespec_buf(ql.arch.bits, ql.arch.endian)
140+
atime_nsec = mtime_nsec = atime_sec = mtime_sec = 0
141+
with timespec_struct.ref(ql.mem, utimes) as atime_ref:
142+
atime_nsec = atime_ref.tv_nsec
143+
atime_sec = atime_ref.tv_sec
144+
with timespec_struct.ref(ql.mem, utimes+ctypes.sizeof(timespec_struct)) as mtime_ref:
145+
mtime_nsec = mtime_ref.tv_nsec
146+
mtime_sec = mtime_ref.tv_sec
147+
ql.log.debug(f"Got filename {unpacked_filename} for utime syscall ")
148+
try:
149+
follow_symlink = True
150+
if flags == AT_SYMLINK_NOFOLLOW:
151+
follow_symlink = False
152+
os.utime(unpacked_filename, ns=(atime_nsec, mtime_nsec), dir_fd=dfd, follow_symlinks=follow_symlink)
153+
os.utime(unpacked_filename, (atime_sec, mtime_sec), dir_fd=dfd, follow_symlinks=follow_symlink)
154+
except Exception as ex:
155+
return -ex.errno
156+
return 0
157+
158+
159+

qiling/os/posix/const.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1083,4 +1083,7 @@ class qnx_mmap_prot_flags(QlPrettyFlag):
10831083
EPOLLWAKEUP = 1 << 29
10841084
EPOLLONESHOT = 1 << 30
10851085
EPOLLET = 1 << 31
1086-
EPOLL_CLOEXEC = 0x02000000
1086+
EPOLL_CLOEXEC = 0x02000000
1087+
1088+
# fcntl
1089+
AT_SYMLINK_NOFOLLOW = 0x100

qiling/os/posix/structs.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,27 @@ class pollfd(Struct):
143143
)
144144

145145
return pollfd
146+
147+
def make_utimbuf(archbits: int, endian: QL_ENDIAN):
148+
Struct = struct.get_aligned_struct(archbits, endian)
149+
class utimbuf(Struct):
150+
if archbits == 32:
151+
_fields_ = (
152+
('actime', ctypes.c_int32),
153+
('modtime', ctypes.c_int32)
154+
)
155+
else:
156+
_fields_ = (
157+
('actime', ctypes.c_int64),
158+
('modtime', ctypes.c_int64)
159+
)
160+
return utimbuf
161+
162+
def make_timespec_buf(archbits: int, endian: QL_ENDIAN):
163+
Struct = struct.get_aligned_struct(archbits, endian)
164+
class timespec(Struct):
165+
_fields_ = (
166+
('tv_sec', ctypes.c_long),
167+
('tv_nsec', ctypes.c_long)
168+
)
169+
return timespec

0 commit comments

Comments
 (0)