@@ -330,30 +330,42 @@ void *memmove(void *dst, const void *src, size_t n)
330330#endif /* WOLFBOOT_USE_STDLIBC */
331331
332332#if defined(PRINTF_ENABLED ) && defined(DEBUG_UART )
333- void uart_writenum (int num , int base , int zeropad , int maxdigits )
333+ /* The widest unsigned/signed types we'll format. With PRINTF_LONG_LONG
334+ * this is 64-bit (so %llu/%llx don't truncate); without, it's 32-bit
335+ * (no libgcc 64-bit divide pulled in for size-constrained targets). */
336+ #ifdef PRINTF_LONG_LONG
337+ typedef unsigned long long uart_writenum_uval ;
338+ typedef long long uart_writenum_sval ;
339+ #else
340+ typedef unsigned long uart_writenum_uval ;
341+ typedef long uart_writenum_sval ;
342+ #endif
343+
344+ /* Core: prints an already-absolute magnitude with an explicit
345+ * negative-sign flag. Bases up to 16. */
346+ static void uart_writenum_core (uart_writenum_uval val , int is_negative ,
347+ int base , int zeropad , int maxdigits )
334348{
335349 int i = 0 ;
336- char buf [sizeof (unsigned long )* 2 + 1 ];
350+ char buf [sizeof (uart_writenum_uval )* 2 + 2 ]; /* hex digits + sign + NUL */
337351 const char * kDigitLut = "0123456789ABCDEF" ;
338- unsigned int val = (unsigned int )num ;
339352 int sz = 0 ;
340353 if (maxdigits == 0 )
341354 maxdigits = 8 ;
342355 if (maxdigits > (int )sizeof (buf ))
343356 maxdigits = (int )sizeof (buf );
344357 memset (buf , 0 , sizeof (buf ));
345- if (base == 10 && num < 0 ) { /* handle negative */
358+ if (is_negative ) {
346359 buf [i ++ ] = '-' ;
347- val = - num ;
348360 }
349361 if (zeropad ) {
350362 memset (& buf [i ], '0' , maxdigits );
351363 }
352364 do {
353- buf [sizeof (buf )- sz - 1 ] = kDigitLut [(val % base )];
365+ buf [sizeof (buf )- sz - 1 ] = kDigitLut [(val % ( unsigned ) base )];
354366 sz ++ ;
355- val /= base ;
356- } while (val > 0U );
367+ val /= ( unsigned ) base ;
368+ } while (val > 0 );
357369 if (zeropad && sz < maxdigits ) {
358370 i += maxdigits - sz ;
359371 }
@@ -362,6 +374,20 @@ void uart_writenum(int num, int base, int zeropad, int maxdigits)
362374 uart_write (buf , i );
363375}
364376
377+ void uart_writenum (int num , int base , int zeropad , int maxdigits )
378+ {
379+ int is_neg = 0 ;
380+ uart_writenum_uval val ;
381+ if (base == 10 && num < 0 ) {
382+ is_neg = 1 ;
383+ val = (uart_writenum_uval )(- (uart_writenum_sval )num );
384+ }
385+ else {
386+ val = (uart_writenum_uval )(unsigned int )num ;
387+ }
388+ uart_writenum_core (val , is_neg , base , zeropad , maxdigits );
389+ }
390+
365391void uart_vprintf (const char * fmt , va_list argp )
366392{
367393 char * fmtp = (char * )fmt ;
@@ -434,9 +460,24 @@ void uart_vprintf(const char* fmt, va_list argp)
434460 {
435461 #ifdef PRINTF_LONG_LONG
436462 if (islong >= 2 ) {
437- /* %llu / %lld: consume 64-bit arg, print low 32 bits */
438- unsigned long long ll = va_arg (argp , unsigned long long);
439- uart_writenum ((int )(unsigned int )ll , 10 , zeropad , maxdigits );
463+ /* %llu / %lld: full 64-bit value */
464+ int is_neg = 0 ;
465+ uart_writenum_uval val ;
466+ if (* fmtp != 'u' ) {
467+ long long sll = va_arg (argp , long long );
468+ if (sll < 0 ) {
469+ is_neg = 1 ;
470+ val = (uart_writenum_uval )(- sll );
471+ }
472+ else {
473+ val = (uart_writenum_uval )sll ;
474+ }
475+ }
476+ else {
477+ val = (uart_writenum_uval )
478+ va_arg (argp , unsigned long long);
479+ }
480+ uart_writenum_core (val , is_neg , 10 , zeropad , maxdigits );
440481 }
441482 else
442483 #endif
@@ -454,9 +495,10 @@ void uart_vprintf(const char* fmt, va_list argp)
454495 {
455496 #ifdef PRINTF_LONG_LONG
456497 if (islong >= 2 ) {
457- /* %llx: consume 64-bit arg, print low 32 bits */
458- unsigned long long ll = va_arg (argp , unsigned long long);
459- uart_writenum ((int )(unsigned int )ll , 16 , zeropad , maxdigits );
498+ /* %llx: full 64-bit value */
499+ uart_writenum_uval val = (uart_writenum_uval )
500+ va_arg (argp , unsigned long long);
501+ uart_writenum_core (val , 0 , 16 , zeropad , maxdigits );
460502 }
461503 else
462504 #endif
0 commit comments