Skip to content

Commit

Permalink
1.0.0.32: support for FreeBSD/x86-64
Browse files Browse the repository at this point in the history
  • Loading branch information
sa2c committed Dec 15, 2006
1 parent 4efb45c commit bd45534
Show file tree
Hide file tree
Showing 18 changed files with 350 additions and 34 deletions.
1 change: 1 addition & 0 deletions NEWS
@@ -1,5 +1,6 @@
;;;; -*- coding: utf-8; -*-
changes in sbcl-1.0.1 relative to sbcl-1.0:
* new platform: FreeBSD/x86-64, including support for threading.
* new feature: the compiler stores cross-referencing information
abount function calls (who-calls), macroexpansion (who-macroexpands)
and special variables (who-binds, who-sets, who-references) for code
Expand Down
1 change: 1 addition & 0 deletions make-config.sh
Expand Up @@ -102,6 +102,7 @@ case `uname -m` in
*86) guessed_sbcl_arch=x86 ;;
i86pc) guessed_sbcl_arch=x86 ;;
*x86_64) guessed_sbcl_arch=x86-64 ;;
amd64) guessed_sbcl_arch=x86-64 ;;
[Aa]lpha) guessed_sbcl_arch=alpha ;;
sparc*) guessed_sbcl_arch=sparc ;;
sun*) guessed_sbcl_arch=sparc ;;
Expand Down
25 changes: 25 additions & 0 deletions src/runtime/Config.x86-64-bsd
@@ -0,0 +1,25 @@
# -*- makefile -*- for the C-level run-time support for SBCL
# configuration stuff shared between various *BSD OSes

# This software is part of the SBCL system. See the README file for
# more information.
#
# This software is derived from the CMU CL system, which was
# written at Carnegie Mellon University and released into the
# public domain. The software is in the public domain and is
# provided with absolutely no warranty. See the COPYING and CREDITS
# files for more information.

ASSEM_SRC = x86-64-assem.S
ARCH_SRC = x86-64-arch.c

OS_SRC = bsd-os.c x86-64-bsd-os.c
OS_LIBS = # -ldl

CFLAGS += -fno-omit-frame-pointer

GC_SRC = gencgc.c

# Nothing to do for after-grovel-headers.
.PHONY: after-grovel-headers
after-grovel-headers:
26 changes: 26 additions & 0 deletions src/runtime/Config.x86-64-freebsd
@@ -0,0 +1,26 @@
# -*- makefile -*- for the C-level run-time support for SBCL

# This software is part of the SBCL system. See the README file for
# more information.
#
# This software is derived from the CMU CL system, which was
# written at Carnegie Mellon University and released into the
# public domain. The software is in the public domain and is
# provided with absolutely no warranty. See the COPYING and CREDITS
# files for more information.

include Config.x86-64-bsd

ASSEM_SRC += ldso-stubs.S

# Until sbcl-0.6.7.3, we used "LINKFLAGS+=-static" here, which
# worked fine for most things, but LOAD-FOREIGN & friends require
# dlopen() etc., which in turn depend on dynamic linking of the
# runtime.
LINKFLAGS += -dynamic -export-dynamic

# use libthr (1:1 threading). libpthread (m:n threading) does not work.
ifdef LISP_FEATURE_SB_THREAD
#OS_LIBS += -lpthread
OS_LIBS += -lthr
endif
2 changes: 2 additions & 0 deletions src/runtime/breakpoint.h
Expand Up @@ -22,6 +22,8 @@ extern void handle_breakpoint(int signal, siginfo_t *info,
os_context_t *context);
extern void *handle_fun_end_breakpoint(int signal, siginfo_t *info,
os_context_t *context);
extern void handle_single_step_trap (os_context_t *context, int kind,
int register_offset);

extern void handle_single_step_trap(os_context_t *context, int kind,
int register_offset);
Expand Down
49 changes: 27 additions & 22 deletions src/runtime/bsd-os.c
Expand Up @@ -41,6 +41,9 @@
#include <signal.h>
/* #include <sys/sysinfo.h> */
#include "validate.h"
#if defined LISP_FEATURE_GENCGC
#include "gencgc-internal.h"
#endif

os_vm_size_t os_vm_page_size;

Expand All @@ -55,7 +58,6 @@ static void netbsd_init();

#ifdef __FreeBSD__
#include <sys/sysctl.h>
#include <osreldate.h>

static void freebsd_init();
#endif /* __FreeBSD__ */
Expand All @@ -73,23 +75,6 @@ os_init(char *argv[], char *envp[])
#endif /* __FreeBSD__ */
}

int *os_context_pc_addr(os_context_t *context)
{
#if defined __FreeBSD__
return CONTEXT_ADDR_FROM_STEM(eip);
#elif defined __OpenBSD__
return CONTEXT_ADDR_FROM_STEM(pc);
#elif defined __NetBSD__
return CONTEXT_ADDR_FROM_STEM(EIP);
#elif defined(LISP_FEATURE_DARWIN) && defined(LISP_FEATURE_X86)
return CONTEXT_ADDR_FROM_STEM(eip);
#elif defined LISP_FEATURE_DARWIN
return &context->uc_mcontext->ss.srr0;
#else
#error unsupported BSD variant
#endif
}

sigset_t *
os_context_sigmask_addr(os_context_t *context)
{
Expand Down Expand Up @@ -172,9 +157,11 @@ is_valid_lisp_addr(os_vm_address_t addr)
in_range_p(addr, DYNAMIC_SPACE_START , dynamic_space_size))
return 1;
for_each_thread(th) {
if((th->control_stack_start <= addr) && (addr < th->control_stack_end))
if(((os_vm_address_t)th->control_stack_start <= addr) &&
(addr < (os_vm_address_t)th->control_stack_end))
return 1;
if(in_range_p(addr, th->binding_stack_start, BINDING_STACK_SIZE))
if(in_range_p(addr, (lispobj)th->binding_stack_start,
BINDING_STACK_SIZE))
return 1;
}
return 0;
Expand All @@ -191,18 +178,28 @@ is_valid_lisp_addr(os_vm_address_t addr)
* page fault on this OS.
*/
static void
memory_fault_handler(int signal, siginfo_t *siginfo, void *void_context)
memory_fault_handler(int signal, siginfo_t *siginfo, void *void_context
#if defined(LISP_FEATURE_FREEBSD) && defined(LISP_FEATURE_X86_64)
/* FreeBSD/amd64 stores fault address only in undocumented 4th arg. */
,void *fault_addr
#endif
)
{
os_context_t *context = arch_os_get_context(&void_context);
#if defined(LISP_FEATURE_FREEBSD) && defined(LISP_FEATURE_X86_64)
/* KLUDGE: Store fault address into si_addr for compatibilities. */
siginfo->si_addr = fault_addr;
#else
void *fault_addr = arch_get_bad_addr(signal, siginfo, context);
#endif

#if defined(LISP_FEATURE_RESTORE_TLS_SEGMENT_REGISTER_FROM_CONTEXT)
FSHOW_SIGNAL((stderr, "/ TLS: restoring fs: %p in memory_fault_handler\n",
*CONTEXT_ADDR_FROM_STEM(fs)));
os_restore_tls_segment_register(context);
#endif

FSHOW((stderr, "Memory fault at: %p, PC: %x\n", fault_addr, *os_context_pc_addr(context)));
FSHOW((stderr, "Memory fault at: %p, PC: %p\n", fault_addr, *os_context_pc_addr(context)));

if (!gencgc_handle_wp_violation(fault_addr))
if(!handle_guard_page_triggered(context,fault_addr)) {
Expand All @@ -225,9 +222,15 @@ os_install_interrupt_handlers(void)
{
SHOW("os_install_interrupt_handlers()/bsd-os/defined(GENCGC)");
undoably_install_low_level_interrupt_handler(SIG_MEMORY_FAULT,
#ifdef LISP_FEATURE_FREEBSD
(__siginfohandler_t *)
#endif
memory_fault_handler);
#ifdef SIG_MEMORY_FAULT2
undoably_install_low_level_interrupt_handler(SIG_MEMORY_FAULT2,
#ifdef LISP_FEATURE_FREEBSD
(__siginfohandler_t *)
#endif
memory_fault_handler);
#endif

Expand Down Expand Up @@ -363,6 +366,8 @@ static void freebsd_init()
#define KERN_PROC_PATHNAME 12
#endif

extern int getosreldate(void);

char *
os_get_runtime_executable_path()
{
Expand Down
1 change: 0 additions & 1 deletion src/runtime/bsd-os.h
Expand Up @@ -31,7 +31,6 @@ typedef vm_size_t os_vm_size_t;
#endif
typedef off_t os_vm_offset_t;
typedef int os_vm_prot_t;
typedef int os_context_register_t;

#if defined __OpenBSD__
/* name defined for compatibility between OpenBSD 3.1 sigaltstack(2) and
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/coreparse.c
Expand Up @@ -107,7 +107,7 @@ search_for_embedded_core(char *filename)
}

static void
process_directory(int fd, u32 *ptr, int count, os_vm_offset_t file_offset)
process_directory(int fd, lispobj *ptr, int count, os_vm_offset_t file_offset)
{
struct ndir_entry *entry;

Expand Down
1 change: 0 additions & 1 deletion src/runtime/interrupt.c
Expand Up @@ -584,7 +584,6 @@ run_deferred_handler(struct interrupt_data *data, void *v_context) {
* pending handler before calling it. Trust the handler to finish
* with the siginfo before enabling interrupts. */
void (*pending_handler) (int, siginfo_t*, void*)=data->pending_handler;
os_context_t *context = arch_os_get_context(&v_context);

data->pending_handler=0;
(*pending_handler)(data->pending_signal,&(data->pending_info), v_context);
Expand Down
1 change: 1 addition & 0 deletions src/runtime/parse.c
Expand Up @@ -12,6 +12,7 @@
*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <signal.h>

Expand Down
1 change: 1 addition & 0 deletions src/runtime/print.c
Expand Up @@ -19,6 +19,7 @@
*/

#include <stdio.h>
#include <string.h>

#include "sbcl.h"
#include "print.h"
Expand Down
92 changes: 86 additions & 6 deletions src/runtime/x86-64-arch.c
Expand Up @@ -50,7 +50,7 @@ arch_get_bad_addr(int sig, siginfo_t *code, os_context_t *context)
* want to get to, and on OS, which determines how we get to it.)
*/

int *
os_context_register_t *
context_eflags_addr(os_context_t *context)
{
#if defined __linux__
Expand All @@ -61,7 +61,7 @@ context_eflags_addr(os_context_t *context)
* instead. */
return &context->uc_mcontext.gregs[17];
#elif defined __FreeBSD__
return &context->uc_mcontext.mc_eflags;
return &context->uc_mcontext.mc_rflags;
#elif defined __OpenBSD__
return &context->sc_eflags;
#else
Expand Down Expand Up @@ -106,7 +106,7 @@ void arch_skip_instruction(os_context_t *context)
break;

default:
fprintf(stderr,"[arch_skip_inst invalid code %d\n]\n",code);
fprintf(stderr,"[arch_skip_inst invalid code %ld\n]\n",code);
break;
}

Expand Down Expand Up @@ -166,6 +166,11 @@ arch_remove_breakpoint(void *pc, unsigned int orig_inst)
/* When single stepping, single_stepping holds the original instruction
* PC location. */
unsigned int *single_stepping = NULL;
#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
unsigned int single_step_save1;
unsigned int single_step_save2;
unsigned int single_step_save3;
#endif

void
arch_do_displaced_inst(os_context_t *context, unsigned int orig_inst)
Expand All @@ -176,9 +181,24 @@ arch_do_displaced_inst(os_context_t *context, unsigned int orig_inst)
*((char *)pc) = orig_inst & 0xff;
*((char *)pc + 1) = (orig_inst & 0xff00) >> 8;

#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
/* Install helper instructions for the single step:
* pushf; or [esp],0x100; popf. */
single_step_save1 = *(pc-3);
single_step_save2 = *(pc-2);
single_step_save3 = *(pc-1);
*(pc-3) = 0x9c909090;
*(pc-2) = 0x00240c81;
*(pc-1) = 0x9d000001;
#else
*context_eflags_addr(context) |= 0x100;
#endif

single_stepping = pc;

#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
*os_context_pc_addr(context) = (os_context_register_t)((char *)pc - 9);
#endif
}


Expand All @@ -191,10 +211,17 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context)

if (single_stepping && (signal==SIGTRAP))
{
#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
/* Un-install single step helper instructions. */
*(single_stepping-3) = single_step_save1;
*(single_stepping-2) = single_step_save2;
*(single_stepping-1) = single_step_save3;
#else
*context_eflags_addr(context) ^= 0x100;

#endif
/* Re-install the breakpoint if possible. */
if (*os_context_pc_addr(context) == (int)single_stepping + 1) {
if ((char *)*os_context_pc_addr(context) ==
(char *)single_stepping + 1) {
fprintf(stderr, "warning: couldn't reinstall breakpoint\n");
} else {
*((char *)single_stepping) = BREAKPOINT_INST; /* x86 INT3 */
Expand All @@ -216,7 +243,7 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context)
single-stepping (as far as I can tell) this is somewhat moot,
but it might be worth either moving this code up or deleting
the single-stepping code entirely. -- CSR, 2002-07-15 */
#ifdef LISP_FEATURE_LINUX
#if defined(LISP_FEATURE_LINUX) || defined(RESTORE_FP_CONTROL_FROM_CONTEXT)
os_restore_fp_control(context);
#endif

Expand Down Expand Up @@ -281,6 +308,56 @@ sigill_handler(int signal, siginfo_t *siginfo, void *void_context) {
lose("fake_foreign_function_call fell through");
}

#ifdef X86_64_SIGFPE_FIXUP
#define MXCSR_IE (0x01) /* Invalid Operation */
#define MXCSR_DE (0x02) /* Denormal */
#define MXCSR_ZE (0x04) /* Devide-by-Zero */
#define MXCSR_OE (0x08) /* Overflow */
#define MXCSR_UE (0x10) /* Underflow */
#define MXCSR_PE (0x20) /* Precision */

static inline int
mxcsr_to_code(unsigned int mxcsr)
{
/* Extract unmasked exception bits. */
mxcsr &= ~(mxcsr >> 7) & 0x3F;

/* This order is defined at "Intel 64 and IA-32 Architectures
* Software Developerfs Manual" Volume 1: "Basic Architecture",
* 4.9.2 "Floating-Point Exception Priority". */
if (mxcsr & MXCSR_IE)
return FPE_FLTINV;
else if (mxcsr & MXCSR_ZE)
return FPE_FLTDIV;
else if (mxcsr & MXCSR_DE)
return FPE_FLTUND;
else if (mxcsr & MXCSR_OE)
return FPE_FLTOVF;
else if (mxcsr & MXCSR_UE)
return FPE_FLTUND;
else if (mxcsr & MXCSR_PE)
return FPE_FLTRES;

return 0;
}

static void
sigfpe_handler(int signal, siginfo_t *siginfo, void *void_context)
{
os_context_t *context = arch_os_get_context(&void_context);
unsigned int *mxcsr = arch_os_context_mxcsr_addr(context);

if (siginfo->si_code == 0) { /* XMM exception */
siginfo->si_code = mxcsr_to_code(*mxcsr);

/* Clear sticky exception flag. */
*mxcsr &= ~0x3F;
}

interrupt_handle_now(signal, siginfo, context);
}
#endif

void
arch_install_interrupt_handlers()
{
Expand All @@ -298,6 +375,9 @@ arch_install_interrupt_handlers()
* why.. -- WHN 2001-06-07 */
undoably_install_low_level_interrupt_handler(SIGILL , sigill_handler);
undoably_install_low_level_interrupt_handler(SIGTRAP, sigtrap_handler);
#ifdef X86_64_SIGFPE_FIXUP
undoably_install_low_level_interrupt_handler(SIGFPE, sigfpe_handler);
#endif

SHOW("returning from arch_install_interrupt_handlers()");
}
Expand Down

0 comments on commit bd45534

Please sign in to comment.