@@ -10,7 +10,52 @@ use core::cmp;
1010use core:: fmt;
1111
1212use crate :: bindings;
13- use crate :: c_types:: c_int;
13+ use crate :: c_types:: { c_char, c_void} ;
14+
15+ // Called from `vsprintf` with format specifier `%pA`.
16+ #[ no_mangle]
17+ unsafe fn rust_fmt_argument ( buf : * mut c_char , end : * mut c_char , ptr : * const c_void ) -> * mut c_char {
18+ use fmt:: Write ;
19+
20+ // Use `usize` to use `saturating_*` functions.
21+ struct Writer {
22+ buf : usize ,
23+ end : usize ,
24+ }
25+
26+ impl Write for Writer {
27+ fn write_str ( & mut self , s : & str ) -> fmt:: Result {
28+ // `buf` value after writing `len` bytes. This does not have to be bounded
29+ // by `end`, but we don't want it to wrap around to 0.
30+ let buf_new = self . buf . saturating_add ( s. len ( ) ) ;
31+
32+ // Amount that we can copy. `saturating_sub` ensures we get 0 if
33+ // `buf` goes past `end`.
34+ let len_to_copy = cmp:: min ( buf_new, self . end ) . saturating_sub ( self . buf ) ;
35+
36+ // SAFETY: In any case, `buf` is non-null and properly aligned.
37+ // If `len_to_copy` is non-zero, then we know `buf` has not past
38+ // `end` yet and so is valid.
39+ unsafe {
40+ core:: ptr:: copy_nonoverlapping (
41+ s. as_bytes ( ) . as_ptr ( ) ,
42+ self . buf as * mut u8 ,
43+ len_to_copy,
44+ )
45+ } ;
46+
47+ self . buf = buf_new;
48+ Ok ( ( ) )
49+ }
50+ }
51+
52+ let mut w = Writer {
53+ buf : buf as _ ,
54+ end : end as _ ,
55+ } ;
56+ let _ = w. write_fmt ( * ( ptr as * const fmt:: Arguments < ' _ > ) ) ;
57+ w. buf as _
58+ }
1459
1560/// Format strings.
1661///
@@ -23,7 +68,7 @@ pub mod format_strings {
2368 const LENGTH_PREFIX : usize = 2 ;
2469
2570 /// The length of the fixed format strings.
26- pub const LENGTH : usize = 11 ;
71+ pub const LENGTH : usize = 10 ;
2772
2873 /// Generates a fixed format string for the kernel's [`printk`].
2974 ///
@@ -42,14 +87,14 @@ pub mod format_strings {
4287 assert ! ( prefix[ 2 ] == b'\x00' ) ;
4388
4489 let suffix: & [ u8 ; LENGTH - LENGTH_PREFIX ] = if is_cont {
45- b"%.*s \0 \0 \0 \0 \0 "
90+ b"%pA \0 \0 \0 \0 \0 "
4691 } else {
47- b"%s: %.*s \0 "
92+ b"%s: %pA \0 "
4893 } ;
4994
5095 [
5196 prefix[ 0 ] , prefix[ 1 ] , suffix[ 0 ] , suffix[ 1 ] , suffix[ 2 ] , suffix[ 3 ] , suffix[ 4 ] , suffix[ 5 ] ,
52- suffix[ 6 ] , suffix[ 7 ] , suffix [ 8 ] ,
97+ suffix[ 6 ] , suffix[ 7 ] ,
5398 ]
5499 }
55100
@@ -84,14 +129,13 @@ pub mod format_strings {
84129pub unsafe fn call_printk (
85130 format_string : & [ u8 ; format_strings:: LENGTH ] ,
86131 module_name : & [ u8 ] ,
87- string : & [ u8 ] ,
132+ args : fmt :: Arguments < ' _ > ,
88133) {
89134 // `printk` does not seem to fail in any path.
90135 bindings:: printk (
91136 format_string. as_ptr ( ) as _ ,
92137 module_name. as_ptr ( ) ,
93- string. len ( ) as c_int ,
94- string. as_ptr ( ) ,
138+ & args as * const _ as * const c_void ,
95139 ) ;
96140}
97141
@@ -101,112 +145,26 @@ pub unsafe fn call_printk(
101145///
102146/// [`printk`]: ../../../../include/linux/printk.h
103147#[ doc( hidden) ]
104- pub fn call_printk_cont ( string : & [ u8 ] ) {
148+ pub fn call_printk_cont ( args : fmt :: Arguments < ' _ > ) {
105149 // `printk` does not seem to fail in any path.
106150 //
107151 // SAFETY: The format string is fixed.
108152 unsafe {
109153 bindings:: printk (
110154 format_strings:: CONT . as_ptr ( ) as _ ,
111- string. len ( ) as c_int ,
112- string. as_ptr ( ) ,
155+ & args as * const _ as * const c_void ,
113156 ) ;
114157 }
115158}
116159
117- /// The maximum size of a log line in the kernel.
118- ///
119- /// From `kernel/printk/printk.c`.
120- const LOG_LINE_MAX : usize = 1024 - 32 ;
121-
122- /// The maximum size of a log line in our side.
123- ///
124- /// FIXME: We should be smarter than this, but for the moment, to reduce stack
125- /// usage, we only allow this much which should work for most purposes.
126- const LOG_LINE_SIZE : usize = 300 ;
127- crate :: static_assert!( LOG_LINE_SIZE <= LOG_LINE_MAX ) ;
128-
129- /// Public but hidden since it should only be used from public macros.
130- #[ doc( hidden) ]
131- pub struct LogLineWriter {
132- data : [ u8 ; LOG_LINE_SIZE ] ,
133- pos : usize ,
134- }
135-
136- impl LogLineWriter {
137- /// Creates a new [`LogLineWriter`].
138- pub fn new ( ) -> LogLineWriter {
139- LogLineWriter {
140- data : [ 0u8 ; LOG_LINE_SIZE ] ,
141- pos : 0 ,
142- }
143- }
144-
145- /// Returns the internal buffer as a byte slice.
146- pub fn as_bytes ( & self ) -> & [ u8 ] {
147- & self . data [ ..self . pos ]
148- }
149- }
150-
151- impl Default for LogLineWriter {
152- fn default ( ) -> Self {
153- Self :: new ( )
154- }
155- }
156-
157- impl fmt:: Write for LogLineWriter {
158- fn write_str ( & mut self , s : & str ) -> fmt:: Result {
159- let copy_len = cmp:: min ( LOG_LINE_SIZE - self . pos , s. as_bytes ( ) . len ( ) ) ;
160- self . data [ self . pos ..self . pos + copy_len] . copy_from_slice ( & s. as_bytes ( ) [ ..copy_len] ) ;
161- self . pos += copy_len;
162- Ok ( ( ) )
163- }
164- }
165-
166- /// Helper function for the [`print_macro!`] to reduce stack usage.
167- ///
168- /// Public but hidden since it should only be used from public macros.
169- ///
170- /// # Safety
171- ///
172- /// The format string must be one of the ones in [`format_strings`], and
173- /// the module name must be null-terminated.
174- #[ doc( hidden) ]
175- pub unsafe fn format_and_call < const CONT : bool > (
176- format_string : & [ u8 ; format_strings:: LENGTH ] ,
177- module_name : & [ u8 ] ,
178- args : fmt:: Arguments ,
179- ) {
180- // Careful: this object takes quite a bit of stack.
181- let mut writer = LogLineWriter :: new ( ) ;
182-
183- match fmt:: write ( & mut writer, args) {
184- Ok ( _) => {
185- if CONT {
186- call_printk_cont ( writer. as_bytes ( ) ) ;
187- } else {
188- call_printk ( format_string, module_name, writer. as_bytes ( ) ) ;
189- }
190- }
191-
192- Err ( _) => {
193- call_printk (
194- & format_strings:: CRIT ,
195- module_name,
196- b"Failure to format string.\n " ,
197- ) ;
198- }
199- } ;
200- }
201-
202160/// Performs formatting and forwards the string to [`call_printk`].
203161///
204162/// Public but hidden since it should only be used from public macros.
205163#[ doc( hidden) ]
206164#[ macro_export]
207165macro_rules! print_macro (
208- // Without extra arguments: no need to format anything .
209- ( $format_string: path, false , $fmt : expr ) => (
166+ // The non-continuation cases (most of them, e.g. `INFO`) .
167+ ( $format_string: path, false , $( $arg : tt ) + ) => (
210168 // SAFETY: This hidden macro should only be called by the documented
211169 // printing macros which ensure the format string is one of the fixed
212170 // ones. All `__LOG_PREFIX`s are null-terminated as they are generated
@@ -216,47 +174,17 @@ macro_rules! print_macro (
216174 $crate:: print:: call_printk(
217175 & $format_string,
218176 crate :: __LOG_PREFIX,
219- $fmt . as_bytes ( ) ,
177+ format_args! ( $ ( $arg ) + ) ,
220178 ) ;
221179 }
222180 ) ;
223181
224- // Without extra arguments: no need to format anything ( `CONT` case) .
225- ( $format_string: path, true , $fmt : expr ) => (
182+ // The `CONT` case.
183+ ( $format_string: path, true , $( $arg : tt ) + ) => (
226184 $crate:: print:: call_printk_cont(
227- $fmt . as_bytes ( ) ,
185+ format_args! ( $ ( $arg ) + ) ,
228186 ) ;
229187 ) ;
230-
231- // With extra arguments: we need to perform formatting.
232- ( $format_string: path, $cont: literal, $fmt: expr, $( $arg: tt) * ) => (
233- // Forwarding the call to a function to perform the formatting
234- // is needed here to avoid stack overflows in non-optimized builds when
235- // invoking the printing macros a lot of times in the same function.
236- // Without it, the compiler reserves one `LogLineWriter` per macro
237- // invocation, which is a huge type.
238- //
239- // We could use an immediately-invoked closure for this, which
240- // seems to lower even more the stack usage at `opt-level=0` because
241- // `fmt::Arguments` objects do not pile up. However, that breaks
242- // the `?` operator if used in one of the arguments.
243- //
244- // At `opt-level=2`, the generated code is basically the same for
245- // all alternatives.
246- //
247- // SAFETY: This hidden macro should only be called by the documented
248- // printing macros which ensure the format string is one of the fixed
249- // ones. All `__LOG_PREFIX`s are null-terminated as they are generated
250- // by the `module!` proc macro or fixed values defined in a kernel
251- // crate.
252- unsafe {
253- $crate:: print:: format_and_call:: <$cont>(
254- & $format_string,
255- crate :: __LOG_PREFIX,
256- format_args!( $fmt, $( $arg) * ) ,
257- ) ;
258- }
259- ) ;
260188) ;
261189
262190// We could use a macro to generate these macros. However, doing so ends
0 commit comments