129f8da76STrung Nguyen /*
229f8da76STrung Nguyen * Copyright 2023, Trung Nguyen, trungnt282910@gmail.com.
329f8da76STrung Nguyen * Distributed under the terms of the MIT License.
429f8da76STrung Nguyen */
529f8da76STrung Nguyen
629f8da76STrung Nguyen
729f8da76STrung Nguyen #include <string.h>
829f8da76STrung Nguyen
929f8da76STrung Nguyen #include <user_mutex_defs.h>
1029f8da76STrung Nguyen
1129f8da76STrung Nguyen #include "strace.h"
1229f8da76STrung Nguyen #include "Context.h"
1329f8da76STrung Nguyen #include "MemoryReader.h"
1429f8da76STrung Nguyen #include "TypeHandler.h"
1529f8da76STrung Nguyen
1629f8da76STrung Nguyen
1729f8da76STrung Nguyen #define FLAG_INFO_ENTRY(name) \
1829f8da76STrung Nguyen { name, #name }
1929f8da76STrung Nguyen
2029f8da76STrung Nguyen static const FlagsTypeHandler::FlagInfo kMutexFlagsInfo[] = {
2129f8da76STrung Nguyen FLAG_INFO_ENTRY(B_USER_MUTEX_LOCKED),
2229f8da76STrung Nguyen FLAG_INFO_ENTRY(B_USER_MUTEX_WAITING),
2329f8da76STrung Nguyen FLAG_INFO_ENTRY(B_USER_MUTEX_DISABLED),
2429f8da76STrung Nguyen
2529f8da76STrung Nguyen { 0, NULL }
2629f8da76STrung Nguyen };
2729f8da76STrung Nguyen
28*2eb83002SAugustin Cavalier static const FlagsTypeHandler::FlagInfo kMutexOptionFlagsInfo[] = {
29*2eb83002SAugustin Cavalier FLAG_INFO_ENTRY(B_RELATIVE_TIMEOUT),
30*2eb83002SAugustin Cavalier FLAG_INFO_ENTRY(B_ABSOLUTE_TIMEOUT),
31*2eb83002SAugustin Cavalier FLAG_INFO_ENTRY(B_TIMEOUT_REAL_TIME_BASE),
32*2eb83002SAugustin Cavalier
33*2eb83002SAugustin Cavalier FLAG_INFO_ENTRY(B_USER_MUTEX_SHARED),
34*2eb83002SAugustin Cavalier FLAG_INFO_ENTRY(B_USER_MUTEX_UNBLOCK_ALL),
35*2eb83002SAugustin Cavalier
36*2eb83002SAugustin Cavalier { 0, NULL }
37*2eb83002SAugustin Cavalier };
38*2eb83002SAugustin Cavalier
3929f8da76STrung Nguyen static FlagsTypeHandler::FlagsList kMutexFlags;
40*2eb83002SAugustin Cavalier static FlagsTypeHandler::FlagsList kMutexOptionFlags;
4129f8da76STrung Nguyen
4229f8da76STrung Nguyen
4329f8da76STrung Nguyen class MutexTypeHandler : public FlagsTypeHandler {
4429f8da76STrung Nguyen public:
MutexTypeHandler()4529f8da76STrung Nguyen MutexTypeHandler()
4629f8da76STrung Nguyen :
4729f8da76STrung Nguyen FlagsTypeHandler(kMutexFlags)
4829f8da76STrung Nguyen {
4929f8da76STrung Nguyen }
5029f8da76STrung Nguyen
GetParameterValue(Context & context,Parameter * param,const void * address)5129f8da76STrung Nguyen string GetParameterValue(Context &context, Parameter *param,
5229f8da76STrung Nguyen const void *address)
5329f8da76STrung Nguyen {
5429f8da76STrung Nguyen void *data = *(void **)address;
5529f8da76STrung Nguyen
5629f8da76STrung Nguyen if (context.GetContents(Context::POINTER_VALUES)) {
5729f8da76STrung Nguyen int32 value, bytesRead;
5829f8da76STrung Nguyen status_t err = context.Reader().Read(data, &value, sizeof(value), bytesRead);
5929f8da76STrung Nguyen if (err != B_OK)
6029f8da76STrung Nguyen return context.FormatPointer(data);
6129f8da76STrung Nguyen
6229f8da76STrung Nguyen string r = context.FormatPointer(data);
6329f8da76STrung Nguyen r += " [";
6429f8da76STrung Nguyen r += RenderValue(context, (unsigned int)value);
6529f8da76STrung Nguyen r += "]";
6629f8da76STrung Nguyen return r;
6729f8da76STrung Nguyen }
6829f8da76STrung Nguyen
6929f8da76STrung Nguyen return context.FormatPointer(data);
7029f8da76STrung Nguyen }
7129f8da76STrung Nguyen
GetReturnValue(Context & context,uint64 value)7229f8da76STrung Nguyen string GetReturnValue(Context &context, uint64 value)
7329f8da76STrung Nguyen {
7429f8da76STrung Nguyen return context.FormatPointer((void *)value);
7529f8da76STrung Nguyen }
7629f8da76STrung Nguyen };
7729f8da76STrung Nguyen
7829f8da76STrung Nguyen
7929f8da76STrung Nguyen void
patch_mutex()8029f8da76STrung Nguyen patch_mutex()
8129f8da76STrung Nguyen {
82*2eb83002SAugustin Cavalier for (int i = 0; kMutexFlagsInfo[i].name != NULL; i++)
8329f8da76STrung Nguyen kMutexFlags.push_back(kMutexFlagsInfo[i]);
84*2eb83002SAugustin Cavalier for (int i = 0; kMutexOptionFlagsInfo[i].name != NULL; i++)
85*2eb83002SAugustin Cavalier kMutexOptionFlags.push_back(kMutexOptionFlagsInfo[i]);
8629f8da76STrung Nguyen
8729f8da76STrung Nguyen Syscall *mutex_lock = get_syscall("_kern_mutex_lock");
8829f8da76STrung Nguyen mutex_lock->GetParameter("mutex")->SetHandler(new MutexTypeHandler());
89*2eb83002SAugustin Cavalier mutex_lock->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kMutexOptionFlags));
9029f8da76STrung Nguyen
9129f8da76STrung Nguyen Syscall *mutex_unlock = get_syscall("_kern_mutex_unblock");
9229f8da76STrung Nguyen mutex_unlock->GetParameter("mutex")->SetHandler(new MutexTypeHandler());
93*2eb83002SAugustin Cavalier mutex_unlock->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kMutexOptionFlags));
9429f8da76STrung Nguyen
9529f8da76STrung Nguyen Syscall *mutex_switch_lock = get_syscall("_kern_mutex_switch_lock");
9629f8da76STrung Nguyen mutex_switch_lock->GetParameter("fromMutex")->SetHandler(new MutexTypeHandler());
97*2eb83002SAugustin Cavalier mutex_switch_lock->GetParameter("fromFlags")->SetHandler(
98*2eb83002SAugustin Cavalier new FlagsTypeHandler(kMutexOptionFlags));
9929f8da76STrung Nguyen mutex_switch_lock->GetParameter("toMutex")->SetHandler(new MutexTypeHandler());
100*2eb83002SAugustin Cavalier mutex_switch_lock->GetParameter("toFlags")->SetHandler(
101*2eb83002SAugustin Cavalier new FlagsTypeHandler(kMutexOptionFlags));
102*2eb83002SAugustin Cavalier
103*2eb83002SAugustin Cavalier Syscall *mutex_sem_acquire = get_syscall("_kern_mutex_sem_acquire");
104*2eb83002SAugustin Cavalier mutex_sem_acquire->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kMutexOptionFlags));
105*2eb83002SAugustin Cavalier
106*2eb83002SAugustin Cavalier Syscall *mutex_sem_release = get_syscall("_kern_mutex_sem_release");
107*2eb83002SAugustin Cavalier mutex_sem_release->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kMutexOptionFlags));
10829f8da76STrung Nguyen }
109