source: trunk/source/lisp-kernel/x86-constants64.h @ 14991

Last change on this file since 14991 was 14991, checked in by rme, 9 years ago

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.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.6 KB
Line 
1/*
2   Copyright (C) 2005-2009 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 "x86-constants.h"
18
19#ifdef DARWIN
20#define REG_RAX 0
21#define REG_RBX 1
22#define REG_RCX 2
23#define REG_RDX 3
24#define REG_RDI 4
25#define REG_RSI 5
26#define REG_RBP 6
27#define REG_RSP 7
28#define REG_R8 8
29#define REG_R9 9
30#define REG_R10 10
31#define REG_R11 11
32#define REG_R12 12
33#define REG_R13 13
34#define REG_R14 14
35#define REG_R15 15
36#define REG_RIP 16
37#define REG_RFL 17
38#endif
39
40#ifdef FREEBSD
41#define REG_RDI 1
42#define REG_RSI 2
43#define REG_RDX 3
44#define REG_RCX 4
45#define REG_R8 5
46#define REG_R9 6
47#define REG_RAX 7
48#define REG_RBX 8
49#define REG_RBP 9
50#define REG_R10 10
51#define REG_R11 11
52#define REG_R12 12
53#define REG_R13 13
54#define REG_R14 14
55#define REG_R15 15
56#define REG_RIP 20
57#define REG_RFL 22
58#define REG_RSP 23
59#endif
60
61#ifdef WIN_64
62/* DWORD64 indices in &(CONTEXT->Rax) */
63#define REG_RAX     0
64#define REG_RCX     1
65#define REG_RDX     2
66#define REG_RBX     3
67#define REG_RSP     4
68#define REG_RBP     5
69#define REG_RSI     6
70#define REG_RDI     7
71#define REG_R8      8
72#define REG_R9      9
73#define REG_R10     10
74#define REG_R11     11
75#define REG_R12     12
76#define REG_R13     13
77#define REG_R14     14
78#define REG_R15     15
79#define REG_RIP     16
80#endif
81
82/* Define indices of the GPRs in the mcontext component of a ucontext */
83#define Itemp0      REG_RBX
84#define Iarg_y      REG_RDI
85#define Iarg_x      REG_R8
86#define Iarg_z      REG_RSI
87#define Isave3      REG_R11
88#define Isave2      REG_R12
89#define Isave1      REG_R14
90#define Isave0      REG_R15
91#define Itemp2        REG_R10
92#define Ifn         REG_R13
93#define Irbp        REG_RBP
94#define Iimm0       REG_RAX
95#define Iimm1       REG_RDX
96#define Iimm2       REG_RCX
97#define Itemp1      REG_R9
98#define Isp         REG_RSP
99#define Iip         REG_RIP
100#if defined(LINUX) || defined(WINDOWS)
101#define Iflags      REG_EFL
102#endif
103
104#if defined(SOLARIS) || defined(FREEBSD) || defined(DARWIN)
105#define Iflags      REG_RFL
106#endif
107
108
109#define Iallocptr Itemp0
110#define Ira0 Itemp2
111#define Inargs Iimm2
112#define Ixfn Itemp1
113#define Ifp Irbp
114
115
116#define nbits_in_word 64L
117#define log2_nbits_in_word 6L
118#define nbits_in_byte 8L
119#define ntagbits 4L
120#define nlisptagbits 3L
121#define nfixnumtagbits 2L
122#define num_subtag_bits 8L
123#define fixnumshift 3L
124#define fixnum_shift 3L
125#define fulltagmask 15L
126#define tagmask  7L
127#define fixnummask 3
128#define subtagmask ((1L<<num_subtag_bits)-1L)
129#define ncharcodebits 8L
130#define charcode_shift 8L
131#define node_size 8L
132#define node_shift 3L
133#define nargregs 3L
134
135#define tag_fixnum 0L
136#define tag_imm_0 1L            /* subtag_single_float ONLY */
137#define tag_imm_1 2L            /* subtag_character, internal markers */
138#define tag_list 3L             /* subtag_cons or NIL */
139#define tag_tra 4L              /* tagged return_address */
140#define tag_misc 5L             /* random uvector */
141#define tag_symbol 6L           /* non-null symbol */
142#define tag_function 7L /* function entry point */
143
144#define fulltag_even_fixnum 0L
145#define fulltag_imm_0 1L
146#define fulltag_imm_1 2L
147#define fulltag_cons 3L
148#define fulltag_tra_0 4L
149#define fulltag_nodeheader_0 5L
150#define fulltag_nodeheader_1 6L
151#define fulltag_immheader_0 7L
152#define fulltag_odd_fixnum 8L
153#define fulltag_immheader_1 9L
154#define fulltag_immheader_2 10L
155#define fulltag_nil 11L
156#define fulltag_tra_1 12L
157#define fulltag_misc 13L
158#define fulltag_symbol 14L
159#define fulltag_function 15L
160
161#define SUBTAG(tag,subtag) ((tag) | ((subtag) << ntagbits))
162#define subtag_arrayH SUBTAG(fulltag_nodeheader_0,10L)
163#define subtag_vectorH SUBTAG(fulltag_nodeheader_1,10L)
164#define subtag_simple_vector SUBTAG(fulltag_nodeheader_1,11L)
165#define min_vector_subtag subtag_vectorH       
166
167#define ivector_class_64_bit fulltag_immheader_2
168#define ivector_class_32_bit fulltag_immheader_1
169#define ivector_class_other_bit fulltag_immheader_0
170
171
172#define subtag_fixnum_vector SUBTAG(ivector_class_64_bit,12L)
173#define subtag_s64_vector SUBTAG(ivector_class_64_bit,13L)
174#define subtag_u64_vector SUBTAG(ivector_class_64_bit,14L)
175#define subtag_double_float_vector SUBTAG(ivector_class_64_bit,15L)
176
177#define subtag_simple_base_string SUBTAG(ivector_class_32_bit,12L)
178#define subtag_s32_vector SUBTAG(ivector_class_32_bit,13L)
179#define subtag_u32_vector SUBTAG(ivector_class_32_bit,14L)
180#define subtag_single_float_vector SUBTAG(ivector_class_32_bit,15L)
181
182#define subtag_s16_vector SUBTAG(ivector_class_other_bit,10L)
183#define subtag_u16_vector SUBTAG(ivector_class_other_bit,11L)
184#define subtag_s8_vector SUBTAG(ivector_class_other_bit,13L)
185#define subtag_u8_vector SUBTAG(ivector_class_other_bit,14L)
186#define subtag_bit_vector SUBTAG(ivector_class_other_bit,15L)
187/* min_8_bit_ivector_subtag is the old 8-bit simple_base_string */
188#define min_8_bit_ivector_subtag SUBTAG(ivector_class_other_bit,12L)
189
190/* There's some room for expansion in non-array ivector space. */
191#define subtag_macptr SUBTAG(ivector_class_64_bit,1)
192#define subtag_dead_macptr SUBTAG(ivector_class_64_bit,2)
193#define subtag_bignum SUBTAG(ivector_class_32_bit,0)
194#define subtag_double_float SUBTAG(ivector_class_32_bit,1)
195#define subtag_xcode_vector SUBTAG(ivector_class_32_bit,2)
196
197/* Note the difference between (e.g) fulltag_function - which
198   defines what the low 4 bytes of a function pointer look like -
199   and subtag_function - which describes what the subtag byte
200   in a function header looks like.  (Likewise for fulltag_symbol
201   and subtag_symbol)
202*/             
203
204#define subtag_symbol SUBTAG(fulltag_nodeheader_0,1)
205#define subtag_catch_frame SUBTAG(fulltag_nodeheader_0,2)
206#define subtag_hash_vector SUBTAG(fulltag_nodeheader_0,3)
207#define subtag_pool SUBTAG(fulltag_nodeheader_0,4)
208#define subtag_weak SUBTAG(fulltag_nodeheader_0,5)
209#define subtag_package SUBTAG(fulltag_nodeheader_0,6)
210#define subtag_slot_vector SUBTAG(fulltag_nodeheader_0,7)
211#define subtag_basic_stream SUBTAG(fulltag_nodeheader_0,8)
212#define subtag_function SUBTAG(fulltag_nodeheader_0,9)
213
214#define subtag_ratio SUBTAG(fulltag_nodeheader_1,1)
215#define subtag_complex SUBTAG(fulltag_nodeheader_1,2)
216#define subtag_struct SUBTAG(fulltag_nodeheader_1,3)
217#define subtag_istruct SUBTAG(fulltag_nodeheader_1,4)
218#define subtag_value_cell SUBTAG(fulltag_nodeheader_1,5)
219#define subtag_xfunction SUBTAG(fulltag_nodeheader_1,6)
220#define subtag_lock SUBTAG(fulltag_nodeheader_1,7)
221#define subtag_instance SUBTAG(fulltag_nodeheader_1,8)
222
223
224
225#define nil_value ((0x13000+fulltag_nil)+(LOWMEM_BIAS))
226#define t_value ((0x13020+fulltag_symbol)+(LOWMEM_BIAS))
227#define misc_bias fulltag_misc
228#define cons_bias fulltag_cons
229
230       
231#define misc_header_offset -fulltag_misc
232#define misc_subtag_offset misc_header_offset       /* low byte of header */
233#define misc_data_offset misc_header_offset+node_size   /* first word of data */
234#define misc_dfloat_offset misc_header_offset           /* double-floats are doubleword-aligned */
235
236#define subtag_single_float SUBTAG(fulltag_imm_0,0)
237#define subtag_character SUBTAG(fulltag_imm_1,0)
238
239#define subtag_unbound SUBTAG(fulltag_imm_1,1)
240#define unbound_marker subtag_unbound
241#define undefined unbound_marker
242#define unbound unbound_marker
243#define subtag_slot_unbound SUBTAG(fulltag_imm_1,2)
244#define slot_unbound_marker subtag_slot_unbound
245#define slot_unbound slot_unbound_marker
246#define subtag_illegal SUBTAG(fulltag_imm_1,3)
247#define illegal_marker subtag_illegal
248#define subtag_no_thread_local_binding SUBTAG(fulltag_imm_1,4)
249#define no_thread_local_binding_marker subtag_no_thread_local_binding
250#define subtag_reserved_frame  SUBTAG(fulltag_imm_1,5)
251#define reserved_frame_marker subtag_reserved_frame
252#define subtag_forward_marker SUBTAG(fulltag_imm_1,6)
253
254#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
266
267/* The objects themselves look something like this: */
268
269
270typedef struct double_float {
271  LispObj header;
272  LispObj value;
273} double_float;
274
275
276
277typedef struct lisp_frame {
278  struct lisp_frame *backlink;
279  LispObj tra;
280  LispObj xtra;                 /* if tra is nvalretn */
281} lisp_frame;
282
283/* These are created on the lisp stack by the exception callback mechanism,
284   but nothing ever returns to them.  (At the very least, nothing -should-
285   try to return to them ...).
286*/
287typedef struct exception_callback_frame {
288  struct lisp_frame *backlink;
289  LispObj tra;                  /* ALWAYS 0 FOR AN XCF */
290  LispObj nominal_function;     /* the current function at the time of the exception */
291  LispObj relative_pc;          /* Boxed byte offset within actual
292                                   function or absolute address */
293  LispObj containing_uvector;   /* the uvector that contains the relative PC or NIL */
294  LispObj xp;                   /* exception context */
295  LispObj ra0;                  /* value of ra0 from context */
296  LispObj foreign_sp;           /* foreign sp at the time that exception occurred */
297  LispObj prev_xframe;          /* so %apply-in-frame can unwind it */
298} xcf;
299
300
301
302/*
303  The GC also needs to know what a catch_frame looks like.
304*/
305
306typedef struct catch_frame {
307  LispObj header;
308  LispObj catch_tag;
309  LispObj link;
310  LispObj mvflag;
311  LispObj csp;
312  LispObj db_link;
313  LispObj regs[4];
314  LispObj xframe;
315  LispObj tsp_segment;
316} catch_frame;
317
318#define catch_frame_element_count ((sizeof(catch_frame)/sizeof(LispObj))-1)
319#define catch_frame_header make_header(subtag_catch_frame,catch_frame_element_count)
320
321
322/*
323  All exception frames in a thread are linked together
324  */
325typedef struct xframe_list {
326  ExceptionInformation *curr;
327  struct xframe_list *prev;
328} xframe_list;
329
330#define fixnum_bitmask(n)  (1LL<<((n)+fixnumshift))
331
332
333#include "lisp-errors.h"
334
335
336
337#define TCR_BIAS (0x0)
338
339typedef struct tcr {
340  struct tcr* next;
341  struct tcr* prev;
342  struct {
343    u32_t tag;
344    float f;
345  } single_float_convert;
346  struct tcr* linear;
347  LispObj *save_fp;            /* RBP when in foreign code */
348  u32_t lisp_mxcsr;
349  u32_t foreign_mxcsr;
350  special_binding* db_link;     /* special binding chain head */
351  LispObj catch_top;            /* top catch frame */
352  LispObj* save_vsp;  /* VSP when in foreign code */
353  LispObj* save_tsp;  /* TSP when in foreign code */
354  LispObj* foreign_sp;
355  struct area* cs_area; /* cstack area pointer */
356  struct area* vs_area; /* vstack area pointer */
357  struct area* ts_area; /* tstack area pointer */
358  LispObj cs_limit;             /* stack overflow limit */
359  natural bytes_allocated;
360  natural log2_allocation_quantum;      /* for per-thread consing */
361  signed_natural interrupt_pending;     /* pending interrupt flag */
362  xframe_list* xframe; /* exception-frame linked list */
363  int* errno_loc;               /* per-thread (?) errno location */
364  LispObj ffi_exception;        /* fpscr bits from ff-call */
365  LispObj osid;                 /* OS thread id */
366  signed_natural valence;                       /* odd when in foreign code */
367  signed_natural foreign_exception_status;      /* non-zero -> call lisp_exit_hook */
368  void* native_thread_info;     /* platform-dependent */
369  void* native_thread_id;       /* mach_thread_t, pid_t, etc. */
370  char *last_allocptr;
371  char *save_allocptr;
372  char *save_allocbase;
373  void* reset_completion;
374  void* activate;
375  signed_natural suspend_count;
376  ExceptionInformation* suspend_context;
377  ExceptionInformation* pending_exception_context;
378  void* suspend;                /* suspension semaphore */
379  void* resume;                 /* resumption semaphore */
380  natural flags;
381  ExceptionInformation* gc_context;
382  void* termination_semaphore;
383  signed_natural unwinding;
384  natural tlb_limit;
385  LispObj* tlb_pointer;
386  natural shutdown_count;
387  LispObj* next_tsp;
388  void *safe_ref_address;
389  void *pending_io_info;
390  void *io_datum;
391} TCR;
392
393#define t_offset (t_value-nil_value)
394
395typedef struct {
396  natural Rip;
397  natural Cs;                   /* in low 16 bits */
398  natural Rflags;               /* in low 32 bits */
399  natural Rsp;
400  natural Ss;                   /* in low 16 bits*/
401} x64_iret_frame;
402
403/*
404  These were previously global variables.  There are lots of implicit
405  assumptions about the size of a heap segment, so they might as well
406  be constants.
407*/
408
409#define heap_segment_size 0x00020000L
410#define log2_heap_segment_size 17L
411
Note: See TracBrowser for help on using the repository browser.