Changeset 14991


Ignore:
Timestamp:
Sep 20, 2011, 2:19:03 AM (8 years ago)
Author:
rme
Message:

New functions in x86-utils.[ch], moved, more-or-less,
from xlbt.c.

Use them in x86-exceptions.c, in particular in
create_exception_callback_frame().

Move the definitions of the RECOVER_FN_xxx constants
from x86-exceptions.h to the appropriate x86-constants{32,64}.h
files.

Location:
trunk/source/lisp-kernel
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lisp-kernel/x86-constants32.h

    r14619 r14991  
    216216#define function_boundary_marker subtag_function_boundary_marker
    217217
     218/* The 32-bit immediate value in the instruction
     219 * "(mov ($ 0x12345678) (% fn))" at a tagged return address
     220 * refers to the associated function.
     221 */
     222#define RECOVER_FN_OPCODE 0xbf
     223#define RECOVER_FN_LENGTH 5
    218224
    219225
  • trunk/source/lisp-kernel/x86-constants64.h

    r14207 r14991  
    253253
    254254#define function_boundary_marker SUBTAG(fulltag_imm_1,15)       
     255
     256/*
     257 * To determine the function associated with a tagged return
     258 * address, we attempt to recognize an the instruction
     259 * (lea (@ disp (% rip)) (% fn)) at the tra.
     260 */
     261#define RECOVER_FN_FROM_RIP_LENGTH 7 /* the instruction is 7 bytes long */
     262#define RECOVER_FN_FROM_RIP_DISP_OFFSET 3 /* displacement word is 3 bytes in */
     263#define RECOVER_FN_FROM_RIP_WORD0 0x8d4c /* 0x4c 0x8d, little-endian */
     264#define RECOVER_FN_FROM_RIP_BYTE2 0x2d  /* third byte of opcode */
     265
    255266
    256267/* The objects themselves look something like this: */
  • trunk/source/lisp-kernel/x86-exceptions.c

    r14968 r14991  
    1818#include "lisp-exceptions.h"
    1919#include "lisp_globals.h"
     20#include "x86-utils.h"
    2021#include "threads.h"
    2122#include <ctype.h>
     
    409410  f = xpGPR(xp,Ifn);
    410411  tra = *(LispObj*)(xpGPR(xp,Isp));
    411 
    412 #ifdef X8664
    413   if (tag_of(tra) == tag_tra) {
    414     if ((*((unsigned short *)tra) == RECOVER_FN_FROM_RIP_WORD0) &&
    415         (*((unsigned char *)(tra+2)) == RECOVER_FN_FROM_RIP_BYTE2)) {
    416       int sdisp = (*(int *) (tra+3));
    417       tra_f = RECOVER_FN_FROM_RIP_LENGTH+tra+sdisp;
    418     }
    419     if (fulltag_of(tra_f) != fulltag_function) {
    420       tra_f = 0;
    421     }
    422   } else {
    423     tra = 0;
    424   }
    425 #endif
    426 #ifdef X8632
    427   if (fulltag_of(tra) == fulltag_tra) {
    428     if (*(unsigned char *)tra == RECOVER_FN_OPCODE) {
    429       tra_f = (LispObj)*(LispObj *)(tra + 1);
    430     }
    431     if (tra_f && header_subtag(header_of(tra_f)) != subtag_function) {
    432       tra_f = 0;
    433     }
    434   } else {
    435     tra = 0;
    436   }
    437 #endif
    438 
     412  tra_f = tra_function(tra);
    439413  abs_pc = (LispObj)xpPC(xp);
    440414
    441 #ifdef X8664
    442   if (fulltag_of(f) == fulltag_function)
    443 #else
    444     if (fulltag_of(f) == fulltag_misc &&
    445         header_subtag(header_of(f)) == subtag_function)
    446 #endif
    447       {
    448         nominal_function = f;
    449       } else {
    450       if (tra_f) {
    451         nominal_function = tra_f;
    452       }
    453     }
     415  if (functionp(f))
     416    nominal_function = f;
     417  else if (tra_f)
     418    nominal_function = tra_f;
    454419 
    455420  f = xpGPR(xp,Ifn);
     
    474439  } else {
    475440    containing_uvector = lisp_nil;
     441    /*
     442     * An absolute PC will not necessarily fit into a fixnum,
     443     * so encode it as two fixnums and let lisp reassemble it.
     444     */
    476445#if WORD_SIZE == 64
    477446    relative_pc = ((abs_pc >> 32) & 0xffffffff) << fixnumshift;
  • trunk/source/lisp-kernel/x86-exceptions.h

    r14295 r14991  
    9191#endif
    9292
    93 /* recognizing the function associated with a tagged return address */
    94 /* now involves recognizinig an "(lea (@ disp (% rip)) (% rn))" */
    95 /* instruction at the tra */
    96 
    97 #define RECOVER_FN_FROM_RIP_LENGTH 7 /* the instruction is 7 bytes long */
    98 #define RECOVER_FN_FROM_RIP_DISP_OFFSET 3 /* displacement word is 3 bytes in */
    99 #define RECOVER_FN_FROM_RIP_WORD0 0x8d4c /* 0x4c 0x8d, little-endian */
    100 #define RECOVER_FN_FROM_RIP_BYTE2 0x2d  /* third byte of opcode */
    101 
    10293extern natural get_mxcsr();
    10394extern void set_mxcsr(natural);
    10495void enable_fp_exceptions(void);
    105 
    106 #ifdef X8632
    107 /* The 32-bit immediate value in the instruction
    108  * "(mov ($ 0x12345678) (% fn))" at a tagged return address
    109  * refers to the associated function.
    110  */
    111 #define RECOVER_FN_OPCODE 0xbf
    112 #define RECOVER_FN_LENGTH 5
    113 #endif
    11496
    11597void callback_for_gc_notification(ExceptionInformation *xp, TCR *tcr);
  • trunk/source/lisp-kernel/x86-utils.c

    r14990 r14991  
     1/*
     2   Copyright (C) 2011 Clozure Associates
     3   This file is part of Clozure CL. 
     4
     5   Clozure CL is licensed under the terms of the Lisp Lesser GNU Public
     6   License , known as the LLGPL and distributed with Clozure CL as the
     7   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,
     8   which is distributed with Clozure CL as the file "LGPL".  Where these
     9   conflict, the preamble takes precedence. 
     10
     11   Clozure CL is referenced in the preamble as the "LIBRARY."
     12
     13   The LLGPL is also available online at
     14   http://opensource.franz.com/preamble.html
     15*/
     16
     17#include "lisp.h"
     18#include "x86-utils.h"
     19
     20LispObj
     21tra_function(LispObj tra)
     22{
     23  LispObj f = 0;
     24
     25#ifdef X8664
     26  if (tag_of(tra) == tag_tra) {
     27    if ((*((unsigned short *)tra) == RECOVER_FN_FROM_RIP_WORD0) &&
     28        (*((unsigned char *)(tra + 2)) == RECOVER_FN_FROM_RIP_BYTE2)) {
     29      int sdisp = (*(int *)(tra + RECOVER_FN_FROM_RIP_DISP_OFFSET));
     30      f = RECOVER_FN_FROM_RIP_LENGTH + tra + sdisp;
     31    }
     32  }
     33#else
     34  if (fulltag_of(tra) == fulltag_tra) {
     35    if (*((unsigned char *)tra) == RECOVER_FN_OPCODE) {
     36      natural n = *((natural *)(tra + 1));
     37      f = (LispObj)n;
     38    }
     39  }
     40#endif
     41  return f;
     42}
     43
     44int
     45tra_offset(LispObj tra)
     46{
     47  LispObj f = tra_function(tra);
     48  int disp = 0;
     49
     50  if (functionp(f))
     51    disp = tra - f;
     52  return disp;
     53}
  • trunk/source/lisp-kernel/x86-utils.h

    r14990 r14991  
     1/*
     2   Copyright (C) 2011 Clozure Associates
     3   This file is part of Clozure CL. 
     4
     5   Clozure CL is licensed under the terms of the Lisp Lesser GNU Public
     6   License , known as the LLGPL and distributed with Clozure CL as the
     7   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,
     8   which is distributed with Clozure CL as the file "LGPL".  Where these
     9   conflict, the preamble takes precedence. 
     10
     11   Clozure CL is referenced in the preamble as the "LIBRARY."
     12
     13   The LLGPL is also available online at
     14   http://opensource.franz.com/preamble.html
     15*/
     16
     17#ifndef X86_UTILS_H
     18#define X86_UTILS_H
     19
     20extern LispObj tra_function(LispObj tra);
     21extern int tra_offset(LispObj tra);
     22
     23static inline LispObj
     24function_to_function_vector(LispObj f)
     25{
     26#ifdef X8664
     27  return f - fulltag_function + fulltag_misc;
     28#else
     29  return f;
     30#endif
     31}
     32
     33static inline int
     34tra_p(LispObj thing)
     35{
     36#ifdef X8664
     37  return tag_of(thing) == tag_tra;
     38#else
     39  return fulltag_of(thing) == fulltag_tra;
     40#endif
     41}
     42
     43static inline int
     44functionp(LispObj f)
     45{
     46#ifdef X8664
     47  return fulltag_of(f) == fulltag_function;
     48#else
     49  return fulltag_of(f) == fulltag_misc &&
     50    header_subtag(header_of(f)) == subtag_function;
     51#endif
     52}
     53
     54#endif
  • trunk/source/lisp-kernel/xlbt.c

    r14977 r14991  
    1616
    1717#include "lispdcmd.h"
     18#include "x86-utils.h"
    1819#include <stdio.h>
    1920#include <signal.h>
    20 
    21 static LispObj
    22 function_to_function_vector(LispObj f)
    23 {
    24 #ifdef X8664
    25   return f - fulltag_function + fulltag_misc;
    26 #else
    27   return f;
    28 #endif
    29 }
    30 
    31 static Boolean
    32 functionp(LispObj f)
    33 {
    34 #ifdef X8664
    35   return fulltag_of(f) == fulltag_function;
    36 #else
    37   return fulltag_of(f) == fulltag_misc &&
    38     header_subtag(header_of(f)) == subtag_function;
    39 #endif
    40 }
    41 
    42 static LispObj
    43 tra_function(LispObj tra)
    44 {
    45   LispObj f = 0;
    46 
    47 #ifdef X8664
    48   if (tag_of(tra) == tag_tra) {
    49     if ((*((unsigned short *)tra) == RECOVER_FN_FROM_RIP_WORD0) &&
    50         (*((unsigned char *)(tra+2)) == RECOVER_FN_FROM_RIP_BYTE2)) {
    51       int sdisp = (*(int *) (tra+3));
    52       f = RECOVER_FN_FROM_RIP_LENGTH+tra+sdisp;
    53     }
    54   }
    55 #else
    56   if (fulltag_of(tra) == fulltag_tra) {
    57     if (*((unsigned char *)tra) == RECOVER_FN_OPCODE) {
    58       natural n = *((natural *)(tra + 1));
    59       f = (LispObj)n;
    60     }
    61   }
    62 #endif
    63   return f;
    64 }
    65 
    66 #if 0
    67 /* untested */
    68 static int
    69 tra_offset(LispObj tra)
    70 {
    71 #ifdef X8664
    72   if (tag_of(tra) == tag_tra) {
    73     if ((*((unsigned short *)tra) == RECOVER_FN_FROM_RIP_WORD0) &&
    74         (*((unsigned char *)(tra+2)) == RECOVER_FN_FROM_RIP_BYTE2)) {
    75       int sdisp = (*(int *) (tra+3));
    76 
    77       sdisp = - sdisp;
    78       sdisp -= RECOVER_FN_FROM_RIP_LENGTH;
    79       return sdisp;
    80     }
    81   }
    82 #else
    83   if (fulltag_of(tra) == fulltag_tra) {
    84     if (*((unsigned char *)tra) == RECOVER_FN_OPCODE) {
    85       int n = *((int *)(tra + 1));
    86       n = n - tra;
    87       n = -n;
    88       return n;
    89     }
    90   }
    91 #endif
    92   return 0;
    93 }
    94 #endif
    9521
    9622natural
Note: See TracChangeset for help on using the changeset viewer.