2 // http://code.google.com/p/inferno-os/source/browse/utils/libmach/6.c
4 // Copyright © 1994-1999 Lucent Technologies Inc.
5 // Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
6 // Portions Copyright © 1997-1999 Vita Nuova Limited.
7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
8 // Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
9 // Portions Copyright © 2009 The Go Authors. All rights reserved.
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
36 #include "uregamd64.h"
38 char *i386excep(Map*, Regs*);
39 int i386foll(Map*, Regs*, u64int, u64int*);
40 int i386hexinst(Map*, u64int, char*, int);
41 int i386das(Map*, u64int, char, char*, int);
42 int i386instlen(Map*, u64int);
43 int i386unwind(Map*, Regs*, u64int*, Symbol*);
45 #define REGOFF(x) offsetof(struct Ureg, x)
47 #define REGSIZE sizeof(struct Ureg)
48 #define FP_CTLS(x) (REGSIZE+2*(x))
49 #define FP_CTL(x) (REGSIZE+4*(x))
50 #define FP_REG(x) (FP_CTL(8)+16*(x))
51 #define XM_REG(x) (FP_CTL(8)+8*16+16*(x))
53 #define FPREGSIZE 512 /* TO DO? currently only 0x1A0 used */
55 static Regdesc amd64reglist[] = {
56 {"AX", REGOFF(ax), RINT, 'Y'},
57 {"BX", REGOFF(bx), RINT, 'Y'},
58 {"CX", REGOFF(cx), RINT, 'Y'},
59 {"DX", REGOFF(dx), RINT, 'Y'},
60 {"SI", REGOFF(si), RINT, 'Y'},
61 {"DI", REGOFF(di), RINT, 'Y'},
62 {"BP", REGOFF(bp), RINT, 'Y'},
63 {"R8", REGOFF(r8), RINT, 'Y'},
64 {"R9", REGOFF(r9), RINT, 'Y'},
65 {"R10", REGOFF(r10), RINT, 'Y'},
66 {"R11", REGOFF(r11), RINT, 'Y'},
67 {"R12", REGOFF(r12), RINT, 'Y'},
68 {"R13", REGOFF(r13), RINT, 'Y'},
69 {"R14", REGOFF(r14), RINT, 'Y'},
70 {"R15", REGOFF(r15), RINT, 'Y'},
71 {"DS", REGOFF(ds), RINT, 'x'},
72 {"ES", REGOFF(es), RINT, 'x'},
73 {"FS", REGOFF(fs), RINT, 'x'},
74 {"GS", REGOFF(gs), RINT, 'x'},
75 {"TYPE", REGOFF(type), RINT, 'Y'},
76 {"TRAP", REGOFF(type), RINT, 'Y'}, /* alias for acid */
77 {"ERROR", REGOFF(error), RINT, 'Y'},
78 {"IP", REGOFF(ip), RINT, 'Y'},
79 {"PC", REGOFF(ip), RINT, 'Y'}, /* alias for acid */
80 {"CS", REGOFF(cs), RINT, 'Y'},
81 {"FLAGS", REGOFF(flags), RINT, 'Y'},
82 {"SP", REGOFF(sp), RINT, 'Y'},
83 {"SS", REGOFF(ss), RINT, 'Y'},
85 {"FCW", FP_CTLS(0), RFLT, 'x'},
86 {"FSW", FP_CTLS(1), RFLT, 'x'},
87 {"FTW", FP_CTLS(2), RFLT, 'b'},
88 {"FOP", FP_CTLS(3), RFLT, 'x'},
89 {"RIP", FP_CTL(2), RFLT, 'Y'},
90 {"RDP", FP_CTL(4), RFLT, 'Y'},
91 {"MXCSR", FP_CTL(6), RFLT, 'X'},
92 {"MXCSRMASK", FP_CTL(7), RFLT, 'X'},
93 {"M0", FP_REG(0), RFLT, 'F'}, /* assumes double */
94 {"M1", FP_REG(1), RFLT, 'F'},
95 {"M2", FP_REG(2), RFLT, 'F'},
96 {"M3", FP_REG(3), RFLT, 'F'},
97 {"M4", FP_REG(4), RFLT, 'F'},
98 {"M5", FP_REG(5), RFLT, 'F'},
99 {"M6", FP_REG(6), RFLT, 'F'},
100 {"M7", FP_REG(7), RFLT, 'F'},
101 {"X0", XM_REG(0), RFLT, 'F'}, /* assumes double */
102 {"X1", XM_REG(1), RFLT, 'F'},
103 {"X2", XM_REG(2), RFLT, 'F'},
104 {"X3", XM_REG(3), RFLT, 'F'},
105 {"X4", XM_REG(4), RFLT, 'F'},
106 {"X5", XM_REG(5), RFLT, 'F'},
107 {"X6", XM_REG(6), RFLT, 'F'},
108 {"X7", XM_REG(7), RFLT, 'F'},
109 {"X8", XM_REG(8), RFLT, 'F'},
110 {"X9", XM_REG(9), RFLT, 'F'},
111 {"X10", XM_REG(10), RFLT, 'F'},
112 {"X11", XM_REG(11), RFLT, 'F'},
113 {"X12", XM_REG(12), RFLT, 'F'},
114 {"X13", XM_REG(13), RFLT, 'F'},
115 {"X14", XM_REG(14), RFLT, 'F'},
116 {"X15", XM_REG(15), RFLT, 'F'},
117 {"X16", XM_REG(16), RFLT, 'F'},
119 {"F0", FP_REG(7), RFLT, '3'},
120 {"F1", FP_REG(6), RFLT, '3'},
121 {"F2", FP_REG(5), RFLT, '3'},
122 {"F3", FP_REG(4), RFLT, '3'},
123 {"F4", FP_REG(3), RFLT, '3'},
124 {"F5", FP_REG(2), RFLT, '3'},
125 {"F6", FP_REG(1), RFLT, '3'},
126 {"F7", FP_REG(0), RFLT, '3'},
131 static char *amd64windregs[] = {
156 MAMD64, /* machine type */
157 amd64reglist, /* register list */
158 REGSIZE, /* size of registers in bytes */
159 FPREGSIZE, /* size of fp registers in bytes */
160 "PC", /* name of PC */
161 "SP", /* name of SP */
162 "BP", /* name of FP */
163 0, /* link register */
164 "setSB", /* static base register name (bogus anyways) */
165 0, /* static base register value */
166 0x1000, /* page size */
167 0xFFFFFFFF80110000ULL, /* kernel base */
168 0xFFFF800000000000ULL, /* kernel text mask */
169 1, /* quantization of pc */
175 amd64windregs, /* locations unwound in stack trace */
178 {0xCC, 0, 0, 0}, /* break point: INT 3 */
179 1, /* break point size */
181 i386foll, /* following addresses */
182 i386excep, /* print exception */
183 i386unwind, /* stack unwind */
185 leswap2, /* convert short to local byte order */
186 leswap4, /* convert long to local byte order */
187 leswap8, /* convert vlong to local byte order */
188 leieeeftoa32, /* single precision float pointer */
189 leieeeftoa64, /* double precision float pointer */
190 leieeeftoa80, /* long double precision floating point */
192 i386das, /* dissembler */
193 i386das, /* plan9-format disassembler */
194 0, /* commercial disassembler */
195 i386hexinst, /* print instruction */
196 i386instlen, /* instruction size calculation */