blob: 1b8f0dea0057717bbcb3c10b64f418e74b7304f1 [file] [log] [blame]
/*
* Copyright (c) 2012 The Native Client Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef NATIVE_CLIENT_TESTS_SIGNAL_HANDLER_SINGLE_STEP_STEP_TEST_COMMON_H_
#define NATIVE_CLIENT_TESTS_SIGNAL_HANDLER_SINGLE_STEP_STEP_TEST_COMMON_H_
#include <unistd.h>
#include "native_client/src/include/build_config.h"
#include "native_client/src/include/nacl_compiler_annotations.h"
#include "native_client/src/include/portability.h"
#include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h"
#include "native_client/src/trusted/service_runtime/nacl_signal.h"
#if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
/* Start single-stepping by setting the trap flag (bit 8). */
static INLINE void SetTrapFlag(void) {
__asm__("pushf\n"
#if NACL_BUILD_SUBARCH == 32
"btsl $8, (%esp)\n"
#else
"btsq $8, (%rsp)\n"
#endif
"popf\n");
}
/* Stop single-stepping by unsetting the trap flag (bit 8). */
static INLINE void UnsetTrapFlag(void) {
__asm__("pushf\n"
#if NACL_BUILD_SUBARCH == 32
"btrl $8, (%esp)\n"
#else
"btrq $8, (%rsp)\n"
#endif
"popf\n");
}
static INLINE uintptr_t GetTrapFlag(void) {
uintptr_t flags;
#if NACL_BUILD_SUBARCH == 32
__asm__("pushf\n"
"popl %0\n" : "=r"(flags));
#else
__asm__("pushf\n"
"popq %0\n" : "=r"(flags));
#endif
return (flags & NACL_X86_TRAP_FLAG) != 0;
}
#endif
static INLINE void SignalSafeWrite(const void *buf, size_t size) {
if (write(2, buf, size) != (ssize_t) size) {
/*
* This error handling is largely because glibc's
* warn_unused_result annotation requires us to do a check.
*/
_exit(1);
}
}
#define SignalSafeLogStringLiteral(string) \
SignalSafeWrite(string, sizeof(string) - 1)
/*
* This is used by both untrusted and trusted code so we use
* explicitly-sized types for the fields.
*/
struct RegsTestShm {
uint32_t *regs_should_match; /* Pointer to boolean */
struct NaClSignalContext expected_regs;
};
#endif