Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

101 lines
3.0 KiB
C++

//===-- ubsan_loop_detect.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Runtime support for -fsanitize-trap-loop.
//
//===----------------------------------------------------------------------===//
#include <sanitizer/ubsan_interface.h>
#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
#include <asm/processor-flags.h>
#include <signal.h>
#include <stdint.h>
#include <sys/time.h>
#include <sys/ucontext.h>
int __ubsan_is_trap_loop(void *c) {
auto *uc = reinterpret_cast<ucontext_t *>(c);
#if defined(__x86_64__)
auto *ip = reinterpret_cast<const uint8_t *>(uc->uc_mcontext.gregs[REG_RIP]);
#else
auto *ip = reinterpret_cast<const uint8_t *>(uc->uc_mcontext.gregs[REG_EIP]);
#endif
// Test whether IP is at a conditional branch to self instruction.
if ((ip[0] & 0xf0) != 0x70 || ip[1] != 0xfe)
return false;
// If so, test whether the condition is satisfied, in case we happened to
// receive the signal at a not-taken branch to self.
uint64_t eflags = uc->uc_mcontext.gregs[REG_EFL];
switch (ip[0]) {
case 0x70: // JO
return eflags & X86_EFLAGS_OF;
case 0x71: // JNO
return !(eflags & X86_EFLAGS_OF);
case 0x72: // JB
return eflags & X86_EFLAGS_CF;
case 0x73: // JAE
return !(eflags & X86_EFLAGS_CF);
case 0x74: // JE
return eflags & X86_EFLAGS_ZF;
case 0x75: // JNE
return !(eflags & X86_EFLAGS_ZF);
case 0x76: // JBE
return (eflags & X86_EFLAGS_CF) || (eflags & X86_EFLAGS_ZF);
case 0x77: // JA
return !(eflags & X86_EFLAGS_CF) && !(eflags & X86_EFLAGS_ZF);
case 0x78: // JS
return eflags & X86_EFLAGS_SF;
case 0x79: // JNS
return !(eflags & X86_EFLAGS_SF);
case 0x7A: // JP
return eflags & X86_EFLAGS_PF;
case 0x7B: // JNP
return !(eflags & X86_EFLAGS_PF);
case 0x7C: // JL
return !!(eflags & X86_EFLAGS_SF) != !!(eflags & X86_EFLAGS_OF);
case 0x7D: // JGE
return !!(eflags & X86_EFLAGS_SF) == !!(eflags & X86_EFLAGS_OF);
case 0x7E: // JLE
return (eflags & X86_EFLAGS_ZF) ||
!!(eflags & X86_EFLAGS_SF) != !!(eflags & X86_EFLAGS_OF);
case 0x7F: // JG
return !(eflags & X86_EFLAGS_ZF) &&
!!(eflags & X86_EFLAGS_SF) == !!(eflags & X86_EFLAGS_OF);
default:
return false;
}
}
static void SigprofHandler(int signo, siginfo_t *si, void *c) {
if (__ubsan_is_trap_loop(c)) {
__builtin_trap();
}
}
void __ubsan_install_trap_loop_detection(void) {
struct sigaction sa;
sa.sa_sigaction = SigprofHandler;
sigaction(SIGPROF, &sa, nullptr);
struct itimerval timer;
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 100000;
timer.it_interval = timer.it_value;
setitimer(ITIMER_PROF, &timer, NULL);
}
#else
int __ubsan_is_trap_loop(void *c) { return false; }
void __ubsan_install_trap_loop_detection(void) {}
#endif