|
3 | 3 | # Cross Platform and Multi Architecture Advanced Binary Emulation Framework |
4 | 4 | # |
5 | 5 |
|
| 6 | +import os |
6 | 7 | import time |
| 8 | +import gevent |
7 | 9 |
|
8 | | -from qiling.const import * |
9 | | -from qiling.os.linux.thread import * |
10 | | -from qiling.const import * |
11 | | -from qiling.os.posix.filestruct import * |
12 | | -from qiling.os.filestruct import * |
13 | | -from qiling.os.posix.const_mapping import * |
14 | | -from qiling.exception import * |
| 10 | +from qiling import Qiling |
15 | 11 |
|
16 | | -def ql_syscall_time(ql, *args, **kw): |
17 | | - regreturn = int(time.time()) |
18 | | - return regreturn |
19 | | - |
20 | | -def ql_syscall_clock_nanosleep_time64(ql, nanosleep_clk_id, nanosleep_flags, nanosleep_req, nanosleep_rem, *args, **kw): |
21 | | - def _sched_sleep(cur_thread): |
22 | | - gevent.sleep(tv_sec) |
| 12 | +def ql_syscall_time(ql: Qiling): |
| 13 | + return int(time.time()) |
23 | 14 |
|
| 15 | +def __sleep_common(ql: Qiling, req: int, rem: int) -> int: |
24 | 16 | n = ql.pointersize |
25 | 17 |
|
26 | | - tv_sec = ql.unpack(ql.mem.read(nanosleep_req, n)) |
27 | | - tv_sec += ql.unpack(ql.mem.read(nanosleep_req + n, n)) / 1000000000 |
28 | | - |
29 | | - if ql.os.thread_management == None: |
30 | | - time.sleep(tv_sec) |
31 | | - else: |
32 | | - ql.emu_stop() |
33 | | - ql.os.thread_management.cur_thread.sched_cb = _sched_sleep |
34 | | - th = ql.os.thread_management.cur_thread |
35 | | - |
36 | | - regreturn = 0 |
37 | | - return regreturn |
| 18 | + tv_sec = ql.unpack(ql.mem.read(req, n)) |
| 19 | + tv_sec += ql.unpack(ql.mem.read(req + n, n)) / 1000000000 |
38 | 20 |
|
| 21 | + if ql.os.thread_management: |
| 22 | + def _sched_sleep(cur_thread): |
| 23 | + gevent.sleep(tv_sec) |
39 | 24 |
|
40 | | -def ql_syscall_nanosleep(ql, nanosleep_req, nanosleep_rem, *args, **kw): |
41 | | - def _sched_sleep(cur_thread): |
42 | | - gevent.sleep(tv_sec) |
43 | | - |
44 | | - n = ql.pointersize |
45 | | - |
46 | | - tv_sec = ql.unpack(ql.mem.read(nanosleep_req, n)) |
47 | | - tv_sec += ql.unpack(ql.mem.read(nanosleep_req + n, n)) / 1000000000 |
48 | | - |
49 | | - if ql.os.thread_management == None: |
50 | | - time.sleep(tv_sec) |
51 | | - else: |
52 | 25 | ql.emu_stop() |
53 | 26 | ql.os.thread_management.cur_thread.sched_cb = _sched_sleep |
54 | | - th = ql.os.thread_management.cur_thread |
55 | 27 |
|
56 | | - regreturn = 0 |
57 | | - return regreturn |
| 28 | + # FIXME: this seems to be incomplete |
| 29 | + th = ql.os.thread_management.cur_thread |
| 30 | + else: |
| 31 | + time.sleep(tv_sec) |
58 | 32 |
|
59 | | -def ql_syscall_clock_nanosleep(ql, clock_nanosleep_clockid, clock_nanosleep_flags, clock_nanosleep_req, clock_nanosleep_remain, *args, **kw): |
60 | | - def _sched_sleep(cur_thread): |
61 | | - gevent.sleep(tv_sec) |
| 33 | + return 0 |
62 | 34 |
|
63 | | - n = ql.pointersize |
| 35 | +def ql_syscall_clock_nanosleep_time64(ql: Qiling, clk_id: int, flags: int, req: int, rem: int): |
| 36 | + return __sleep_common(ql, req, rem) |
64 | 37 |
|
65 | | - tv_sec = ql.unpack(ql.mem.read(clock_nanosleep_req, n)) |
66 | | - tv_sec += ql.unpack(ql.mem.read(clock_nanosleep_req + n, n)) / 1000000000 |
| 38 | +def ql_syscall_nanosleep(ql: Qiling, req: int, rem: int): |
| 39 | + return __sleep_common(ql, req, rem) |
67 | 40 |
|
68 | | - if ql.os.thread_management == None: |
69 | | - time.sleep(tv_sec) |
70 | | - else: |
71 | | - ql.emu_stop() |
72 | | - ql.os.thread_management.cur_thread.sched_cb = _sched_sleep |
73 | | - th = ql.os.thread_management.cur_thread |
74 | | - |
75 | | - regreturn = 0 |
76 | | - return regreturn |
| 41 | +def ql_syscall_clock_nanosleep(ql: Qiling, clockid: int, flags: int, req: int, rem: int): |
| 42 | + return __sleep_common(ql, req, rem) |
77 | 43 |
|
78 | | - |
79 | | -def ql_syscall_setitimer(ql, setitimer_which, setitimer_new_value, setitimer_old_value, *args, **kw): |
| 44 | +def ql_syscall_setitimer(ql: Qiling, which: int, new_value: int, old_value: int): |
80 | 45 | # TODO:The system provides each process with three interval timers, each decrementing in a distinct time domain. |
81 | 46 | # When any timer expires, a signal is sent to the process, and the timer (potentially) restarts. |
82 | 47 | # But I haven’t figured out how to send a signal yet. |
83 | | - regreturn = 0 |
84 | | - return regreturn |
85 | | - |
86 | | - |
87 | | -def ql_syscall_times(ql, times_tbuf, *args, **kw): |
88 | | - tmp_times = os.times() |
89 | | - if times_tbuf != 0: |
90 | | - tmp_buf = b'' |
91 | | - tmp_buf += ql.pack32(int(tmp_times.user * 1000)) |
92 | | - tmp_buf += ql.pack32(int(tmp_times.system * 1000)) |
93 | | - tmp_buf += ql.pack32(int(tmp_times.children_user * 1000)) |
94 | | - tmp_buf += ql.pack32(int(tmp_times.children_system * 1000)) |
95 | | - ql.mem.write(times_tbuf, tmp_buf) |
96 | | - regreturn = int(tmp_times.elapsed * 100) |
97 | | - return regreturn |
98 | 48 |
|
| 49 | + return 0 |
| 50 | + |
| 51 | +def ql_syscall_times(ql: Qiling, tbuf: int): |
| 52 | + times = os.times() |
| 53 | + |
| 54 | + if tbuf: |
| 55 | + fields = (times.user, times.system, times.children_user, times.children_system) |
| 56 | + |
| 57 | + ql.mem.write(tbuf, b''.join(ql.pack32(int(f * 1000)) for f in fields)) |
| 58 | + |
| 59 | + return int(times.elapsed * 100) |
0 commit comments