strace: Move poll/select syscall handling to an "event" file.
Also bring along the type handlers, and use FlagsTypeHandler.
This commit is contained in:
@@ -21,6 +21,7 @@ local straceSources =
|
|||||||
MemoryReader.cpp
|
MemoryReader.cpp
|
||||||
|
|
||||||
area.cpp
|
area.cpp
|
||||||
|
events.cpp
|
||||||
exec.cpp
|
exec.cpp
|
||||||
fcntl.cpp
|
fcntl.cpp
|
||||||
ioctl.cpp
|
ioctl.cpp
|
||||||
|
|||||||
@@ -101,68 +101,6 @@ TypeHandlerImpl<iovec *>::GetReturnValue(Context &context, uint64 value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static string
|
|
||||||
read_fdset(Context &context, void *data)
|
|
||||||
{
|
|
||||||
// default FD_SETSIZE is 1024
|
|
||||||
unsigned long tmp[1024 / (sizeof(unsigned long) * 8)];
|
|
||||||
int32 bytesRead;
|
|
||||||
|
|
||||||
status_t err = context.Reader().Read(data, &tmp, sizeof(tmp), bytesRead);
|
|
||||||
if (err != B_OK)
|
|
||||||
return context.FormatPointer(data);
|
|
||||||
|
|
||||||
/* implicitly align to unsigned long lower boundary */
|
|
||||||
int count = bytesRead / sizeof(unsigned long);
|
|
||||||
int added = 0;
|
|
||||||
|
|
||||||
string r;
|
|
||||||
r.reserve(16);
|
|
||||||
|
|
||||||
r = "[";
|
|
||||||
|
|
||||||
for (int i = 0; i < count && added < 8; i++) {
|
|
||||||
for (int j = 0;
|
|
||||||
j < (int)(sizeof(unsigned long) * 8) && added < 8; j++) {
|
|
||||||
if (tmp[i] & (1UL << j)) {
|
|
||||||
if (added > 0)
|
|
||||||
r += " ";
|
|
||||||
unsigned int fd = i * sizeof(unsigned long) * 8 + j;
|
|
||||||
r += format_number(fd);
|
|
||||||
added++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (added >= 8)
|
|
||||||
r += " ...";
|
|
||||||
|
|
||||||
r += "]";
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<>
|
|
||||||
string
|
|
||||||
TypeHandlerImpl<fd_set *>::GetParameterValue(Context &context, Parameter *,
|
|
||||||
const void *address)
|
|
||||||
{
|
|
||||||
void *data = *(void **)address;
|
|
||||||
if (data != NULL && context.GetContents(Context::SIMPLE_STRUCTS))
|
|
||||||
return read_fdset(context, data);
|
|
||||||
return context.FormatPointer(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<>
|
|
||||||
string
|
|
||||||
TypeHandlerImpl<fd_set *>::GetReturnValue(Context &context, uint64 value)
|
|
||||||
{
|
|
||||||
return context.FormatPointer((void *)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static string
|
static string
|
||||||
format_ltype(Context &context, int ltype)
|
format_ltype(Context &context, int ltype)
|
||||||
{
|
{
|
||||||
@@ -219,127 +157,6 @@ format_pointer(Context &context, flock *lock)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static string
|
|
||||||
format_signed_number(int32 value)
|
|
||||||
{
|
|
||||||
char tmp[32];
|
|
||||||
snprintf(tmp, sizeof(tmp), "%d", (signed int)value);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static string
|
|
||||||
read_pollfd(Context &context, void *data)
|
|
||||||
{
|
|
||||||
nfds_t numfds = context.ReadValue<nfds_t>(context.GetSibling(1));
|
|
||||||
if ((int64)numfds <= 0)
|
|
||||||
return string();
|
|
||||||
|
|
||||||
pollfd tmp[numfds];
|
|
||||||
int32 bytesRead;
|
|
||||||
|
|
||||||
status_t err = context.Reader().Read(data, &tmp, sizeof(tmp), bytesRead);
|
|
||||||
if (err != B_OK)
|
|
||||||
return context.FormatPointer(data);
|
|
||||||
|
|
||||||
int added = 0;
|
|
||||||
|
|
||||||
string r;
|
|
||||||
r.reserve(16);
|
|
||||||
|
|
||||||
r = "[";
|
|
||||||
|
|
||||||
for (nfds_t i = 0; i < numfds && added < 8; i++) {
|
|
||||||
if ((tmp[i].fd == -1 || tmp[i].revents == 0)
|
|
||||||
&& context.GetContents(Context::OUTPUT_VALUES)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (added > 0)
|
|
||||||
r += ", ";
|
|
||||||
r += "{fd=" + format_signed_number(tmp[i].fd);
|
|
||||||
if (tmp[i].fd != -1 && context.GetContents(Context::INPUT_VALUES)) {
|
|
||||||
r += ", events=";
|
|
||||||
int flags = 0;
|
|
||||||
if ((tmp[i].events & POLLIN) != 0) {
|
|
||||||
if (flags > 0)
|
|
||||||
r += "|";
|
|
||||||
r += "POLLIN";
|
|
||||||
flags++;
|
|
||||||
}
|
|
||||||
if ((tmp[i].events & POLLOUT) != 0) {
|
|
||||||
if (flags > 0)
|
|
||||||
r += "|";
|
|
||||||
r += "POLLOUT";
|
|
||||||
flags++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (context.GetContents(Context::OUTPUT_VALUES)) {
|
|
||||||
r += ", revents=";
|
|
||||||
int flags = 0;
|
|
||||||
if ((tmp[i].revents & POLLIN) != 0) {
|
|
||||||
if (flags > 0)
|
|
||||||
r += "|";
|
|
||||||
r += "POLLIN";
|
|
||||||
flags++;
|
|
||||||
}
|
|
||||||
if ((tmp[i].revents & POLLOUT) != 0) {
|
|
||||||
if (flags > 0)
|
|
||||||
r += "|";
|
|
||||||
r += "POLLOUT";
|
|
||||||
flags++;
|
|
||||||
}
|
|
||||||
if ((tmp[i].revents & POLLERR) != 0) {
|
|
||||||
if (flags > 0)
|
|
||||||
r += "|";
|
|
||||||
r += "POLLERR";
|
|
||||||
flags++;
|
|
||||||
}
|
|
||||||
if ((tmp[i].revents & POLLHUP) != 0) {
|
|
||||||
if (flags > 0)
|
|
||||||
r += "|";
|
|
||||||
r += "POLLHUP";
|
|
||||||
flags++;
|
|
||||||
}
|
|
||||||
if ((tmp[i].revents & POLLNVAL) != 0) {
|
|
||||||
if (flags > 0)
|
|
||||||
r += "|";
|
|
||||||
r += "POLLNVAL";
|
|
||||||
flags++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
added++;
|
|
||||||
r += "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (added >= 8)
|
|
||||||
r += " ...";
|
|
||||||
|
|
||||||
r += "]";
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<>
|
|
||||||
string
|
|
||||||
TypeHandlerImpl<pollfd *>::GetParameterValue(Context &context, Parameter *,
|
|
||||||
const void *address)
|
|
||||||
{
|
|
||||||
void *data = *(void **)address;
|
|
||||||
if (data != NULL && context.GetContents(Context::SIMPLE_STRUCTS))
|
|
||||||
return read_pollfd(context, data);
|
|
||||||
return context.FormatPointer(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<>
|
|
||||||
string
|
|
||||||
TypeHandlerImpl<pollfd *>::GetReturnValue(Context &context, uint64 value)
|
|
||||||
{
|
|
||||||
return context.FormatPointer((void *)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
static string
|
static string
|
||||||
format_pointer_value(Context &context, void *address)
|
format_pointer_value(Context &context, void *address)
|
||||||
@@ -769,12 +586,6 @@ class SpecializedPointerTypeHandler : public TypeHandler {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFINE_TYPE(name, type) \
|
|
||||||
TypeHandler *create_##name##_type_handler() \
|
|
||||||
{ \
|
|
||||||
return new TypeHandlerImpl<type>(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define POINTER_TYPE(name, type) \
|
#define POINTER_TYPE(name, type) \
|
||||||
TypeHandler *create_##name##_type_handler() \
|
TypeHandler *create_##name##_type_handler() \
|
||||||
{ \
|
{ \
|
||||||
@@ -782,11 +593,9 @@ class SpecializedPointerTypeHandler : public TypeHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_TYPE(iovec_ptr, iovec *);
|
DEFINE_TYPE(iovec_ptr, iovec *);
|
||||||
DEFINE_TYPE(fdset_ptr, fd_set *);
|
|
||||||
POINTER_TYPE(flock_ptr, flock);
|
POINTER_TYPE(flock_ptr, flock);
|
||||||
POINTER_TYPE(ifconf_ptr, ifconf);
|
POINTER_TYPE(ifconf_ptr, ifconf);
|
||||||
POINTER_TYPE(ifreq_ptr, ifreq);
|
POINTER_TYPE(ifreq_ptr, ifreq);
|
||||||
DEFINE_TYPE(pollfd_ptr, pollfd *);
|
|
||||||
POINTER_TYPE(siginfo_t_ptr, siginfo_t);
|
POINTER_TYPE(siginfo_t_ptr, siginfo_t);
|
||||||
POINTER_TYPE(msghdr_ptr, msghdr);
|
POINTER_TYPE(msghdr_ptr, msghdr);
|
||||||
DEFINE_TYPE(sockaddr_ptr, sockaddr *);
|
DEFINE_TYPE(sockaddr_ptr, sockaddr *);
|
||||||
@@ -796,4 +605,3 @@ POINTER_TYPE(sockaddr_args_ptr, sockaddr_args);
|
|||||||
POINTER_TYPE(sockopt_args_ptr, sockopt_args);
|
POINTER_TYPE(sockopt_args_ptr, sockopt_args);
|
||||||
POINTER_TYPE(socket_args_ptr, socket_args);
|
POINTER_TYPE(socket_args_ptr, socket_args);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ public:
|
|||||||
string GetParameterValue(Context &c, Parameter *, const void *);
|
string GetParameterValue(Context &c, Parameter *, const void *);
|
||||||
string GetReturnValue(Context &, uint64 value);
|
string GetReturnValue(Context &, uint64 value);
|
||||||
|
|
||||||
private:
|
|
||||||
string RenderValue(Context &, unsigned int value) const;
|
string RenderValue(Context &, unsigned int value) const;
|
||||||
|
|
||||||
|
private:
|
||||||
const EnumMap &fMap;
|
const EnumMap &fMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -63,7 +63,6 @@ public:
|
|||||||
string GetParameterValue(Context &c, Parameter *, const void *);
|
string GetParameterValue(Context &c, Parameter *, const void *);
|
||||||
string GetReturnValue(Context &, uint64 value);
|
string GetReturnValue(Context &, uint64 value);
|
||||||
|
|
||||||
protected:
|
|
||||||
string RenderValue(Context &, unsigned int value) const;
|
string RenderValue(Context &, unsigned int value) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -119,6 +118,12 @@ struct TypeHandlerFactory<const char*> {
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
|
#define DEFINE_TYPE(name, type) \
|
||||||
|
TypeHandler *create_##name##_type_handler() \
|
||||||
|
{ \
|
||||||
|
return new TypeHandlerImpl<type>(); \
|
||||||
|
}
|
||||||
|
|
||||||
struct fd_set;
|
struct fd_set;
|
||||||
struct flock;
|
struct flock;
|
||||||
struct ifconf;
|
struct ifconf;
|
||||||
|
|||||||
@@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023-2024, Haiku Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
|
#include "strace.h"
|
||||||
|
#include "Syscall.h"
|
||||||
|
#include "Context.h"
|
||||||
|
#include "MemoryReader.h"
|
||||||
|
#include "TypeHandler.h"
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - enums & flags handlers
|
||||||
|
|
||||||
|
|
||||||
|
struct enum_info {
|
||||||
|
unsigned int index;
|
||||||
|
const char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ENUM_INFO_ENTRY(name) \
|
||||||
|
{ name, #name }
|
||||||
|
|
||||||
|
|
||||||
|
#define FLAG_INFO_ENTRY(name) \
|
||||||
|
{ name, #name }
|
||||||
|
|
||||||
|
|
||||||
|
static const FlagsTypeHandler::FlagInfo kPollFlagInfos[] = {
|
||||||
|
FLAG_INFO_ENTRY(POLLIN),
|
||||||
|
FLAG_INFO_ENTRY(POLLOUT),
|
||||||
|
FLAG_INFO_ENTRY(POLLRDBAND),
|
||||||
|
FLAG_INFO_ENTRY(POLLWRBAND),
|
||||||
|
FLAG_INFO_ENTRY(POLLPRI),
|
||||||
|
|
||||||
|
FLAG_INFO_ENTRY(POLLERR),
|
||||||
|
FLAG_INFO_ENTRY(POLLHUP),
|
||||||
|
FLAG_INFO_ENTRY(POLLNVAL),
|
||||||
|
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static FlagsTypeHandler::FlagsList kPollFlags;
|
||||||
|
static FlagsTypeHandler sPollFlagsHandler(kPollFlags);
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - specialized type handlers
|
||||||
|
|
||||||
|
|
||||||
|
static string
|
||||||
|
read_fdset(Context &context, void *data)
|
||||||
|
{
|
||||||
|
// default FD_SETSIZE is 1024
|
||||||
|
unsigned long tmp[1024 / (sizeof(unsigned long) * 8)];
|
||||||
|
int32 bytesRead;
|
||||||
|
|
||||||
|
status_t err = context.Reader().Read(data, &tmp, sizeof(tmp), bytesRead);
|
||||||
|
if (err != B_OK)
|
||||||
|
return context.FormatPointer(data);
|
||||||
|
|
||||||
|
/* implicitly align to unsigned long lower boundary */
|
||||||
|
int count = bytesRead / sizeof(unsigned long);
|
||||||
|
int added = 0;
|
||||||
|
|
||||||
|
string r;
|
||||||
|
r.reserve(16);
|
||||||
|
|
||||||
|
r = "[";
|
||||||
|
|
||||||
|
for (int i = 0; i < count && added < 8; i++) {
|
||||||
|
for (int j = 0;
|
||||||
|
j < (int)(sizeof(unsigned long) * 8) && added < 8; j++) {
|
||||||
|
if (tmp[i] & (1UL << j)) {
|
||||||
|
if (added > 0)
|
||||||
|
r += " ";
|
||||||
|
unsigned int fd = i * sizeof(unsigned long) * 8 + j;
|
||||||
|
r += context.FormatUnsigned(fd);
|
||||||
|
added++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (added >= 8)
|
||||||
|
r += " ...";
|
||||||
|
|
||||||
|
r += "]";
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
string
|
||||||
|
TypeHandlerImpl<fd_set *>::GetParameterValue(Context &context, Parameter *,
|
||||||
|
const void *address)
|
||||||
|
{
|
||||||
|
void *data = *(void **)address;
|
||||||
|
if (data != NULL && context.GetContents(Context::SIMPLE_STRUCTS))
|
||||||
|
return read_fdset(context, data);
|
||||||
|
return context.FormatPointer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
string
|
||||||
|
TypeHandlerImpl<fd_set *>::GetReturnValue(Context &context, uint64 value)
|
||||||
|
{
|
||||||
|
return context.FormatPointer((void *)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static string
|
||||||
|
read_pollfd(Context &context, void *data)
|
||||||
|
{
|
||||||
|
nfds_t numfds = context.ReadValue<nfds_t>(context.GetSibling(1));
|
||||||
|
if ((int64)numfds <= 0)
|
||||||
|
return string();
|
||||||
|
|
||||||
|
pollfd tmp[numfds];
|
||||||
|
int32 bytesRead;
|
||||||
|
|
||||||
|
status_t err = context.Reader().Read(data, &tmp, sizeof(tmp), bytesRead);
|
||||||
|
if (err != B_OK)
|
||||||
|
return context.FormatPointer(data);
|
||||||
|
|
||||||
|
string r;
|
||||||
|
r.reserve(16);
|
||||||
|
|
||||||
|
r = "[";
|
||||||
|
|
||||||
|
int added = 0;
|
||||||
|
for (nfds_t i = 0; i < numfds && added < 8; i++) {
|
||||||
|
if ((tmp[i].fd == -1 || tmp[i].revents == 0)
|
||||||
|
&& context.GetContents(Context::OUTPUT_VALUES)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (added > 0)
|
||||||
|
r += ", ";
|
||||||
|
r += "{fd=" + context.FormatSigned(tmp[i].fd);
|
||||||
|
if (tmp[i].fd != -1 && context.GetContents(Context::INPUT_VALUES)) {
|
||||||
|
r += ", events=";
|
||||||
|
r += sPollFlagsHandler.RenderValue(context, tmp[i].events);
|
||||||
|
}
|
||||||
|
if (context.GetContents(Context::OUTPUT_VALUES)) {
|
||||||
|
r += ", revents=";
|
||||||
|
r += sPollFlagsHandler.RenderValue(context, tmp[i].revents);
|
||||||
|
}
|
||||||
|
added++;
|
||||||
|
r += "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (added >= 8)
|
||||||
|
r += " ...";
|
||||||
|
|
||||||
|
r += "]";
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
string
|
||||||
|
TypeHandlerImpl<pollfd *>::GetParameterValue(Context &context, Parameter *,
|
||||||
|
const void *address)
|
||||||
|
{
|
||||||
|
void *data = *(void **)address;
|
||||||
|
if (data != NULL && context.GetContents(Context::SIMPLE_STRUCTS))
|
||||||
|
return read_pollfd(context, data);
|
||||||
|
return context.FormatPointer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
string
|
||||||
|
TypeHandlerImpl<pollfd *>::GetReturnValue(Context &context, uint64 value)
|
||||||
|
{
|
||||||
|
return context.FormatPointer((void *)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DEFINE_TYPE(fdset_ptr, fd_set *)
|
||||||
|
DEFINE_TYPE(pollfd_ptr, pollfd *)
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - patch function
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
patch_events()
|
||||||
|
{
|
||||||
|
for (int i = 0; kPollFlagInfos[i].name != NULL; i++)
|
||||||
|
kPollFlags.push_back(kPollFlagInfos[i]);
|
||||||
|
|
||||||
|
Syscall *poll = get_syscall("_kern_poll");
|
||||||
|
poll->ParameterAt(0)->SetInOut(true);
|
||||||
|
|
||||||
|
Syscall *select = get_syscall("_kern_select");
|
||||||
|
select->ParameterAt(1)->SetInOut(true);
|
||||||
|
select->ParameterAt(2)->SetInOut(true);
|
||||||
|
select->ParameterAt(3)->SetInOut(true);
|
||||||
|
|
||||||
|
Syscall *wait = get_syscall("_kern_wait_for_child");
|
||||||
|
wait->ParameterAt(2)->SetOut(true);
|
||||||
|
wait->ParameterAt(3)->SetOut(true);
|
||||||
|
}
|
||||||
@@ -124,18 +124,6 @@ patch_network()
|
|||||||
shutdown->GetParameter("how")->SetHandler(
|
shutdown->GetParameter("how")->SetHandler(
|
||||||
new EnumTypeHandler(kShutdownHowMap));
|
new EnumTypeHandler(kShutdownHowMap));
|
||||||
|
|
||||||
Syscall *poll = get_syscall("_kern_poll");
|
|
||||||
poll->ParameterAt(0)->SetInOut(true);
|
|
||||||
|
|
||||||
Syscall *select = get_syscall("_kern_select");
|
|
||||||
select->ParameterAt(1)->SetInOut(true);
|
|
||||||
select->ParameterAt(2)->SetInOut(true);
|
|
||||||
select->ParameterAt(3)->SetInOut(true);
|
|
||||||
|
|
||||||
Syscall *wait = get_syscall("_kern_wait_for_child");
|
|
||||||
wait->ParameterAt(2)->SetOut(true);
|
|
||||||
wait->ParameterAt(3)->SetOut(true);
|
|
||||||
|
|
||||||
Syscall *createPipe = get_syscall("_kern_create_pipe");
|
Syscall *createPipe = get_syscall("_kern_create_pipe");
|
||||||
createPipe->ParameterAt(0)->SetOut(true);
|
createPipe->ParameterAt(0)->SetOut(true);
|
||||||
createPipe->ParameterAt(0)->SetCount(2);
|
createPipe->ParameterAt(0)->SetCount(2);
|
||||||
@@ -147,5 +135,4 @@ patch_network()
|
|||||||
new EnumTypeHandler(kSocketFamilyMap));
|
new EnumTypeHandler(kSocketFamilyMap));
|
||||||
socketPair->GetParameter("type")->SetHandler(
|
socketPair->GetParameter("type")->SetHandler(
|
||||||
new EnumTypeHandler(kSocketTypeMap));
|
new EnumTypeHandler(kSocketTypeMap));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -230,6 +230,7 @@ patch_syscalls()
|
|||||||
// kernel/syscalls.h and have it parsed automatically
|
// kernel/syscalls.h and have it parsed automatically
|
||||||
|
|
||||||
extern void patch_area();
|
extern void patch_area();
|
||||||
|
extern void patch_events();
|
||||||
extern void patch_exec();
|
extern void patch_exec();
|
||||||
extern void patch_fcntl();
|
extern void patch_fcntl();
|
||||||
extern void patch_ioctl();
|
extern void patch_ioctl();
|
||||||
@@ -248,6 +249,7 @@ patch_syscalls()
|
|||||||
}
|
}
|
||||||
|
|
||||||
patch_area();
|
patch_area();
|
||||||
|
patch_events();
|
||||||
patch_exec();
|
patch_exec();
|
||||||
patch_fcntl();
|
patch_fcntl();
|
||||||
patch_ioctl();
|
patch_ioctl();
|
||||||
|
|||||||
Reference in New Issue
Block a user