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