/*
 * Copyright © 2015 Raspberry Pi Foundation
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of the copyright holders not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  The copyright holders make no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "utils.h"


#if FENCE_MALLOC_ACTIVE && defined (HAVE_SIGACTION)

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

pixman_bool_t verbose;

static void
segv_handler (int sig, siginfo_t *si, void *unused)
{
    _exit (EXIT_SUCCESS);
}

static void
die (const char *msg, int err)
{
    if (err)
        perror (msg);
    else
        fprintf (stderr, "%s\n", msg);

    abort ();
}

static void
prinfo (const char *fmt, ...)
{
    va_list ap;

    if (!verbose)
        return;

    va_start (ap, fmt);
    vfprintf (stderr, fmt, ap);
    va_end (ap);
}

static void
do_expect_segv (void (*fn)(void *), void *data)
{
    struct sigaction sa;

    sa.sa_flags = SA_SIGINFO;
    sigemptyset (&sa.sa_mask);
    sa.sa_sigaction = segv_handler;
    if (sigaction (SIGSEGV, &sa, NULL) == -1)
        die ("sigaction failed", errno);

    (*fn)(data);

    _exit (EXIT_FAILURE);
}

/* Check that calling fn(data) causes a segmentation fault.
 *
 * You cannot portably return from a SIGSEGV handler in any way,
 * so we fork, and do the test in the child process. Child's
 * exit status will reflect the result. Its SEGV handler causes it
 * to exit with success, and return failure otherwise.
 */
static pixman_bool_t
expect_segv (void (*fn)(void *), void *data)
{
    pid_t pid, wp;
    int status;

    pid = fork ();
    if (pid == -1)
        die ("fork failed", errno);

    if (pid == 0)
        do_expect_segv (fn, data); /* never returns */

    wp = waitpid (pid, &status, 0);
    if (wp != pid)
        die ("waitpid did not work", wp == -1 ? errno : 0);

    if (WIFEXITED (status) && WEXITSTATUS (status) == EXIT_SUCCESS)
        return TRUE;

    return FALSE;
}

static void
read_u8 (void *data)
{
    volatile uint8_t *p = data;

    *p;
}

static pixman_bool_t
test_read_fault (uint8_t *p, int offset)
{
    prinfo ("*(uint8_t *)(%p + %d)", p, offset);

    if (expect_segv (read_u8, p + offset))
    {
        prinfo ("\tSEGV OK\n");

        return TRUE;
    }

    prinfo ("\tFAILED\n");

    return FALSE;
}

static void
test_read_ok (uint8_t *p, int offset)
{
    prinfo ("*(uint8_t *)(%p + %d)", p, offset);

    /* If fails, SEGV. */
    read_u8 (p + offset);

    prinfo ("\tOK\n");
}

static pixman_bool_t
test_read_faults (pixman_image_t *image)
{
    pixman_bool_t ok = TRUE;
    pixman_format_code_t format = pixman_image_get_format (image);
    int width = pixman_image_get_width (image);
    int height = pixman_image_get_height (image);
    int stride = pixman_image_get_stride (image);
    uint8_t *p = (void *)pixman_image_get_data (image);
    int row_bytes = width * PIXMAN_FORMAT_BPP (format) / 8;

    prinfo ("%s %dx%d, row %d B, stride %d B:\n",
            format_name (format), width, height, row_bytes, stride);

    assert (height > 3);

    test_read_ok (p, 0);
    test_read_ok (p, row_bytes - 1);
    test_read_ok (p, stride);
    test_read_ok (p, stride + row_bytes - 1);
    test_read_ok (p, 2 * stride);
    test_read_ok (p, 2 * stride + row_bytes - 1);
    test_read_ok (p, 3 * stride);
    test_read_ok (p, (height - 1) * stride + row_bytes - 1);

    ok &= test_read_fault (p, -1);
    ok &= test_read_fault (p, row_bytes);
    ok &= test_read_fault (p, stride - 1);
    ok &= test_read_fault (p, stride + row_bytes);
    ok &= test_read_fault (p, 2 * stride - 1);
    ok &= test_read_fault (p, 2 * stride + row_bytes);
    ok &= test_read_fault (p, 3 * stride - 1);
    ok &= test_read_fault (p, height * stride);

    return ok;
}

static pixman_bool_t
test_image_faults (pixman_format_code_t format, int min_width, int height)
{
    pixman_bool_t ok;
    pixman_image_t *image;

    image = fence_image_create_bits (format, min_width, height, TRUE);
    ok = test_read_faults (image);
    pixman_image_unref (image);

    return ok;
}

int
main (int argc, char **argv)
{
    pixman_bool_t ok = TRUE;

    if (getenv ("VERBOSE") != NULL)
        verbose = TRUE;

    ok &= test_image_faults (PIXMAN_a8r8g8b8, 7, 5);
    ok &= test_image_faults (PIXMAN_r8g8b8, 7, 5);
    ok &= test_image_faults (PIXMAN_r5g6b5, 7, 5);
    ok &= test_image_faults (PIXMAN_a8, 7, 5);
    ok &= test_image_faults (PIXMAN_a4, 7, 5);
    ok &= test_image_faults (PIXMAN_a1, 7, 5);

    if (ok)
        return EXIT_SUCCESS;

    return EXIT_FAILURE;
}

#else /* FENCE_MALLOC_ACTIVE */

int
main (int argc, char **argv)
{
    /* Automake return code for test SKIP. */
    return 77;
}

#endif /* FENCE_MALLOC_ACTIVE */
