Blob


1 // Inferno libmach/6.c
2 // http://code.google.com/p/inferno-os/source/browse/utils/libmach/6.c
3 //
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.
10 //
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:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
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
27 // THE SOFTWARE.
29 /*
30 * amd64 definition
31 */
32 #include <u.h>
33 #include <libc.h>
34 #include <bio.h>
35 #include <mach.h>
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'},
118 /*
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'},
127 */
128 { 0 }
129 };
131 static char *amd64windregs[] = {
132 "PC",
133 "SP",
134 "BP",
135 "AX",
136 "CX",
137 "DX",
138 "BX",
139 "SI",
140 "DI",
141 "R8",
142 "R9",
143 "R10",
144 "R11",
145 "R12",
146 "R13",
147 "R14",
148 "R15",
149 0,
150 };
153 Mach machamd64=
155 "amd64",
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 */
170 8, /* szaddr */
171 4, /* szreg */
172 4, /* szfloat */
173 8, /* szdouble */
175 amd64windregs, /* locations unwound in stack trace */
176 17,
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 */
197 };