From: Igor Kudrin Date: Mon, 15 Aug 2022 18:24:08 +0000 (+0400) Subject: [ubsan-minimal] Report the address of an error X-Git-Tag: upstream/17.0.6~34408 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=84c4efbc6d61ec2bed9e9bc64b5829b4487b210c;p=platform%2Fupstream%2Fllvm.git [ubsan-minimal] Report the address of an error This implements a FIXME in the runtime library and adds printing the address at the end of the message as "by 0x123abc". The buffer for the message is allocated on the stack in a handler, so the stack memory consumption is slightly increased. No additional external dependencies are added. Differential revision: https://reviews.llvm.org/D131914 --- diff --git a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp index 5301a51..53a3273 100644 --- a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp +++ b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp @@ -51,6 +51,19 @@ __attribute__((noinline)) static bool report_this_error(uintptr_t caller) { } } +__attribute__((noinline)) static void decorate_msg(char *buf, + uintptr_t caller) { + // print the address by nibbles + for (unsigned shift = sizeof(uintptr_t) * 8; shift;) { + shift -= 4; + unsigned nibble = (caller >> shift) & 0xf; + *(buf++) = nibble < 10 ? nibble + '0' : nibble - 10 + 'a'; + } + // finish the message + buf[0] = '\n'; + buf[1] = '\0'; +} + #if defined(__ANDROID__) extern "C" __attribute__((weak)) void android_set_abort_message(const char *); static void abort_with_message(const char *msg) { @@ -76,18 +89,28 @@ void NORETURN CheckFailed(const char *file, int, const char *cond, u64, u64) { #define INTERFACE extern "C" __attribute__((visibility("default"))) -// FIXME: add caller pc to the error message (possibly as "ubsan: error-type -// @1234ABCD"). +// How many chars we need to reserve to print an address. +constexpr unsigned kAddrBuf = SANITIZER_WORDSIZE / 4; +#define MSG_TMPL(msg) "ubsan: " msg " by 0x" +#define MSG_TMPL_END(buf, msg) (buf + sizeof(MSG_TMPL(msg)) - 1) +// Reserve an additional byte for '\n'. +#define MSG_BUF_LEN(msg) (sizeof(MSG_TMPL(msg)) + kAddrBuf + 1) + #define HANDLER_RECOVER(name, msg) \ INTERFACE void __ubsan_handle_##name##_minimal() { \ - if (!report_this_error(GET_CALLER_PC())) return; \ - message("ubsan: " msg "\n"); \ + uintptr_t caller = GET_CALLER_PC(); \ + if (!report_this_error(caller)) return; \ + char msg_buf[MSG_BUF_LEN(msg)] = MSG_TMPL(msg); \ + decorate_msg(MSG_TMPL_END(msg_buf, msg), caller); \ + message(msg_buf); \ } #define HANDLER_NORECOVER(name, msg) \ INTERFACE void __ubsan_handle_##name##_minimal_abort() { \ - message("ubsan: " msg "\n"); \ - abort_with_message("ubsan: " msg); \ + char msg_buf[MSG_BUF_LEN(msg)] = MSG_TMPL(msg); \ + decorate_msg(MSG_TMPL_END(msg_buf, msg), GET_CALLER_PC()); \ + message(msg_buf); \ + abort_with_message(msg_buf); \ } #define HANDLER(name, msg) \ diff --git a/compiler-rt/test/ubsan_minimal/TestCases/alignment-assumption.c b/compiler-rt/test/ubsan_minimal/TestCases/alignment-assumption.c index 08696c8..acc3e85 100644 --- a/compiler-rt/test/ubsan_minimal/TestCases/alignment-assumption.c +++ b/compiler-rt/test/ubsan_minimal/TestCases/alignment-assumption.c @@ -8,7 +8,7 @@ int main(int argc, char *argv[]) { void *t = __builtin_assume_aligned(ptr + 1, 0x8000); (void)t; - // CHECK: ubsan: alignment-assumption + // CHECK: ubsan: alignment-assumption by 0x{{[[:xdigit:]]+$}} // CHECK-NOT: alignment-assumption free(ptr); diff --git a/compiler-rt/test/ubsan_minimal/TestCases/implicit-integer-sign-change.c b/compiler-rt/test/ubsan_minimal/TestCases/implicit-integer-sign-change.c index 1e20892..0f1bbbf 100644 --- a/compiler-rt/test/ubsan_minimal/TestCases/implicit-integer-sign-change.c +++ b/compiler-rt/test/ubsan_minimal/TestCases/implicit-integer-sign-change.c @@ -10,7 +10,7 @@ int main() { // Positive tests. int32_t t0 = (~((uint32_t)0)); -// CHECK: implicit-conversion +// CHECK: implicit-conversion by 0x{{[[:xdigit:]]+$}} // CHECK-NOT: implicit-conversion return 0; diff --git a/compiler-rt/test/ubsan_minimal/TestCases/implicit-signed-integer-truncation-or-sign-change.c b/compiler-rt/test/ubsan_minimal/TestCases/implicit-signed-integer-truncation-or-sign-change.c index 3a72a40..e9f26dd 100644 --- a/compiler-rt/test/ubsan_minimal/TestCases/implicit-signed-integer-truncation-or-sign-change.c +++ b/compiler-rt/test/ubsan_minimal/TestCases/implicit-signed-integer-truncation-or-sign-change.c @@ -10,7 +10,7 @@ int main() { // Positive tests. int8_t t0 = (uint32_t)-1; -// CHECK: implicit-conversion +// CHECK: implicit-conversion by 0x{{[[:xdigit:]]+$}} // CHECK-NOT: implicit-conversion return 0; diff --git a/compiler-rt/test/ubsan_minimal/TestCases/implicit-signed-integer-truncation.c b/compiler-rt/test/ubsan_minimal/TestCases/implicit-signed-integer-truncation.c index 9677407..dc8d775 100644 --- a/compiler-rt/test/ubsan_minimal/TestCases/implicit-signed-integer-truncation.c +++ b/compiler-rt/test/ubsan_minimal/TestCases/implicit-signed-integer-truncation.c @@ -18,7 +18,7 @@ int main() { // Positive tests. uint8_t t0 = (int32_t)(-1); -// CHECK: implicit-conversion +// CHECK: implicit-conversion by 0x{{[[:xdigit:]]+$}} // CHECK-NOT: implicit-conversion return 0; diff --git a/compiler-rt/test/ubsan_minimal/TestCases/implicit-unsigned-integer-truncation.c b/compiler-rt/test/ubsan_minimal/TestCases/implicit-unsigned-integer-truncation.c index 8b9e166..77d38f5 100644 --- a/compiler-rt/test/ubsan_minimal/TestCases/implicit-unsigned-integer-truncation.c +++ b/compiler-rt/test/ubsan_minimal/TestCases/implicit-unsigned-integer-truncation.c @@ -18,7 +18,7 @@ int main() { // Positive tests. uint8_t t0 = (~((uint32_t)(0))); -// CHECK: implicit-conversion +// CHECK: implicit-conversion by 0x{{[[:xdigit:]]+$}} // CHECK-NOT: implicit-conversion return 0; diff --git a/compiler-rt/test/ubsan_minimal/TestCases/nullptr-and-nonzero-offset.c b/compiler-rt/test/ubsan_minimal/TestCases/nullptr-and-nonzero-offset.c index 699aeee..2077e7d 100644 --- a/compiler-rt/test/ubsan_minimal/TestCases/nullptr-and-nonzero-offset.c +++ b/compiler-rt/test/ubsan_minimal/TestCases/nullptr-and-nonzero-offset.c @@ -8,16 +8,16 @@ int main(int argc, char *argv[]) { base = (char *)0; result = base + 0; - // CHECK-C: pointer-overflow + // CHECK-C: pointer-overflow by 0x{{[[:xdigit:]]+$}} // CHECK-CPP-NOT: pointer-overflow base = (char *)0; result = base + 1; - // CHECK: pointer-overflow + // CHECK: pointer-overflow by 0x{{[[:xdigit:]]+$}} base = (char *)1; result = base - 1; - // CHECK: pointer-overflow + // CHECK: pointer-overflow by 0x{{[[:xdigit:]]+$}} return 0; } diff --git a/compiler-rt/test/ubsan_minimal/TestCases/recover-dedup.cpp b/compiler-rt/test/ubsan_minimal/TestCases/recover-dedup.cpp index 4dfd699..b7c9ddc 100644 --- a/compiler-rt/test/ubsan_minimal/TestCases/recover-dedup.cpp +++ b/compiler-rt/test/ubsan_minimal/TestCases/recover-dedup.cpp @@ -4,25 +4,25 @@ #include int *_Nonnull h() { - // CHECK: nullability-return + // CHECK: nullability-return by 0x{{[[:xdigit:]]+$}} return NULL; } __attribute__((returns_nonnull)) int *i() { - // CHECK: nonnull-return + // CHECK: nonnull-return by 0x{{[[:xdigit:]]+$}} return NULL; } __attribute__((noinline)) int f(int x, int y) { - // CHECK: mul-overflow + // CHECK: mul-overflow by 0x{{[[:xdigit:]]+$}} return x * y; } __attribute__((noinline)) int g(int x, int y) { - // CHECK: mul-overflow + // CHECK: mul-overflow by 0x{{[[:xdigit:]]+$}} return x * (y + 1); } diff --git a/compiler-rt/test/ubsan_minimal/TestCases/uadd-overflow.cpp b/compiler-rt/test/ubsan_minimal/TestCases/uadd-overflow.cpp index 0345750..4ae081c 100644 --- a/compiler-rt/test/ubsan_minimal/TestCases/uadd-overflow.cpp +++ b/compiler-rt/test/ubsan_minimal/TestCases/uadd-overflow.cpp @@ -6,5 +6,5 @@ int main() { uint32_t k = 0x87654321; k += 0xedcba987; - // CHECK: add-overflow + // CHECK: add-overflow by 0x{{[[:xdigit:]]+$}} }