]>
git.saurik.com Git - apple/boot.git/blob - i386/nasm/ndisasm.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 /* ndisasm.c the Netwide Disassembler main module
27 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
28 * Julian Hall. All rights reserved. The software is
29 * redistributable under the licence given in the file "Licence"
30 * distributed in the NASM archive.
44 #define BPL 8 /* bytes per line of hex dump */
46 static const char *help
=
47 "usage: ndisasm [-a] [-i] [-h] [-r] [-u] [-b bits] [-o origin] [-s sync...]\n"
48 " [-e bytes] [-k start,bytes] file\n"
49 " -a or -i activates auto (intelligent) sync\n"
50 " -u sets USE32 (32-bit mode)\n"
51 " -b 16 or -b 32 sets number of bits too\n"
52 " -h displays this text\n"
53 " -r displays the version number\n"
54 " -e skips <bytes> bytes of header\n"
55 " -k avoids disassembling <bytes> bytes from position <start>\n";
57 static void output_ins (unsigned long, unsigned char *, int, char *);
58 static void skip (unsigned long dist
, FILE *fp
);
60 int main(int argc
, char **argv
) {
61 unsigned char buffer
[INSN_MAX
* 2], *p
, *q
;
64 char *filename
= NULL
;
65 unsigned long nextsync
, synclen
, initskip
= 0L;
78 char *v
, *vv
, *p
= *++argv
;
81 while (*p
) switch (tolower(*p
)) {
82 case 'a': /* auto or intelligent sync */
88 fprintf(stderr
, help
);
91 fprintf(stderr
, "NDISASM version " NASM_VER
"\n");
98 v
= p
[1] ? p
+1 : --argc
? *++argv
: NULL
;
100 fprintf(stderr
, "%s: `-b' requires an argument\n", pname
);
103 if (!strcmp(v
, "16"))
105 else if (!strcmp(v
, "32"))
108 fprintf(stderr
, "%s: argument to `-b' should"
109 " be `16' or `32'\n", pname
);
111 p
= ""; /* force to next argument */
113 case 'o': /* origin */
114 v
= p
[1] ? p
+1 : --argc
? *++argv
: NULL
;
116 fprintf(stderr
, "%s: `-o' requires an argument\n", pname
);
119 offset
= readnum (v
, &rn_error
);
121 fprintf(stderr
, "%s: `-o' requires a numeric argument\n",
125 p
= ""; /* force to next argument */
127 case 's': /* sync point */
128 v
= p
[1] ? p
+1 : --argc
? *++argv
: NULL
;
130 fprintf(stderr
, "%s: `-s' requires an argument\n", pname
);
133 add_sync (readnum (v
, &rn_error
), 0L);
135 fprintf(stderr
, "%s: `-s' requires a numeric argument\n",
139 p
= ""; /* force to next argument */
141 case 'e': /* skip a header */
142 v
= p
[1] ? p
+1 : --argc
? *++argv
: NULL
;
144 fprintf(stderr
, "%s: `-e' requires an argument\n", pname
);
147 initskip
= readnum (v
, &rn_error
);
149 fprintf(stderr
, "%s: `-e' requires a numeric argument\n",
153 p
= ""; /* force to next argument */
155 case 'k': /* skip a region */
156 v
= p
[1] ? p
+1 : --argc
? *++argv
: NULL
;
158 fprintf(stderr
, "%s: `-k' requires an argument\n", pname
);
163 fprintf(stderr
, "%s: `-k' requires two numbers separated"
164 " by a comma\n", pname
);
168 nextsync
= readnum (v
, &rn_error
);
170 fprintf(stderr
, "%s: `-k' requires numeric arguments\n",
174 synclen
= readnum (vv
, &rn_error
);
176 fprintf(stderr
, "%s: `-k' requires numeric arguments\n",
180 add_sync (nextsync
, synclen
);
181 p
= ""; /* force to next argument */
184 } else if (!filename
) {
187 fprintf(stderr
, "%s: more than one filename specified\n", pname
);
193 fprintf(stderr
, help
, pname
);
197 fp
= fopen(filename
, "rb");
199 fprintf(stderr
, "%s: unable to open `%s': %s\n",
200 pname
, filename
, strerror(errno
));
207 * This main loop is really horrible, and wants rewriting with
208 * an axe. It'll stay the way it is for a while though, until I
213 nextsync
= next_sync (offset
, &synclen
);
215 unsigned long to_read
= buffer
+sizeof(buffer
)-p
;
216 if (to_read
> nextsync
-offset
-(p
-q
))
217 to_read
= nextsync
-offset
-(p
-q
);
218 lenread
= fread (p
, 1, to_read
, fp
);
220 eof
= TRUE
; /* help along systems with bad feof */
222 if (offset
== (long)nextsync
) {
224 printf("%08lX skipping 0x%lX bytes\n", offset
, synclen
);
229 nextsync
= next_sync (offset
, &synclen
);
231 while (p
> q
&& (p
- q
>= INSN_MAX
|| lenread
== 0)) {
232 lendis
= disasm (q
, outbuf
, bits
, offset
, autosync
);
233 if (!lendis
|| lendis
> (p
- q
) ||
234 lendis
> (int)(nextsync
-offset
))
235 lendis
= eatbyte (q
, outbuf
);
236 output_ins (offset
, q
, lendis
, outbuf
);
240 if (q
>= buffer
+INSN_MAX
) {
241 unsigned char *r
= buffer
, *s
= q
;
248 } while (lenread
> 0 || !(eof
|| feof(fp
)));
253 static void output_ins (unsigned long offset
, unsigned char *data
,
254 int datalen
, char *insn
) {
256 printf("%08lX ", offset
);
259 while (datalen
> 0 && bytes
< BPL
) {
260 printf("%02X", *data
++);
265 printf("%*s%s\n", (BPL
+1-bytes
)*2, "", insn
);
267 while (datalen
> 0) {
270 while (datalen
> 0 && bytes
< BPL
) {
271 printf("%02X", *data
++);
280 * Skip a certain amount of data in a file, either by seeking if
281 * possible, or if that fails then by reading and discarding.
283 static void skip (unsigned long dist
, FILE *fp
) {
284 char buffer
[256]; /* should fit on most stacks :-) */
287 * Got to be careful with fseek: at least one fseek I've tried
288 * doesn't approve of SEEK_CUR. So I'll use SEEK_SET and
289 * ftell... horrible but apparently necessary.
291 if (fseek (fp
, dist
+ftell(fp
), SEEK_SET
)) {
293 unsigned long len
= (dist
< sizeof(buffer
) ?
294 dist
: sizeof(buffer
));
295 if (fread (buffer
, 1, len
, fp
) < len
) {