MOS Source Code
Loading...
Searching...
No Matches
stdio_kernel_ext.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#include "mos/assert.hpp"
7
8#include <mos/types.hpp>
9#include <mos_stdio.hpp>
10
11static size_t do_print_vmflags(char *buf, size_t size, VMFlags flags)
12{
13 return snprintf(buf, size, "%c%c%c", flags.test(VM_READ) ? 'r' : '-', flags.test(VM_WRITE) ? 'w' : '-', flags.test(VM_EXEC) ? 'x' : '-');
14}
15
38
39size_t vsnprintf_do_pointer_kernel(char *buf, size_t *size, const char **pformat, ptr_t ptr)
40{
41 size_t ret = 0;
42#define current (**pformat)
43#define peek_next (*(*pformat + 1))
44#define shift_next ((void) ((*pformat)++))
45#define unshift_next ((void) ((*pformat)--))
46
47#define wrap_print(...) wrap_printed(snprintf(buf, *size, __VA_ARGS__))
48#define wrap_printed(x) \
49 do \
50 { \
51 const size_t _printed = x; \
52 buf += _printed, ret += _printed; \
53 } while (0)
54
55 if (current != 'p')
56 goto done;
57
58#define null_check() \
59 do \
60 { \
61 if (unlikely(ptr == 0)) \
62 { \
63 wrap_print("(null)"); \
64 goto done; \
65 } \
66 } while (0)
67
68 switch (peek_next)
69 {
70 case 'i':
71 {
73 switch (peek_next)
74 {
75 case 'o':
76 {
78 // IO
79 const IO *io = (const IO *) ptr;
80 if (io == NULL)
81 {
82 wrap_print("(null)");
83 goto done;
84 }
85
86 const auto name = io->name();
87 wrap_print("{ '%s'", name.c_str());
88 if (!IO::IsValid(io))
89 wrap_print(", invalid");
90 wrap_print(" }");
91 goto done;
92 }
93 default: return false;
94 }
95
97 }
98 case 's': // %ps
99 {
101 // kernel symbol address
102 const kallsyms_t *sym = kallsyms_get_symbol(ptr);
103 if (!sym)
104 {
105 wrap_print("(unknown)");
106 goto done;
107 }
108
109 const off_t off = ptr - sym->address;
110 if (off)
111 wrap_print("%s (+0x%zx)", sym ? sym->name : "(unknown)", off);
112 else
113 wrap_print("%s", sym ? sym->name : "(unknown)");
114 goto done;
115 }
116 case 't': // %pt
117 {
119 // thread_t
120 null_check();
121 const auto thread = (Thread *) ptr;
122 if (thread == NULL)
123 {
124 wrap_print("(null)");
125 goto done;
126 }
127 MOS_ASSERT_X(Thread::IsValid(thread), "thread is invalid");
128 wrap_print("[t%d:%s]", thread->tid, thread->name.empty() ? "<no name>" : thread->name.data());
129 goto done;
130 }
131 case 'p': // %pp
132 {
134 // process_t
135 null_check();
136 const Process *process = (const Process *) ptr;
137 if (process == NULL)
138 {
139 wrap_print("(null)");
140 goto done;
141 }
142 MOS_ASSERT_X(Process::IsValid(process), "process is invalid");
143 wrap_print("[p%d:%s]", process->pid, process->name.empty() ? "<no name>" : process->name.data());
144 goto done;
145 }
146 case 'v': // %pv
147 {
149
150 // vmap-related types
151 switch (peek_next)
152 {
153 case 'f': // %pvf
154 {
156 // VMFlags, only r/w/x are supported
157 const VMFlags flags = *(VMFlags *) ptr;
158 wrap_printed(do_print_vmflags(buf, *size, flags));
159 goto done;
160 }
161 case 'm': // %pvm
162 {
164 // vmap_t *, print the vmap's range and flags
165 const vmap_t *vmap = (const vmap_t *) ptr;
166 if (vmap == NULL)
167 {
168 wrap_print("(null)");
169 goto done;
170 }
171
172 wrap_print("{ [" PTR_VLFMT " - " PTR_VLFMT "], ", vmap->vaddr, vmap->vaddr + vmap->npages * MOS_PAGE_SIZE - 1);
174 wrap_print(", fault: %ps", (void *) (ptr_t) vmap->on_fault);
175
176 if (vmap->io)
177 {
178 const auto name = vmap->io->name();
179 wrap_print(", io: '%s', offset: 0x%zx", name.c_str(), vmap->io_offset);
180 }
181
182 wrap_print(" }");
183 goto done;
184 }
185 default: return false;
186 }
187 }
188 default: return false;
189 }
190
191done:
192 return ret;
193}
#define MOS_ASSERT_X(cond, msg,...)
Definition assert.hpp:12
#define MOS_UNREACHABLE()
Definition assert.hpp:10
#define MOS_PAGE_SIZE
Definition autoconf.h:6
bool empty() const
Definition string.hpp:279
const Char * data() const
Definition string.hpp:254
const kallsyms_t * kallsyms_get_symbol(ptr_t addr)
Definition kallsyms.cpp:5
@ VM_READ
Definition mm_types.hpp:13
@ VM_EXEC
Definition mm_types.hpp:15
@ VM_WRITE
Definition mm_types.hpp:14
#define current
#define NULL
Definition pb_syshdr.h:46
mos::shared_ptr< T > ptr
size_t size
Definition slab.cpp:32
const char * name
Definition slab.cpp:33
size_t vsnprintf_do_pointer_kernel(char *buf, size_t *size, const char **pformat, ptr_t ptr)
Kernel's extension to vsnprintf, 'p' format specifier.
static size_t do_print_vmflags(char *buf, size_t size, VMFlags flags)
#define null_check()
#define peek_next
#define shift_next
#define wrap_printed(x)
#define wrap_print(...)
Definition io.hpp:39
static bool IsValid(const IO *io)
Definition io.hpp:46
virtual mos::string name() const
Definition io.cpp:45
mos::string name
static bool IsValid(const Process *process)
pid_t pid
static bool IsValid(const Thread *thread)
ptr_t address
Definition kallsyms.hpp:9
const char * name
Definition kallsyms.hpp:10
Definition mm.hpp:60
ptr_t vaddr
Definition mm.hpp:64
VMFlags vmflags
Definition mm.hpp:66
size_t npages
Definition mm.hpp:65
vmfault_handler_t on_fault
Definition mm.hpp:75
IO * io
Definition mm.hpp:69
off_t io_offset
Definition mm.hpp:70
int snprintf(char *__restrict str, size_t size, const char *__restrict format,...)
Definition mos_stdio.cpp:16
#define PTR_VLFMT
Definition types.h:30
ssize_t off_t
Definition types.h:80
unsigned long ptr_t
Definition types.h:21