#include <setjmp.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "func.inc"

typedef void (*PfnVoid)(void);

#define MEMCPY_TEST(where) \
	memcpy(in_##where, in_code, sizeof(in_code)); \
	test(#where, (PfnVoid)in_##where)

static jmp_buf env;
static int received_sigill = 0;
static void on_sigill(int sig)
{
  printf(" on_sigill=%d ", sig);
  received_sigill = 1;
  longjmp(env, 1);
}

static void test(const char* name, PfnVoid code)
{
  printf("%8p is %s ... ", code, name);
  fflush(stdout);
  received_sigill = 0;
  if (0 == setjmp(env))
  {
    signal(SIGILL, on_sigill);
    code();
  }
  printf(" sigill=%d\n", received_sigill);
}

static char in_data[sizeof(in_code)];

int main()
{
  char* in_heap = malloc(sizeof(in_code));
  char in_stack[sizeof(in_code)];

  test("code", (PfnVoid)in_code);
  MEMCPY_TEST(data);
  MEMCPY_TEST(heap);
  MEMCPY_TEST(stack);
  return 0;
}
