]>
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  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights 
   7  * Reserved.  This file contains Original Code and/or Modifications of 
   8  * Original Code as defined in and that are subject to the Apple Public 
   9  * Source License Version 1.1 (the "License").  You may not use this file 
  10  * except in compliance with the License.  Please obtain a copy of the 
  11  * License at http://www.apple.com/publicsource and read it before using 
  14  * The Original Code and all software distributed under the License are 
  15  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  16  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  17  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  18  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the 
  19  * License for the specific language governing rights and limitations 
  22  * @APPLE_LICENSE_HEADER_END@ 
  24 /* ndisasm.c   the Netwide Disassembler main module 
  26  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and 
  27  * Julian Hall. All rights reserved. The software is 
  28  * redistributable under the licence given in the file "Licence" 
  29  * distributed in the NASM archive. 
  43 #define BPL 8                          /* bytes per line of hex dump */ 
  45 static const char *help 
= 
  46 "usage: ndisasm [-a] [-i] [-h] [-r] [-u] [-b bits] [-o origin] [-s sync...]\n" 
  47 "               [-e bytes] [-k start,bytes] file\n" 
  48 "   -a or -i activates auto (intelligent) sync\n" 
  49 "   -u sets USE32 (32-bit mode)\n" 
  50 "   -b 16 or -b 32 sets number of bits too\n" 
  51 "   -h displays this text\n" 
  52 "   -r displays the version number\n" 
  53 "   -e skips <bytes> bytes of header\n" 
  54 "   -k avoids disassembling <bytes> bytes from position <start>\n"; 
  56 static void output_ins (unsigned long, unsigned char *, int, char *); 
  57 static void skip (unsigned long dist
, FILE *fp
); 
  59 int main(int argc
, char **argv
) { 
  60     unsigned char buffer
[INSN_MAX 
* 2], *p
, *q
; 
  63     char *filename 
= NULL
; 
  64     unsigned long nextsync
, synclen
, initskip 
= 0L; 
  77         char *v
, *vv
, *p 
= *++argv
; 
  80             while (*p
) switch (tolower(*p
)) { 
  81               case 'a':                /* auto or intelligent sync */ 
  87                 fprintf(stderr
, help
); 
  90                 fprintf(stderr
, "NDISASM version " NASM_VER 
"\n"); 
  97                 v 
= p
[1] ? p
+1 : --argc 
? *++argv 
: NULL
; 
  99                     fprintf(stderr
, "%s: `-b' requires an argument\n", pname
); 
 102                 if (!strcmp(v
, "16")) 
 104                 else if (!strcmp(v
, "32")) 
 107                     fprintf(stderr
, "%s: argument to `-b' should" 
 108                             " be `16' or `32'\n", pname
); 
 110                 p 
= "";                /* force to next argument */ 
 112               case 'o':                /* origin */ 
 113                 v 
= p
[1] ? p
+1 : --argc 
? *++argv 
: NULL
; 
 115                     fprintf(stderr
, "%s: `-o' requires an argument\n", pname
); 
 118                 offset 
= readnum (v
, &rn_error
); 
 120                     fprintf(stderr
, "%s: `-o' requires a numeric argument\n", 
 124                 p 
= "";                /* force to next argument */ 
 126               case 's':                /* sync point */ 
 127                 v 
= p
[1] ? p
+1 : --argc 
? *++argv 
: NULL
; 
 129                     fprintf(stderr
, "%s: `-s' requires an argument\n", pname
); 
 132                 add_sync (readnum (v
, &rn_error
), 0L); 
 134                     fprintf(stderr
, "%s: `-s' requires a numeric argument\n", 
 138                 p 
= "";                /* force to next argument */ 
 140               case 'e':                /* skip a header */ 
 141                 v 
= p
[1] ? p
+1 : --argc 
? *++argv 
: NULL
; 
 143                     fprintf(stderr
, "%s: `-e' requires an argument\n", pname
); 
 146                 initskip 
= readnum (v
, &rn_error
); 
 148                     fprintf(stderr
, "%s: `-e' requires a numeric argument\n", 
 152                 p 
= "";                /* force to next argument */ 
 154               case 'k':                /* skip a region */ 
 155                 v 
= p
[1] ? p
+1 : --argc 
? *++argv 
: NULL
; 
 157                     fprintf(stderr
, "%s: `-k' requires an argument\n", pname
); 
 162                     fprintf(stderr
, "%s: `-k' requires two numbers separated" 
 163                             " by a comma\n", pname
); 
 167                 nextsync 
= readnum (v
, &rn_error
); 
 169                     fprintf(stderr
, "%s: `-k' requires numeric arguments\n", 
 173                 synclen 
= readnum (vv
, &rn_error
); 
 175                     fprintf(stderr
, "%s: `-k' requires numeric arguments\n", 
 179                 add_sync (nextsync
, synclen
); 
 180                 p 
= "";                /* force to next argument */ 
 183         } else if (!filename
) { 
 186             fprintf(stderr
, "%s: more than one filename specified\n", pname
); 
 192         fprintf(stderr
, help
, pname
); 
 196     fp 
= fopen(filename
, "rb"); 
 198         fprintf(stderr
, "%s: unable to open `%s': %s\n", 
 199                 pname
, filename
, strerror(errno
)); 
 206      * This main loop is really horrible, and wants rewriting with 
 207      * an axe. It'll stay the way it is for a while though, until I 
 212     nextsync 
= next_sync (offset
, &synclen
); 
 214         unsigned long to_read 
= buffer
+sizeof(buffer
)-p
; 
 215         if (to_read 
> nextsync
-offset
-(p
-q
)) 
 216             to_read 
= nextsync
-offset
-(p
-q
); 
 217         lenread 
= fread (p
, 1, to_read
, fp
); 
 219             eof 
= TRUE
;                /* help along systems with bad feof */ 
 221         if (offset 
== (long)nextsync
) { 
 223                 printf("%08lX  skipping 0x%lX bytes\n", offset
, synclen
); 
 228             nextsync 
= next_sync (offset
, &synclen
); 
 230         while (p 
> q 
&& (p 
- q 
>= INSN_MAX 
|| lenread 
== 0)) { 
 231             lendis 
= disasm (q
, outbuf
, bits
, offset
, autosync
); 
 232             if (!lendis 
|| lendis 
> (p 
- q
) || 
 233                 lendis 
> (int)(nextsync
-offset
)) 
 234                 lendis 
= eatbyte (q
, outbuf
); 
 235             output_ins (offset
, q
, lendis
, outbuf
); 
 239         if (q 
>= buffer
+INSN_MAX
) { 
 240             unsigned char *r 
= buffer
, *s 
= q
; 
 247     } while (lenread 
> 0 || !(eof 
|| feof(fp
))); 
 252 static void output_ins (unsigned long offset
, unsigned char *data
, 
 253                         int datalen
, char *insn
) { 
 255     printf("%08lX  ", offset
); 
 258     while (datalen 
> 0 && bytes 
< BPL
) { 
 259         printf("%02X", *data
++); 
 264     printf("%*s%s\n", (BPL
+1-bytes
)*2, "", insn
); 
 266     while (datalen 
> 0) { 
 269         while (datalen 
> 0 && bytes 
< BPL
) { 
 270             printf("%02X", *data
++); 
 279  * Skip a certain amount of data in a file, either by seeking if 
 280  * possible, or if that fails then by reading and discarding. 
 282 static void skip (unsigned long dist
, FILE *fp
) { 
 283     char buffer
[256];                  /* should fit on most stacks :-) */ 
 286      * Got to be careful with fseek: at least one fseek I've tried 
 287      * doesn't approve of SEEK_CUR. So I'll use SEEK_SET and 
 288      * ftell... horrible but apparently necessary. 
 290     if (fseek (fp
, dist
+ftell(fp
), SEEK_SET
)) { 
 292             unsigned long len 
= (dist 
< sizeof(buffer
) ? 
 293                                  dist 
: sizeof(buffer
)); 
 294             if (fread (buffer
, 1, len
, fp
) < len
) {