1 /* 2 * Copyright 2023, Trung Nguyen, trungnt282910@gmail.com. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <string.h> 8 9 #include <user_mutex_defs.h> 10 11 #include "strace.h" 12 #include "Context.h" 13 #include "MemoryReader.h" 14 #include "TypeHandler.h" 15 16 17 #define FLAG_INFO_ENTRY(name) \ 18 { name, #name } 19 20 static const FlagsTypeHandler::FlagInfo kMutexFlagsInfo[] = { 21 FLAG_INFO_ENTRY(B_USER_MUTEX_LOCKED), 22 FLAG_INFO_ENTRY(B_USER_MUTEX_WAITING), 23 FLAG_INFO_ENTRY(B_USER_MUTEX_DISABLED), 24 25 { 0, NULL } 26 }; 27 28 static FlagsTypeHandler::FlagsList kMutexFlags; 29 30 31 class MutexTypeHandler : public FlagsTypeHandler { 32 public: 33 MutexTypeHandler() 34 : 35 FlagsTypeHandler(kMutexFlags) 36 { 37 } 38 39 string GetParameterValue(Context &context, Parameter *param, 40 const void *address) 41 { 42 void *data = *(void **)address; 43 44 if (context.GetContents(Context::POINTER_VALUES)) { 45 int32 value, bytesRead; 46 status_t err = context.Reader().Read(data, &value, sizeof(value), bytesRead); 47 if (err != B_OK) 48 return context.FormatPointer(data); 49 50 string r = context.FormatPointer(data); 51 r += " ["; 52 r += RenderValue(context, (unsigned int)value); 53 r += "]"; 54 return r; 55 } 56 57 return context.FormatPointer(data); 58 } 59 60 string GetReturnValue(Context &context, uint64 value) 61 { 62 return context.FormatPointer((void *)value); 63 } 64 }; 65 66 67 void 68 patch_mutex() 69 { 70 for (int i = 0; kMutexFlagsInfo[i].name != NULL; i++) { 71 kMutexFlags.push_back(kMutexFlagsInfo[i]); 72 } 73 74 Syscall *mutex_lock = get_syscall("_kern_mutex_lock"); 75 mutex_lock->GetParameter("mutex")->SetHandler(new MutexTypeHandler()); 76 77 Syscall *mutex_unlock = get_syscall("_kern_mutex_unblock"); 78 mutex_unlock->GetParameter("mutex")->SetHandler(new MutexTypeHandler()); 79 80 Syscall *mutex_switch_lock = get_syscall("_kern_mutex_switch_lock"); 81 mutex_switch_lock->GetParameter("fromMutex")->SetHandler(new MutexTypeHandler()); 82 mutex_switch_lock->GetParameter("toMutex")->SetHandler(new MutexTypeHandler()); 83 } 84