1
2 #include "inc.h"
3
4 #include <sys/mman.h>
5 #include <sys/resource.h>
6
7 static int
vm_brk_out(struct trace_proc * proc,const message * m_out)8 vm_brk_out(struct trace_proc * proc, const message * m_out)
9 {
10
11 put_ptr(proc, "addr", (vir_bytes)m_out->m_lc_vm_brk.addr);
12
13 return CT_DONE;
14 }
15
16 static const struct flags mmap_prot[] = {
17 FLAG_ZERO(PROT_NONE),
18 FLAG(PROT_READ),
19 FLAG(PROT_WRITE),
20 FLAG(PROT_EXEC),
21 };
22
23 static const struct flags mmap_flags[] = {
24 FLAG(MAP_SHARED),
25 FLAG(MAP_PRIVATE),
26 FLAG(MAP_FIXED),
27 FLAG(MAP_RENAME),
28 FLAG(MAP_NORESERVE),
29 FLAG(MAP_INHERIT),
30 FLAG(MAP_HASSEMAPHORE),
31 FLAG(MAP_TRYFIXED),
32 FLAG(MAP_WIRED),
33 FLAG_MASK(MAP_ANON | MAP_STACK, MAP_FILE),
34 FLAG(MAP_ANON),
35 FLAG(MAP_STACK),
36 FLAG(MAP_UNINITIALIZED),
37 FLAG(MAP_PREALLOC),
38 FLAG(MAP_CONTIG),
39 FLAG(MAP_LOWER16M),
40 FLAG(MAP_LOWER1M),
41 FLAG(MAP_THIRDPARTY),
42 /* TODO: interpret alignments for which there is no constant */
43 FLAG_MASK(MAP_ALIGNMENT_MASK, MAP_ALIGNMENT_64KB),
44 FLAG_MASK(MAP_ALIGNMENT_MASK, MAP_ALIGNMENT_16MB),
45 FLAG_MASK(MAP_ALIGNMENT_MASK, MAP_ALIGNMENT_4GB),
46 FLAG_MASK(MAP_ALIGNMENT_MASK, MAP_ALIGNMENT_1TB),
47 FLAG_MASK(MAP_ALIGNMENT_MASK, MAP_ALIGNMENT_256TB),
48 FLAG_MASK(MAP_ALIGNMENT_MASK, MAP_ALIGNMENT_64PB),
49 };
50
51 static int
vm_mmap_out(struct trace_proc * proc,const message * m_out)52 vm_mmap_out(struct trace_proc * proc, const message * m_out)
53 {
54
55 if (m_out->m_mmap.flags & MAP_THIRDPARTY)
56 put_endpoint(proc, "forwhom", m_out->m_mmap.forwhom);
57 put_ptr(proc, "addr", (vir_bytes)m_out->m_mmap.addr);
58 put_value(proc, "len", "%zu", m_out->m_mmap.len);
59 put_flags(proc, "prot", mmap_prot, COUNT(mmap_prot), "0x%x",
60 m_out->m_mmap.prot);
61 put_flags(proc, "flags", mmap_flags, COUNT(mmap_flags), "0x%x",
62 m_out->m_mmap.flags);
63 put_fd(proc, "fd", m_out->m_mmap.fd);
64 put_value(proc, "offset", "%"PRId64, m_out->m_mmap.offset);
65
66 return CT_DONE;
67 }
68
69 static void
vm_mmap_in(struct trace_proc * proc,const message * __unused m_out,const message * m_in,int failed)70 vm_mmap_in(struct trace_proc * proc, const message * __unused m_out,
71 const message * m_in, int failed)
72 {
73
74 if (!failed)
75 put_ptr(proc, NULL, (vir_bytes)m_in->m_mmap.retaddr);
76 else
77 /* TODO: consider printing MAP_FAILED in the right cases */
78 put_result(proc);
79 }
80
81 static int
vm_munmap_out(struct trace_proc * proc,const message * m_out)82 vm_munmap_out(struct trace_proc * proc, const message * m_out)
83 {
84
85 put_ptr(proc, "addr", (vir_bytes)m_out->m_mmap.addr);
86 put_value(proc, "len", "%zu", m_out->m_mmap.len);
87
88 return CT_DONE;
89 }
90
91 #define VM_CALL(c) [((VM_ ## c) - VM_RQ_BASE)]
92
93 static const struct call_handler vm_map[] = {
94 VM_CALL(BRK) = HANDLER("brk", vm_brk_out, default_in),
95 VM_CALL(MMAP) = HANDLER("mmap", vm_mmap_out, vm_mmap_in),
96 VM_CALL(MUNMAP) = HANDLER("munmap", vm_munmap_out, default_in),
97 };
98
99 const struct calls vm_calls = {
100 .endpt = VM_PROC_NR,
101 .base = VM_RQ_BASE,
102 .map = vm_map,
103 .count = COUNT(vm_map)
104 };
105