1 /* 2 * Copyright 2023, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <OS.h> 8 #include <vm_defs.h> 9 10 #include "strace.h" 11 #include "Syscall.h" 12 #include "TypeHandler.h" 13 14 15 #define FLAG_INFO_ENTRY(name) \ 16 { name, #name } 17 18 static const FlagsTypeHandler::FlagInfo kAreaProtectionFlagInfos[] = { 19 FLAG_INFO_ENTRY(B_READ_AREA), 20 FLAG_INFO_ENTRY(B_WRITE_AREA), 21 FLAG_INFO_ENTRY(B_EXECUTE_AREA), 22 FLAG_INFO_ENTRY(B_STACK_AREA), 23 24 FLAG_INFO_ENTRY(B_CLONEABLE_AREA), 25 FLAG_INFO_ENTRY(B_OVERCOMMITTING_AREA), 26 27 { 0, NULL } 28 }; 29 30 31 struct enum_info { 32 unsigned int index; 33 const char *name; 34 }; 35 36 #define ENUM_INFO_ENTRY(name) \ 37 { name, #name } 38 39 static const enum_info kAddressSpecs[] = { 40 ENUM_INFO_ENTRY(B_ANY_ADDRESS), 41 ENUM_INFO_ENTRY(B_EXACT_ADDRESS), 42 ENUM_INFO_ENTRY(B_BASE_ADDRESS), 43 ENUM_INFO_ENTRY(B_CLONE_ADDRESS), 44 ENUM_INFO_ENTRY(B_ANY_KERNEL_ADDRESS), 45 ENUM_INFO_ENTRY(B_RANDOMIZED_ANY_ADDRESS), 46 ENUM_INFO_ENTRY(B_RANDOMIZED_BASE_ADDRESS), 47 48 { 0, NULL } 49 }; 50 51 52 static FlagsTypeHandler::FlagsList kAreaProtectionFlags; 53 static EnumTypeHandler::EnumMap kAddressSpecsMap; 54 55 56 void 57 patch_area() 58 { 59 for (int i = 0; kAreaProtectionFlagInfos[i].name != NULL; i++) { 60 kAreaProtectionFlags.push_back(kAreaProtectionFlagInfos[i]); 61 } 62 for (int i = 0; kAddressSpecs[i].name != NULL; i++) { 63 kAddressSpecsMap[kAddressSpecs[i].index] = kAddressSpecs[i].name; 64 } 65 66 Syscall *create = get_syscall("_kern_create_area"); 67 create->GetParameter("address")->SetInOut(true); 68 create->GetParameter("addressSpec")->SetHandler( 69 new EnumTypeHandler(kAddressSpecsMap)); 70 create->GetParameter("protection")->SetHandler( 71 new FlagsTypeHandler(kAreaProtectionFlags)); 72 73 Syscall *transfer = get_syscall("_kern_transfer_area"); 74 transfer->GetParameter("_address")->SetInOut(true); 75 transfer->GetParameter("addressSpec")->SetHandler( 76 new EnumTypeHandler(kAddressSpecsMap)); 77 78 Syscall *clone = get_syscall("_kern_clone_area"); 79 clone->GetParameter("_address")->SetInOut(true); 80 clone->GetParameter("addressSpec")->SetHandler( 81 new EnumTypeHandler(kAddressSpecsMap)); 82 clone->GetParameter("protection")->SetHandler( 83 new FlagsTypeHandler(kAreaProtectionFlags)); 84 85 Syscall *reserve_address_range = get_syscall("_kern_reserve_address_range"); 86 reserve_address_range->GetParameter("_address")->SetInOut(true); 87 reserve_address_range->GetParameter("addressSpec")->SetHandler( 88 new EnumTypeHandler(kAddressSpecsMap)); 89 90 Syscall *set_area_protection = get_syscall("_kern_set_area_protection"); 91 set_area_protection->GetParameter("newProtection")->SetHandler( 92 new FlagsTypeHandler(kAreaProtectionFlags)); 93 94 Syscall *map_file = get_syscall("_kern_map_file"); 95 map_file->GetParameter("address")->SetInOut(true); 96 map_file->GetParameter("addressSpec")->SetHandler( 97 new EnumTypeHandler(kAddressSpecsMap)); 98 map_file->GetParameter("protection")->SetHandler( 99 new FlagsTypeHandler(kAreaProtectionFlags)); 100 101 Syscall *set_memory_protection = get_syscall("_kern_set_memory_protection"); 102 set_memory_protection->GetParameter("protection")->SetHandler( 103 new FlagsTypeHandler(kAreaProtectionFlags)); 104 } 105