diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp @@ -20,6 +20,10 @@ #include #include +#if defined(__x86_64__) +# include +#endif + #if SANITIZER_WINDOWS && defined(_MSC_VER) && _MSC_VER < 1800 && \ !defined(va_copy) # define va_copy(dst, src) ((dst) = (src)) @@ -162,17 +166,15 @@ cur += have_z; bool have_ll = !have_z && (cur[0] == 'l' && cur[1] == 'l'); cur += have_ll * 2; - s64 dval; - u64 uval; const bool have_length = have_z || have_ll; const bool have_flags = have_width || have_length; // At the moment only %s supports precision and left-justification. CHECK(!((precision >= 0 || left_justified) && *cur != 's')); switch (*cur) { case 'd': { - dval = have_ll ? va_arg(args, s64) - : have_z ? va_arg(args, sptr) - : va_arg(args, int); + s64 dval = have_ll ? va_arg(args, s64) + : have_z ? va_arg(args, sptr) + : va_arg(args, int); result += AppendSignedDecimal(&buff, buff_end, dval, width, pad_with_zero); break; @@ -180,14 +182,24 @@ case 'u': case 'x': case 'X': { - uval = have_ll ? va_arg(args, u64) - : have_z ? va_arg(args, uptr) - : va_arg(args, unsigned); + u64 uval = have_ll ? va_arg(args, u64) + : have_z ? va_arg(args, uptr) + : va_arg(args, unsigned); bool uppercase = (*cur == 'X'); result += AppendUnsigned(&buff, buff_end, uval, (*cur == 'u') ? 10 : 16, width, pad_with_zero, uppercase); break; } +#if defined(__x86_64__) + case 'V': { + __m128i v = va_arg(args, __m128i); + u8 x[sizeof(v)]; + internal_memcpy(x, &v, sizeof(x)); + for (uptr i = 0; i < sizeof(x); i++) + result += AppendUnsigned(&buff, buff_end, x[i], 16, 2, true, false); + break; + } +#endif case 'p': { RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp); result += AppendPointer(&buff, buff_end, va_arg(args, uptr)); diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_printf_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_printf_test.cpp --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_printf_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_printf_test.cpp @@ -16,6 +16,10 @@ #include #include +#ifdef __x86_64__ +# include +#endif + namespace __sanitizer { TEST(Printf, Basic) { @@ -154,4 +158,18 @@ EXPECT_STREQ("12345 ", buf); } +#ifdef __x86_64__ +TEST(Printf, M128) { + __m128i v = _mm_set_epi32(0x12345678, 0x0a0a0a0a, 0xb0b0b0b0, 0xaabbccdd); + char buf[128]; + internal_snprintf(buf, sizeof(buf), "%V", v); + EXPECT_STREQ("ddccbbaab0b0b0b00a0a0a0a78563412", buf); + v = _mm_cvtsi32_si128(0x12345678); + internal_snprintf(buf, sizeof(buf), "%V", v); + EXPECT_STREQ("78563412000000000000000000000000", buf); + internal_snprintf(buf, sizeof(buf), "%d %V", 0, v); + EXPECT_STREQ("0 78563412000000000000000000000000", buf); +} +#endif + } // namespace __sanitizer