Index: lib/ubsan/ubsan_handlers.cc =================================================================== --- lib/ubsan/ubsan_handlers.cc +++ lib/ubsan/ubsan_handlers.cc @@ -660,6 +660,21 @@ if (!FName) FName = "(unknown)"; Diag(FLoc, DL_Note, ET, "%0 defined here") << FName; + + // If the failure occurred due to a cross-DSO icall, report the DSO names. + const char *DstModule = FLoc.get()->info.module; + if (!DstModule) + DstModule = "(unknown)"; + + SymbolizedStackHolder CalleeLoc(getCallerLocation(Opts.pc)); + const char *SrcModule = CalleeLoc.get()->info.module; + if (!SrcModule) + SrcModule = "(unknown)"; + + if (internal_strcmp(SrcModule, DstModule)) + Diag(CalleeLoc, DL_Note, ET, + "check failed in %0, destination function located in %1") + << SrcModule << DstModule; } namespace __ubsan { Index: test/cfi/icall/bad-cross-dso.c =================================================================== --- /dev/null +++ test/cfi/icall/bad-cross-dso.c @@ -0,0 +1,30 @@ +// Check that cross-DSO icalls diagnostics print the names of both modules + +// RUN: %clang -o %t1 %s -ldl +// RUN: %t1 2>&1 | FileCheck --check-prefix=NCFI %s + +// RUN: %clang_cfi -o %t2 %s -ldl +// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clang_cfi_diag -g -o %t3 %s -ldl +// RUN: %t3 2>&1 | FileCheck --check-prefix=CFI-DIAG %s + +#define _GNU_SOURCE // For RTLD_DEFAULT +#include +#include + +int main() { + // CFI: 1 + // NCFI: 1 + fprintf(stderr, "1\n"); + + // CFI-DIAG: runtime error: control flow integrity check for type 'void (int)' failed during indirect function call + // CFI-DIAG: getpid defined here + // CFI-DIAG: check failed in {{.*}}, destination function located in {{.*}} + void (*fp)(int) = dlsym(RTLD_DEFAULT, "getpid"); + fp(1); // UB here + + // CFI-NOT: 2 + // NCFI: 2 + fprintf(stderr, "2\n"); +}