xref: /haiku/src/bin/debug/strace/area.cpp (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
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