From c0207cd846900bac466e8cbcbdfd106725025e4b Mon Sep 17 00:00:00 2001 From: Sylvain BERTRAND Date: Sun, 7 Jan 2024 13:17:28 +0000 Subject: [PATCH] switch the fatal error path to put_string --- linux/arch/x64/vsnprintf/directives_split_format.S | 17 +++++++++-------- linux/arch/x64/vsnprintf/entry.S | 10 ++++++++++ linux/arch/x64/vsnprintf/exit.S | 13 ------------- .../finish_directives__auto_incremented_argument_mode.S | 2 +- .../finish_directives__numbered_argument_mode.S | 10 +++++----- 5 files changed, 25 insertions(+), 27 deletions(-) diff --git a/linux/arch/x64/vsnprintf/directives_split_format.S b/linux/arch/x64/vsnprintf/directives_split_format.S index bd584d5..0c90caa 100644 --- a/linux/arch/x64/vsnprintf/directives_split_format.S +++ b/linux/arch/x64/vsnprintf/directives_split_format.S @@ -51,7 +51,7 @@ LLL(load_specifications_char): mov FORMAT_CHAR,byte ptr [FORMAT] // do we hit the end of the format test FORMAT_CHAR,FORMAT_CHAR - jz L(write_empty_string) // ERROR:unfinished conversion directive + jz L(put_string) // ERROR:unfinished conversion directive //------------------------------------------------------------------------------------------ test STATE,CD_STATE__PRECISION_FOUND // if we got already a precision marker, just scan for the numbered argument mode marker jnz LLL(numbered_argument_mode) @@ -102,7 +102,7 @@ LLLL(h_hh): inc FORMAT mov FORMAT_CHAR,byte ptr [FORMAT] test FORMAT,FORMAT - jz L(write_empty_string) // ERROR:unfinished conversion directive + jz L(put_string) // ERROR:unfinished conversion directive cmp FORMAT_CHAR,0x68 // 'h' jne LLL(test_is_conversion_specifier) // then this char must be a conversion specifier add STATE,CD_STATE__LENGTH_MODIFIER__h @@ -116,7 +116,7 @@ LLLL(l_ll): inc FORMAT mov FORMAT_CHAR,byte ptr [FORMAT] test FORMAT,FORMAT - jz L(write_empty_string) // ERROR:unfinished conversion directive + jz L(put_string) // ERROR:unfinished conversion directive cmp FORMAT_CHAR,0x6c // 'l' jne LLL(test_is_conversion_specifier) // then this char must be a conversion specifier add STATE,CD_STATE__LENGTH_MODIFIER__l @@ -152,14 +152,14 @@ LLL(next_char_must_be_a_conversion_specifier): inc FORMAT mov FORMAT_CHAR,byte ptr [FORMAT] test FORMAT_CHAR,FORMAT_CHAR - jz L(write_empty_string) // ERROR:unfinished conversion directive + jz L(put_string) // ERROR:unfinished conversion directive LLL(test_is_conversion_specifier): mov cl,FORMAT_CHAR sub cl,0x41 // 'A' // see the bitmap tables of chars test cl,-64 // warp around and mod 64 - jnz L(write_empty_string) + jnz L(put_string) bt CONV_SPECIFIERS_CHARS_BITMAP,rcx - jnc L(write_empty_string) // ERROR:unknown conversion specifier + jnc L(put_string) // ERROR:unknown conversion specifier ASM_ALIGN_NOPS(CODE_FETCH_BYTES_N_LOG2) LLL(conversion_specifier_copy): or STATE_b,FORMAT_CHAR @@ -177,7 +177,9 @@ LL(percent_directive): // rare //-------------------------------------------------------------------------------------------------- ASM_ALIGN_NOPS(CODE_FETCH_BYTES_N_LOG2) LL(format_terminating_zero): - mov GLOBALS_FORMAT_END,FORMAT + // XXX: we already did look for GLOBALS_FORMAT_END on function entry in order to enable + // our fatal error path. + //mov GLOBALS_FORMAT_END,FORMAT #undef CONV_SPECIFIERS_CHARS_BITMAP #undef LENGTH_MODIFIERS_CHARS_BITMAP #undef FORMAT @@ -188,4 +190,3 @@ LL(format_terminating_zero): #undef STATE_b #undef LL // directives_split_format // FALL-THRU - diff --git a/linux/arch/x64/vsnprintf/entry.S b/linux/arch/x64/vsnprintf/entry.S index 06c93a8..8b39ea9 100644 --- a/linux/arch/x64/vsnprintf/entry.S +++ b/linux/arch/x64/vsnprintf/entry.S @@ -22,3 +22,13 @@ ASM_GLOBAL_FUNCTION(vsnprintf) mov GLOBALS_VA_LIST_FLOATS_IN_REGS,rax // the number of floats in [xyz]mm registers, up to 8 (ABI may have been update, but only in gcc/clang), up to 8 (ABI may have been update, but only in gcc/clang). mov GLOBALS_CONV_DIRECTIVES_N,0 xor GLOBAL_STATE,GLOBAL_STATE +//-------------------------------------------------------------------------------------------------- + // We are going to lookup for the end of the format, excluding the 0 terminating byte, in + // order to enable our put_string right now for our fatal error path. + mov rdi,rdx + xor al,al + or rcx,-1 + repne scasb // we must find the 0 terminating byte + // here, rdi point past the 0 terminating byte + dec rdi + mov GLOBALS_FORMAT_END,rdi diff --git a/linux/arch/x64/vsnprintf/exit.S b/linux/arch/x64/vsnprintf/exit.S index 4da1720..3a2df98 100644 --- a/linux/arch/x64/vsnprintf/exit.S +++ b/linux/arch/x64/vsnprintf/exit.S @@ -7,16 +7,3 @@ L(exit): mov r15,GLOBALS_R15_SAVE leave // restores RBP and RSP ret - -L(write_empty_string): - //DEBUG - mov rax,0xdeadbeef - DBGHEXNL(rax) - xor eax,eax // 0 chars, excluding the terminating 0 char - mov rcx,GLOBALS_N - test rcx,rcx - jz L(exit) - // here we have a buffer of at least 1 byte - mov rcx,GLOBALS_S - mov byte ptr [rcx],0 // terminating 0 char - jmp L(exit) diff --git a/linux/arch/x64/vsnprintf/finish_directives__auto_incremented_argument_mode.S b/linux/arch/x64/vsnprintf/finish_directives__auto_incremented_argument_mode.S index e645605..e093e45 100644 --- a/linux/arch/x64/vsnprintf/finish_directives__auto_incremented_argument_mode.S +++ b/linux/arch/x64/vsnprintf/finish_directives__auto_incremented_argument_mode.S @@ -31,7 +31,7 @@ LLL(next_format_char): LLL(load_next_format_char): mov FLAG_CHAR,byte ptr [FLAG] test FLAG_CHAR,FLAG_CHAR - jz L(write_empty_string) // ERROR:unfinished conversion directive + jz L(put_string) // ERROR:unfinished conversion directive mov cl,FLAG_CHAR sub cl,0x20 // ' ' test cl,-64 // warp around and mod 64 diff --git a/linux/arch/x64/vsnprintf/finish_directives__numbered_argument_mode.S b/linux/arch/x64/vsnprintf/finish_directives__numbered_argument_mode.S index 0cf7707..17cba3e 100644 --- a/linux/arch/x64/vsnprintf/finish_directives__numbered_argument_mode.S +++ b/linux/arch/x64/vsnprintf/finish_directives__numbered_argument_mode.S @@ -25,10 +25,10 @@ LL(load_directive_state): mov rsi,rdi // make a copy for later mov rcx,qword ptr [ST_CONV_DIRECTIVE+CD_SPECIFIER] // our "end" for scanning the '$' char sub rcx,rdi // max chars to scan - jz L(write_empty_string) // no room for even '$', bail out + jz L(put_string) // no room for even '$', bail out mov al,0x24 // '$' repne scasb // we did ensure we have at least 1 char to scan - jne L(write_empty_string) // failed to find the mandatory '$', bail out + jne L(put_string) // failed to find the mandatory '$', bail out // Here, rdi points past the found '$' mov PREVIOUS_SPECIFICATION_END,rdi // keep that for the following flags decoder dec rdi // make '$' the end pointer for the following decimal string conversion @@ -58,7 +58,7 @@ LLL(next_format_char): LLL(load_next_format_char): mov FLAG_CHAR,byte ptr [FLAG] test FLAG_CHAR,FLAG_CHAR - jz L(write_empty_string) // ERROR:unfinished conversion directive + jz L(put_string) // ERROR:unfinished conversion directive mov cl,FLAG_CHAR sub cl,0x20 // ' ' test cl,-64 // warp around and mod 64 @@ -161,7 +161,7 @@ LLL(no_update): // We did check only for a width of 1 char which is not enough cmp WIDTH_END,WIDTH_START - jbe L(write_empty_string) // invalid width argument number, bail out + jbe L(put_string) // invalid width argument number, bail out //------------------------------------------------------------------------------------------ LLL(convert): // nocheck decimal string conversion, inputs are properly setup @@ -220,7 +220,7 @@ LLL(epilog): // We did check only for a width of 1 char which is not enough cmp PRECISION_END,PRECISION_START - jbe L(write_empty_string) // invalid precision argument number (this is _not_ the same as being empty), bail out + jbe L(put_string) // invalid precision argument number (this is _not_ the same as being empty), bail out //------------------------------------------------------------------------------------------ LLL(convert): // nocheck decimal string conversion, inputs are properly setup -- 2.11.4.GIT