X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Farm%2Fmd.c;h=4149a7eaadcacea2c96ca43a855ffdd39e9cd3e0;hb=67702ed5605e84f33724aeee9ccf5f82ea774084;hp=30df98d484ba893b04a6925ec15d4c3b7ff2de6b;hpb=8c6bb03b79a31fcdb02e2331a91a928d558c2845;p=cacao.git diff --git a/src/vm/jit/arm/md.c b/src/vm/jit/arm/md.c index 30df98d48..4149a7eaa 100644 --- a/src/vm/jit/arm/md.c +++ b/src/vm/jit/arm/md.c @@ -1,7 +1,8 @@ /* src/vm/jit/arm/md.c - machine dependent ARM functions - Copyright (C) 1996-2005, 2006, 2007, 2008 + Copyright (C) 1996-2005, 2006, 2007, 2008, 2010 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO + Copyright (C) 2009 Theobroma Systems Ltd. This file is part of CACAO. @@ -32,6 +33,9 @@ #include "vm/jit/arm/md.h" #include "vm/jit/arm/md-abi.h" +#include "vm/jit/executionstate.h" +#include "vm/jit/trap.hpp" + /* md_init ********************************************************************* @@ -142,20 +146,41 @@ void *md_jit_method_patch_address(void *pv, void *ra, void *mptr) /* Case: We loaded from base REG_PV with positive offset. */ else if (M_MEM_GET_Rbase(mcode) == REG_PV && (mcode & 0x00800000) == 0x00800000) { - /* We loaded from REG_METHODPTR with a larger displacement */ + /* We loaded with a larger displacement. Normally this means we loaded + from REG_METHODPTR. However there is a corner case if we loaded + from the data segment at an address aligned to 12 bit, which leads to a + zero (positive) displacement for the last instruction. */ mcode = pc[-1]; /* check for "ADD IP, FP, #??, ROTL 12" */ - if ((mcode & 0xffffff00) == 0xe28bca00) + if ((mcode & 0xffffff00) == 0xe28bca00) { + /* We loaded from REG_METHODPTR with a larger displacement. */ + + assert(mptr != NULL); + disp += (int32_t) ((mcode & 0x00ff) << 12); + pa = ((uint8_t *) mptr) + disp; + } + + /* check for "SUB IP, IP, #??, ROTL 12" (corner case) */ + + else if ((mcode & 0xffffff00) == 0xe24cca00 && disp == 0) { + /* We loaded from data segment with a larger displacement aligned to 12 bit. */ + disp += (int32_t) ((mcode & 0x00ff) << 12); - else + pa = ((uint8_t *) pv) - disp; + } + + /* Case is not covered, something is severely wrong. */ + + else { vm_abort_disassemble(pc - 1, 4, "md_jit_method_patch_address: unknown instruction %x", mcode); - /* we loaded from REG_METHODPTR */ + /* Keep compiler happy. */ - pa = ((uint8_t *) mptr) + disp; + pa = NULL; + } } /* Case is not covered, something is severely wrong. */ @@ -172,6 +197,52 @@ void *md_jit_method_patch_address(void *pv, void *ra, void *mptr) } +/** + * Decode the trap instruction at the given PC. + * + * @param trp information about trap to be filled + * @param sig signal number + * @param xpc exception PC + * @param es execution state of the machine + * @return true if trap was decoded successfully, false otherwise. + */ +bool md_trap_decode(trapinfo_t* trp, int sig, void* xpc, executionstate_t* es) +{ + // Get the exception-throwing instruction. + uint32_t mcode = *((uint32_t*) xpc); + + switch (sig) { + case TRAP_SIGILL: + // Check for valid trap instruction. + if (patcher_is_valid_trap_instruction_at(xpc)) { + trp->type = (mcode >> 8) & 0x0fff; + trp->value = es->intregs[mcode & 0x0f]; + return true; + } + return false; + + case TRAP_SIGSEGV: + { + // Sanity check for load/store instruction. + // FIXME Implement this! + + // Retrieve base address of load/store instruction. + uintptr_t addr = es->intregs[(mcode >> 16) & 0x0f]; + + // Check for implicit NullPointerException. + if (addr == 0) { + trp->type = TRAP_NullPointerException; + trp->value = 0; + return true; + } + } + + default: + return false; + } +} + + /** * Patch the given replacement point. */