Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 195 lines (179 sloc) 4.865 kb
d076be50 » koriakin
2010-04-27 fc: Start a Fermi ctxprog disassembler
1 /*
2 *
3 * Copyright (C) 2009 Marcin Kościelnicki <koriakin@0x04.net>
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 #include "coredis.h"
27
344edd05 » koriakin
2010-05-08 fc: Use the coredis skeleton.
28 #define AP -1
29
30 /*
f9619be0 » koriakin
2010-05-08 fc: Add branch insn
31 * Code target fields
344edd05 » koriakin
2010-05-08 fc: Use the coredis skeleton.
32 */
33
187d3e90 » koriakin
2010-05-08 fc: Add the long branch insn.
34 #define SBTARG atomsbtarg, 0
35 void atomsbtarg APROTO {
f9619be0 » koriakin
2010-05-08 fc: Add branch insn
36 uint32_t delta = BF(16, 8);
37 if (delta & 0x80) delta += 0xffffff00;
38 fprintf (out, " %s%#x", cbr, pos + delta);
39 }
40
187d3e90 » koriakin
2010-05-08 fc: Add the long branch insn.
41 #define LBTARG atomlbtarg, 0
42 void atomlbtarg APROTO {
43 uint32_t delta = BF(16, 16);
44 if (delta & 0x8000) delta += 0xffff0000;
45 fprintf (out, " %s%#x", cbr, pos + delta);
46 }
47
344edd05 » koriakin
2010-05-08 fc: Use the coredis skeleton.
48 #define CTARG atomctarg, 0
49 void atomctarg APROTO {
9e8415a1 » koriakin
2010-05-08 fc: Fix call.
50 fprintf (out, " %s%#llx", cbr, BF(16, 16));
344edd05 » koriakin
2010-05-08 fc: Use the coredis skeleton.
51 }
52
53 /*
54 * Register fields
55 */
56
57 int reg1off[] = { 8, 4, 'r' };
58 int reg2off[] = { 12, 4, 'r' };
59 #define REG1 atomreg, reg1off
60 #define REG2 atomreg, reg2off
61
62 /*
63 * Immediate fields
64 */
65
66 int limmoff[] = { 16, 16, 0, 0 };
67 int simmoff[] = { 16, 8, 0, 1 };
68 int limmhoff[] = { 16, 16, 16, 0 };
69 int simmhoff[] = { 16, 8, 16, 1 };
70 #define LIMM atomnum, limmoff
71 #define SIMM atomnum, simmoff
72 #define LIMMH atomnum, limmhoff
73 #define SIMMH atomnum, simmhoff
74
f9619be0 » koriakin
2010-05-08 fc: Add branch insn
75 struct insn tabp[] = {
76 { AP, 0x00000e00, 0x00001f00 }, /* always true */
77 { AP, 0, 0, OOPS },
78 };
79
344edd05 » koriakin
2010-05-08 fc: Use the coredis skeleton.
80 struct insn tabm[] = {
187d3e90 » koriakin
2010-05-08 fc: Add the long branch insn.
81 { AP, 0x000000f4, 0x0000e0ff, N("bra"), T(p), SBTARG },
82 { AP, 0x000000f5, 0x0000e0ff, N("bra"), T(p), LBTARG },
344edd05 » koriakin
2010-05-08 fc: Use the coredis skeleton.
83 { AP, 0x000021f5, 0x0000ffff, N("call"), CTARG },
84 { AP, 0x000000f8, 0x0000ffff, N("ret") },
85 { AP, 0x000003f0, 0x00000fff, N("lhigh"), REG2, SIMMH },
86 { AP, 0x000003f1, 0x00000fff, N("lhigh"), REG2, LIMMH },
87 { AP, 0x000007f0, 0x00000fff, N("limm"), REG2, SIMM },
88 { AP, 0x000007f1, 0x00000fff, N("limm"), REG2, LIMM },
e94d665f » koriakin
2010-05-08 fc: Nailed down add/sub insns
89 { AP, 0x000000b6, 0x00000fff, N("add"), REG2, SIMM },
90 { AP, 0x000000b7, 0x00000fff, N("add"), REG2, LIMM },
91 { AP, 0x000002b6, 0x00000fff, N("sub"), REG2, SIMM },
92 { AP, 0x000002b7, 0x00000fff, N("sub"), REG2, LIMM },
344edd05 » koriakin
2010-05-08 fc: Use the coredis skeleton.
93 { AP, 0, 0, OOPS },
94 };
95
d076be50 » koriakin
2010-04-27 fc: Start a Fermi ctxprog disassembler
96 /*
97 * Disassembler driver
98 *
99 * You pass a block of memory to this function, disassembly goes out to given
100 * FILE*.
101 */
102
103 void fcdis (FILE *out, uint8_t *code, int num) {
104 int cur = 0, i;
105 while (cur < num) {
106 fprintf (out, "%s%08x:%s", cgray, cur, cnorm);
107 uint8_t op = code[cur];
108 int length = 0;
109 switch (op) {
110 case 0xa0:
111 case 0xb1:
112 case 0xb7:
113 case 0xe3:
114 case 0xe4:
115 case 0xe7:
116 case 0xf1:
117 case 0xf5:
118 length = 4;
119 break;
120 case 0x80:
121 case 0x90:
122 case 0x92:
123 case 0x94:
124 case 0x95:
125 case 0x97:
126 case 0x98:
127 case 0xb0:
128 case 0xb4:
129 case 0xb6:
130 case 0xb8:
131 case 0xb9:
132 case 0xbb:
133 case 0xbc:
134 case 0xc4:
135 case 0xc5:
136 case 0xc7:
137 case 0xf0:
138 case 0xfa:
139 case 0xf4:
140 case 0xfd:
141 case 0xfe:
142 case 0xff:
143 length = 3;
144 break;
145 case 0xbd:
146 case 0xf8:
147 case 0xf9:
148 case 0xfc:
149 length = 2;
150 break;
151 }
152 if (!length || cur + length > num) {
344edd05 » koriakin
2010-05-08 fc: Use the coredis skeleton.
153 fprintf (out, " %s%02x ???%s\n", cred, op, cnorm);
d076be50 » koriakin
2010-04-27 fc: Start a Fermi ctxprog disassembler
154 cur++;
155 } else {
344edd05 » koriakin
2010-05-08 fc: Use the coredis skeleton.
156 ull a = 0, m = 0;
157 for (i = cur; i < cur + length; i++) {
d076be50 » koriakin
2010-04-27 fc: Start a Fermi ctxprog disassembler
158 fprintf (out, " %02x", code[i]);
344edd05 » koriakin
2010-05-08 fc: Use the coredis skeleton.
159 a |= (ull)code[i] << (i-cur)*8;
160 }
68e49678 » koriakin
2010-04-27 fc: Add load-immediate, call, ret instructions
161 for (i = 0; i < 4 - length; i++)
162 fprintf (out, " ");
344edd05 » koriakin
2010-05-08 fc: Use the coredis skeleton.
163 atomtab (out, &a, &m, tabm, -1, cur);
164 a &= ~m;
165 if (a) {
166 fprintf (out, " %s[unknown: %08llx]%s", cred, a, cnorm);
68e49678 » koriakin
2010-04-27 fc: Add load-immediate, call, ret instructions
167 }
344edd05 » koriakin
2010-05-08 fc: Use the coredis skeleton.
168 printf ("%s\n", cnorm);
d076be50 » koriakin
2010-04-27 fc: Start a Fermi ctxprog disassembler
169 cur += length;
170 }
171 }
172 }
173
174 /*
175 * Options:
176 *
177 * -b Read input as binary ctxprog
178 * -4 Disassembles NV40 ctxprogs
179 * -5 Disassembles NV50 ctxprogs
180 * -n Disable color escape sequences in output
181 */
182
183 int main(int argc, char **argv) {
184 int num = 0;
185 int maxnum = 16;
186 uint8_t *code = malloc (maxnum * 4);
187 uint32_t t;
188 while (!feof(stdin) && scanf ("%x", &t) == 1) {
189 if (num == maxnum) maxnum *= 2, code = realloc (code, maxnum*4);
190 code[num++] = t;
191 scanf (" ,");
192 }
193 fcdis (stdout, code, num);
194 return 0;
195 }
Something went wrong with that request. Please try again.