qemu/tests/tcg/s390x/trap.c
<<
>>
Prefs
   1/*
   2 * Copyright 2021 IBM Corp.
   3 *
   4 * This work is licensed under the terms of the GNU GPL, version 2 or (at
   5 * your option) any later version. See the COPYING file in the top-level
   6 * directory.
   7 */
   8
   9#include <stdarg.h>
  10#include <stdint.h>
  11#include <stdio.h>
  12#include <stdlib.h>
  13#include <unistd.h>
  14#include <errno.h>
  15#include <string.h>
  16#include <signal.h>
  17
  18static void error1(const char *filename, int line, const char *fmt, ...)
  19{
  20    va_list ap;
  21    va_start(ap, fmt);
  22    fprintf(stderr, "%s:%d: ", filename, line);
  23    vfprintf(stderr, fmt, ap);
  24    fprintf(stderr, "\n");
  25    va_end(ap);
  26    exit(1);
  27}
  28
  29static int __chk_error(const char *filename, int line, int ret)
  30{
  31    if (ret < 0) {
  32        error1(filename, line, "%m (ret=%d, errno=%d/%s)",
  33               ret, errno, strerror(errno));
  34    }
  35    return ret;
  36}
  37
  38#define error(fmt, ...) error1(__FILE__, __LINE__, fmt, ## __VA_ARGS__)
  39
  40#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret))
  41
  42int sigfpe_count;
  43int sigill_count;
  44
  45static void sig_handler(int sig, siginfo_t *si, void *puc)
  46{
  47    if (sig == SIGFPE) {
  48        if (si->si_code != 0) {
  49            error("unexpected si_code: 0x%x != 0", si->si_code);
  50        }
  51        ++sigfpe_count;
  52        return;
  53    }
  54
  55    if (sig == SIGILL) {
  56        ++sigill_count;
  57        return;
  58    }
  59
  60    error("unexpected signal 0x%x\n", sig);
  61}
  62
  63int main(int argc, char **argv)
  64{
  65    sigfpe_count = sigill_count = 0;
  66
  67    struct sigaction act;
  68
  69    /* Set up SIG handler */
  70    act.sa_sigaction = sig_handler;
  71    sigemptyset(&act.sa_mask);
  72    act.sa_flags = SA_SIGINFO;
  73    chk_error(sigaction(SIGFPE, &act, NULL));
  74    chk_error(sigaction(SIGILL, &act, NULL));
  75
  76    uint64_t z = 0x0ull;
  77    uint64_t lz = 0xffffffffffffffffull;
  78    asm volatile (
  79        "lg %%r13,%[lz]\n"
  80        "cgitne %%r13,0\n" /* SIGFPE */
  81        "lg %%r13,%[z]\n"
  82        "cgitne %%r13,0\n" /* no trap */
  83        "nopr\n"
  84        "lg %%r13,%[lz]\n"
  85        "citne %%r13,0\n" /* SIGFPE */
  86        "lg %%r13,%[z]\n"
  87        "citne %%r13,0\n" /* no trap */
  88        "nopr\n"
  89        :
  90        : [z] "m" (z), [lz] "m" (lz)
  91        : "memory", "r13");
  92
  93    if (sigfpe_count != 2) {
  94        error("unexpected SIGFPE count: %d != 2", sigfpe_count);
  95    }
  96    if (sigill_count != 0) {
  97        error("unexpected SIGILL count: %d != 0", sigill_count);
  98    }
  99
 100    printf("PASS\n");
 101    return 0;
 102}
 103