diff options
author | Keith Kanios <spook@dynatos.net> | 2007-04-12 02:40:54 +0000 |
---|---|---|
committer | Keith Kanios <spook@dynatos.net> | 2007-04-12 02:40:54 +0000 |
commit | b7a89544d09455d7b2f4621c80b21ca457563f4a (patch) | |
tree | 6c89a3318c19c2bf364cbd95859e78fbc2d4e306 | |
parent | aa348dec7d6c5366efd10513ae4ff6fa2bbbd6ed (diff) | |
download | nasm-b7a89544d09455d7b2f4621c80b21ca457563f4a.tar.gz nasm-b7a89544d09455d7b2f4621c80b21ca457563f4a.tar.bz2 nasm-b7a89544d09455d7b2f4621c80b21ca457563f4a.zip |
General push for x86-64 support, dubbed 0.99.00.
-rw-r--r-- | AUTHORS | 10 | ||||
-rw-r--r-- | CHANGES | 11 | ||||
-rw-r--r-- | ChangeLog | 30 | ||||
-rw-r--r-- | Mkfiles/README | 1 | ||||
-rw-r--r-- | README | 6 | ||||
-rw-r--r-- | TODO | 38 | ||||
-rw-r--r-- | assemble.c | 774 | ||||
-rw-r--r-- | assemble.h | 4 | ||||
-rw-r--r-- | disasm.c | 68 | ||||
-rw-r--r-- | disasm.h | 6 | ||||
-rw-r--r-- | doc/nasmdoc.src | 298 | ||||
-rw-r--r-- | eval.c | 51 | ||||
-rw-r--r-- | float.c | 51 | ||||
-rw-r--r-- | float.h | 2 | ||||
-rw-r--r-- | insns.dat | 385 | ||||
-rw-r--r-- | insns.h | 19 | ||||
-rw-r--r-- | insns.pl | 7 | ||||
-rw-r--r-- | labels.c | 54 | ||||
-rw-r--r-- | labels.h | 16 | ||||
-rw-r--r-- | lcc/lin-aout.c | 18 | ||||
-rw-r--r-- | lcc/lin-elf.c | 18 | ||||
-rw-r--r-- | listing.c | 62 | ||||
-rw-r--r-- | macros.pl | 2 | ||||
-rw-r--r-- | names.c | 2 | ||||
-rw-r--r-- | nasm.c | 154 | ||||
-rw-r--r-- | nasm.h | 139 | ||||
-rw-r--r-- | nasmlib.c | 203 | ||||
-rw-r--r-- | nasmlib.h | 95 | ||||
-rw-r--r-- | ndisasm.c | 45 | ||||
-rw-r--r-- | outform.c | 5 | ||||
-rw-r--r-- | outform.h | 17 | ||||
-rw-r--r-- | output/outaout.c | 149 | ||||
-rw-r--r-- | output/outas86.c | 145 | ||||
-rw-r--r-- | output/outbin.c | 159 | ||||
-rw-r--r-- | output/outcoff.c | 305 | ||||
-rw-r--r-- | output/outdbg.c | 55 | ||||
-rw-r--r-- | output/outelf.c | 257 | ||||
-rw-r--r-- | output/outieee.c | 149 | ||||
-rw-r--r-- | output/outmacho.c | 369 | ||||
-rw-r--r-- | output/outobj.c | 159 | ||||
-rw-r--r-- | output/outrdf.c | 89 | ||||
-rw-r--r-- | output/outrdf2.c | 97 | ||||
-rw-r--r-- | parser.c | 21 | ||||
-rw-r--r-- | parser.h | 2 | ||||
-rw-r--r-- | preproc.c | 219 | ||||
-rw-r--r-- | preproc.h | 13 | ||||
-rw-r--r-- | rdoff/collectn.h | 2 | ||||
-rw-r--r-- | rdoff/hash.c | 4 | ||||
-rw-r--r-- | rdoff/hash.h | 2 | ||||
-rw-r--r-- | rdoff/ldrdf.c | 72 | ||||
-rw-r--r-- | rdoff/ldsegs.h | 4 | ||||
-rw-r--r-- | rdoff/rdf2bin.c | 12 | ||||
-rw-r--r-- | rdoff/rdf2ihx.c | 12 | ||||
-rw-r--r-- | rdoff/rdfdump.c | 60 | ||||
-rw-r--r-- | rdoff/rdflib.c | 56 | ||||
-rw-r--r-- | rdoff/rdfload.c | 22 | ||||
-rw-r--r-- | rdoff/rdfload.h | 10 | ||||
-rw-r--r-- | rdoff/rdlar.c | 50 | ||||
-rw-r--r-- | rdoff/rdlar.h | 14 | ||||
-rw-r--r-- | rdoff/rdlib.c | 28 | ||||
-rw-r--r-- | rdoff/rdlib.h | 10 | ||||
-rw-r--r-- | rdoff/rdoff.c | 64 | ||||
-rw-r--r-- | rdoff/rdoff.h | 66 | ||||
-rw-r--r-- | rdoff/rdx.c | 4 | ||||
-rw-r--r-- | rdoff/segtab.c | 8 | ||||
-rw-r--r-- | rdoff/segtab.h | 4 | ||||
-rw-r--r-- | rdoff/symtab.c | 4 | ||||
-rw-r--r-- | rdoff/symtab.h | 8 | ||||
-rw-r--r-- | regs.dat | 225 | ||||
-rwxr-xr-x | regs.pl | 12 | ||||
-rw-r--r-- | standard.mac | 6 | ||||
-rw-r--r-- | sync.c | 9 | ||||
-rw-r--r-- | sync.h | 4 | ||||
-rw-r--r-- | test/aouttest.c | 5 | ||||
-rw-r--r-- | test/cofftest.c | 4 | ||||
-rw-r--r-- | test/elftest.c | 4 | ||||
-rw-r--r-- | test/objlink.c | 8 | ||||
-rw-r--r-- | version | 2 |
78 files changed, 3291 insertions, 2283 deletions
@@ -1,5 +1,5 @@ This is the AUTHORS file for the NASM project located at: -http://nasm.2y.net/ +http://nasm.sourceforge.net/ Names should be inserted as follows: @@ -117,3 +117,11 @@ N: Alexei Frounze E: alexfru@users.sourceforge.net D: "-I" paths searched for "incbined" files D: bugswatting + +N: Keith Kanios, aka SpooK +E: keith@kanios.net +D: c99 Compliance +D: General x64 Support +D: win64 (x86-64 COFF) output format +D: __BITS__ Standard Macro +D: Website Maintenance @ http://nasm.sourceforge.net/ @@ -1,5 +1,12 @@ -0.98.40 -* fix (?) bug in outobj.c - every 256th "extern" caused Nasm crash +0.99.00 +------- +* Added c99 data-type compliance. +* Added general x86-64 support. +* Added win64 (x86-64 COFF) output format. +* Added __BITS__ standard macro which returns current [BITS XX] mode. +* fix (???) bug in outobj.c - every 256th "extern" caused Nasm crash. + (is this during definition or use, I made over 260 externs with obj + and could not duplicate the gripe -Keith Kanios) 0.98.39 ------- @@ -1,3 +1,33 @@ +2007-04-10 Keith Kanios <keith@kanios.net> + * (insns.dat): updated x86-64 general+system instruction set. + +2007-04-09 Keith Kanios <keith@kanios.net> + * (outrdf.c): added support for 64-bit addressing. + * (outrdf2.c): added support for 64-bit addressing. + +2007-04-08 Keith Kanios <keith@kanios.net> + * (standard.mac): added entry for __BITS__ standard macro. + * (preproc.c): added __BITS__ to the standard macro processing. + +2007-04-05 Keith Kanios <keith@kanios.net> + * (nasm.c): added [BITS 64] for the x86-64 architecture extension. + * (nasm.h): added general flags to support the x86-64 architecture. + * (nasmlib.h): updated to support the x86-64 architecture. + * (nasmlib.c): revamped readnum/readlinenum to support 64-bit. + * (assemble.c): modified for the x86-64 architecture extension. + * (regs.dat): added x86-64 register extensions; revamped flags. + * (insns.dat): added AMD64 instruction set support. + * (outbin.c): added support for 64-bit addressing. + * (outcoff.c): added win64 (x86-64 COFF) support. + * (outform.h): added entry for win64. + +2007-03-15 Keith Kanios <keith@kanios.net> + * (*.c): added c99 data-type compliance and <inttypes.h> inclusion. + * (*.pl): added c99 data-type compliance and <inttypes.h> inclusion. + * (*.h): added c99 data-type compliance. + * (assemble.h): fixed procedure defintions to sync with respective + procedure declarations. + 2002-05-16 Ed Beroset <beroset@mindspring.com> * (preproc.c): fixed unterminated macro bug error reporting * (nasmlib.h): changed strdup's arg to const char * diff --git a/Mkfiles/README b/Mkfiles/README index 19bfcd9..047c788 100644 --- a/Mkfiles/README +++ b/Mkfiles/README @@ -18,6 +18,7 @@ The Makefiles are: Makefile.b32 Win32 Borland C++ OK as of NASM 0.98.37 Makefile.bc3 16-bit DOS Borland C++ OK as of NASM 0.98.34 Makefile.bor 16-bit DOS Turbo C (**) + Makefile.dcp Win32 Dev-Cpp/MinGW OK as of NASM 0.99.00 Makefile.dj 32-bit DOS DJGPP OK as of NASM 0.98.37 Makefile.djo 32-bit DOS DJGPP "Opus Make" version(**) Makefile.dl 32-bit DOS cc386 cc386 by David Lindauer @@ -10,10 +10,10 @@ This means its development is open to even wider society of programmers wishing to improve their lovely assembler. The NASM project is now situated at SourceForge.net, the most -famous Open Source development center on The Net. +popular Open Source development site on the Internet. -Visit our development page at http://nasm.2y.net/ and our -SF project at http://sf.net/projects/nasm/ +Visit our website at http://nasm.sourceforge.net/ and our +SourceForge project at http://sourceforge.net/projects/nasm/ See the file CHANGES for the description of changes between revisions. @@ -18,7 +18,42 @@ Anything that doesn't start with /^[FVRCD]:/ should be ignored. ============= +F: Extended x64 Support +D: Full FPU/MMX/SSE* instruction support for x64 + +F: ELF64 output format +D: Support for assembling code to the ELF64 output format + +F: NDISASM x64 Support +D: Ability to disassemble respective x64 code + +F: General x64 Support +V: 0.99.00 +R: Keith Kanios +C: 99% +D: Support for assembling 64-bit code to various output formats + +F: win64 (x86-64 COFF) output format +V: 0.99.00 +R: Keith Kanios +C: 99% +D: Support for assembling code to the win64 output format + +F: c99 data-type compliance +V: 0.99.00 +R: Keith Kanios +C: 99% +D: Revamped entire source-code base data-types for compliance +D: with c99 (inttypes.h) + +F: __BITS__ Standard Macro +V: 0.99.00 +R: Keith Kanios +C: 100% +D: __BITS__ standard macro that returns current [BITS XX] mode + F: i18n via gettext +D: kkanios: be careful about that, stick to UTF-8 if anything F: Convert shallow code model to deep code model D: Tired of messing between lots of unrelated files (especially .c/.h stuff) @@ -28,7 +63,7 @@ D: Current looks awful and will break if anything changes. F: Move output modules out*.c to output/ subdir R: madfire -C: 10% +C: 100% == THESE ARE FROM old NASM's Wishlist == THEY NEED SEVERE REVISING (seems they weren't updated for a couple of years or so) @@ -44,6 +79,7 @@ F: 3DNow!, SSE and other extensions need documenting V: 0.98 D: hpa: Does it really make sense to have a whole instruction set D: reference packaged with the assembler? +D: kkanios: Yes, for me it was a great help... and still is. F: prototypes of lrotate don't match in test/*. Fix. V: 0.98 @@ -28,6 +28,7 @@ * \44, \45, \46 - select between \3[012] and \4[012] depending on 16/32 bit * assembly mode or the address-size override on the operand * \50, \51, \52 - a byte relative operand, from operand 0, 1 or 2 + * \54, \55, \56 - a qword immediate operand, from operand 0, 1 or 2 * \60, \61, \62 - a word relative operand, from operand 0, 1 or 2 * \64, \65, \66 - select between \6[012] and \7[012] depending on 16/32 bit * assembly mode or the operand-size override on the operand @@ -40,6 +41,9 @@ * \140,\141,\142 - an immediate dword or signed byte for operand 0, 1, or 2 * \143,\144,\145 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2 * is a signed byte rather than a dword. + * \150,\151,\152 - an immediate qword or signed byte for operand 0, 1, or 2 + * \153,\154,\155 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2 + * is a signed byte rather than a qword. * \2ab - a ModRM, calculated on EA in operand a, with the spare * field equal to digit b. * \30x - might be an 0x67 byte, depending on the address size of @@ -47,11 +51,14 @@ * \310 - indicates fixed 16-bit address size, i.e. optional 0x67. * \311 - indicates fixed 32-bit address size, i.e. optional 0x67. * \312 - (disassembler only) marker on LOOP, LOOPxx instructions. + * \313 - indicates fixed 64-bit address size, no REX required. * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66. * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66. * \322 - indicates that this instruction is only valid when the * operand size is the default (instruction to disassembler, * generates no code in the assembler) + * \323 - indicates fixed 64-bit operand size, REX on extensions, only. + * \324 - indicates 64-bit operand size requiring REX prefix. * \330 - a literal byte follows in the code stream, to be added * to the condition code value of the instruction. * \331 - instruction not valid with REP prefix. Hint for @@ -59,7 +66,7 @@ * \332 - disassemble a rep (0xF3 byte) prefix as repe not rep. * \333 - REP prefix (0xF3 byte); for SSE instructions. Not encoded * as a literal byte in order to aid the disassembler. - * \340 - reserve <operand 0> bytes of uninitialised storage. + * \340 - reserve <operand 0> bytes of uninitialized storage. * Operand 0 had better be a segmentless constant. * \370,\371,\372 - match only if operand 0 meets byte jump criteria. * 370 is used for Jcc, 371 is used for JMP. @@ -69,31 +76,34 @@ #include <stdio.h> #include <string.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" #include "assemble.h" #include "insns.h" #include "preproc.h" +#include "regvals.c" extern struct itemplate *nasm_instructions[]; typedef struct { - int sib_present; /* is a SIB byte necessary? */ - int bytes; /* # of bytes of offset needed */ - int size; /* lazy - this is sib+bytes+1 */ - unsigned char modrm, sib; /* the bytes themselves */ + int sib_present; /* is a SIB byte necessary? */ + int bytes; /* # of bytes of offset needed */ + int size; /* lazy - this is sib+bytes+1 */ + uint8_t modrm, sib, rex, rip; /* the bytes themselves */ } ea; -static unsigned long cpu; /* cpu level received from nasm.c */ +static uint32_t cpu; /* cpu level received from nasm.c */ static efunc errfunc; static struct ofmt *outfmt; static ListGen *list; -static long calcsize(long, long, int, insn *, const char *); -static void gencode(long, long, int, insn *, const char *, long); +static int32_t calcsize(int32_t, int32_t, int, insn *, const int8_t *); +static void gencode(int32_t, int32_t, int, insn *, const int8_t *, int32_t); static int regval(operand * o); -static int matches(struct itemplate *, insn *); +static int regflag(operand * o); +static int matches(struct itemplate *, insn *, int bits); static ea *process_ea(operand *, ea *, int, int, int); static int chsize(operand *, int); @@ -102,11 +112,11 @@ static int chsize(operand *, int); * in order to pass a copy of the data off to the listing file * generator at the same time. */ -static void out(long offset, long segto, const void *data, - unsigned long type, long segment, long wrt) +static void out(int32_t offset, int32_t segto, const void *data, + uint32_t type, int32_t segment, int32_t wrt) { - static long lineno = 0; /* static!!! */ - static char *lnfname = NULL; + static int32_t lineno = 0; /* static!!! */ + static int8_t *lnfname = NULL; if ((type & OUT_TYPMASK) == OUT_ADDRESS) { if (segment != NO_SEG || wrt != NO_SEG) { @@ -116,16 +126,19 @@ static void out(long offset, long segto, const void *data, */ list->output(offset, data, type); } else { - unsigned char p[4], *q = p; + uint8_t p[8], *q = p; /* * This is a non-relocated address, and we're going to * convert it into RAWDATA format. */ if ((type & OUT_SIZMASK) == 4) { - WRITELONG(q, *(long *)data); + WRITELONG(q, *(int32_t *)data); list->output(offset, p, OUT_RAWDATA + 4); + } else if ((type & OUT_SIZMASK) == 8) { + WRITEDLONG(q, *(int64_t *)data); + list->output(offset, p, OUT_RAWDATA + 8); } else { - WRITESHORT(q, *(long *)data); + WRITESHORT(q, *(int32_t *)data); list->output(offset, p, OUT_RAWDATA + 2); } } @@ -154,11 +167,11 @@ static void out(long offset, long segto, const void *data, outfmt->output(segto, data, type, segment, wrt); } -static int jmp_match(long segment, long offset, int bits, - insn * ins, const char *code) +static int jmp_match(int32_t segment, int32_t offset, int bits, + insn * ins, const int8_t *code) { - long isize; - unsigned char c = code[0]; + int32_t isize; + uint8_t c = code[0]; if (c != 0370 && c != 0371) return 0; @@ -179,17 +192,17 @@ static int jmp_match(long segment, long offset, int bits, return 0; } -long assemble(long segment, long offset, int bits, unsigned long cp, +int32_t assemble(int32_t segment, int32_t offset, int bits, uint32_t cp, insn * instruction, struct ofmt *output, efunc error, ListGen * listgen) { struct itemplate *temp; int j; int size_prob; - long insn_end; - long itimes; - long start = offset; - long wsize = 0; /* size for DB etc. */ + int32_t insn_end; + int32_t itimes; + int32_t start = offset; + int32_t wsize = 0; /* size for DB etc. */ errfunc = error; /* to pass to other functions */ cpu = cp; @@ -218,7 +231,7 @@ long assemble(long segment, long offset, int bits, unsigned long cp, if (wsize) { extop *e; - long t = instruction->times; + int32_t t = instruction->times; if (t < 0) errfunc(ERR_PANIC, "instruction->times < 0 (%ld) in assemble()", t); @@ -231,7 +244,7 @@ long assemble(long segment, long offset, int bits, unsigned long cp, errfunc(ERR_NONFATAL, "one-byte relocation attempted"); else { - unsigned char out_byte = e->offset; + uint8_t out_byte = e->offset; out(offset, segment, &out_byte, OUT_RAWDATA + 1, NO_SEG, NO_SEG); } @@ -272,11 +285,11 @@ long assemble(long segment, long offset, int bits, unsigned long cp, } if (instruction->opcode == I_INCBIN) { - static char fname[FILENAME_MAX]; + static int8_t fname[FILENAME_MAX]; FILE *fp; - long len; - char *prefix = "", *combine; - char **pPrevPath = NULL; + int32_t len; + int8_t *prefix = "", *combine; + int8_t **pPrevPath = NULL; len = FILENAME_MAX - 1; if (len > instruction->eops->stringlen) @@ -284,7 +297,7 @@ long assemble(long segment, long offset, int bits, unsigned long cp, strncpy(fname, instruction->eops->stringval, len); fname[len] = '\0'; - while (1) { /* added by alexfru: 'incbin' uses include paths */ + while (1) { /* added by alexfru: 'incbin' uses include paths */ combine = nasm_malloc(strlen(prefix) + len + 1); strcpy(combine, prefix); strcat(combine, fname); @@ -308,9 +321,9 @@ long assemble(long segment, long offset, int bits, unsigned long cp, error(ERR_NONFATAL, "`incbin': unable to seek on file `%s'", fname); else { - static char buf[2048]; - long t = instruction->times; - long base = 0; + static int8_t buf[2048]; + int32_t t = instruction->times; + int32_t base = 0; len = ftell(fp); if (instruction->eops->next) { @@ -327,12 +340,12 @@ long assemble(long segment, long offset, int bits, unsigned long cp, list->output(offset, NULL, OUT_RAWDATA); list->uplevel(LIST_INCBIN); while (t--) { - long l; + int32_t l; fseek(fp, base, SEEK_SET); l = len; while (l > 0) { - long m = + int32_t m = fread(buf, 1, (l > sizeof(buf) ? sizeof(buf) : l), fp); if (!m) { @@ -369,15 +382,16 @@ long assemble(long segment, long offset, int bits, unsigned long cp, } size_prob = FALSE; - temp = nasm_instructions[instruction->opcode]; - while (temp->opcode != -1) { - int m = matches(temp, instruction); + + for (temp = nasm_instructions[instruction->opcode]; temp->opcode != -1; temp++){ + int m = matches(temp, instruction, bits); + if (m == 99) m += jmp_match(segment, offset, bits, instruction, temp->code); if (m == 100) { /* matches! */ - const char *codes = temp->code; - long insn_size = calcsize(segment, offset, bits, + const int8_t *codes = temp->code; + int32_t insn_size = calcsize(segment, offset, bits, instruction, codes); itimes = instruction->times; if (insn_size < 0) /* shouldn't be, on pass two */ @@ -385,7 +399,7 @@ long assemble(long segment, long offset, int bits, unsigned long cp, else while (itimes--) { for (j = 0; j < instruction->nprefix; j++) { - unsigned char c = 0; + uint8_t c = 0; switch (instruction->prefixes[j]) { case P_LOCK: c = 0xF0; @@ -423,6 +437,10 @@ long assemble(long segment, long offset, int bits, unsigned long cp, "segr6 and segr7 cannot be used as prefixes"); break; case P_A16: + if (bits == 64) { + error(ERR_PANIC, "16-bit addressing is depreciated in long mode"); + break; + } if (bits != 16) c = 0x67; break; @@ -435,7 +453,7 @@ long assemble(long segment, long offset, int bits, unsigned long cp, c = 0x66; break; case P_O32: - if (bits != 32) + if (bits == 16) c = 0x66; break; default: @@ -446,7 +464,7 @@ long assemble(long segment, long offset, int bits, unsigned long cp, NO_SEG, NO_SEG); offset++; } - } + } insn_end = offset + insn_size; gencode(segment, offset, bits, instruction, codes, insn_end); @@ -466,7 +484,7 @@ long assemble(long segment, long offset, int bits, unsigned long cp, } else if (m > 0 && m > size_prob) { size_prob = m; } - temp++; +// temp++; } if (temp->opcode == -1) { /* didn't match any instruction */ @@ -476,6 +494,8 @@ long assemble(long segment, long offset, int bits, unsigned long cp, error(ERR_NONFATAL, "mismatch in operand sizes"); else if (size_prob == 3) error(ERR_NONFATAL, "no instruction for this cpu level"); + else if (size_prob == 4) + error(ERR_NONFATAL, "instruction depreciated in long mode"); else error(ERR_NONFATAL, "invalid combination of opcode and operands"); @@ -483,7 +503,7 @@ long assemble(long segment, long offset, int bits, unsigned long cp, return 0; } -long insn_size(long segment, long offset, int bits, unsigned long cp, +int32_t insn_size(int32_t segment, int32_t offset, int bits, uint32_t cp, insn * instruction, efunc error) { struct itemplate *temp; @@ -499,7 +519,7 @@ long insn_size(long segment, long offset, int bits, unsigned long cp, instruction->opcode == I_DD || instruction->opcode == I_DQ || instruction->opcode == I_DT) { extop *e; - long isize, osize, wsize = 0; /* placate gcc */ + int32_t isize, osize, wsize = 0; /* placate gcc */ isize = 0; switch (instruction->opcode) { @@ -521,7 +541,7 @@ long insn_size(long segment, long offset, int bits, unsigned long cp, } for (e = instruction->eops; e; e = e->next) { - long align; + int32_t align; osize = 0; if (e->type == EOT_DB_NUMBER) @@ -538,11 +558,11 @@ long insn_size(long segment, long offset, int bits, unsigned long cp, } if (instruction->opcode == I_INCBIN) { - char fname[FILENAME_MAX]; + int8_t fname[FILENAME_MAX]; FILE *fp; - long len; - char *prefix = "", *combine; - char **pPrevPath = NULL; + int32_t len; + int8_t *prefix = "", *combine; + int8_t **pPrevPath = NULL; len = FILENAME_MAX - 1; if (len > instruction->eops->stringlen) @@ -588,16 +608,15 @@ long insn_size(long segment, long offset, int bits, unsigned long cp, return 0; /* if we're here, there's an error */ } - temp = nasm_instructions[instruction->opcode]; - while (temp->opcode != -1) { - int m = matches(temp, instruction); + for (temp = nasm_instructions[instruction->opcode]; temp->opcode != -1; temp++) { + int m = matches(temp, instruction, bits); if (m == 99) m += jmp_match(segment, offset, bits, instruction, temp->code); if (m == 100) { /* we've matched an instruction. */ - long isize; - const char *codes = temp->code; + int32_t isize; + const int8_t *codes = temp->code; int j; isize = calcsize(segment, offset, bits, instruction, codes); @@ -607,13 +626,14 @@ long insn_size(long segment, long offset, int bits, unsigned long cp, if ((instruction->prefixes[j] != P_A16 && instruction->prefixes[j] != P_O16 && bits == 16) || (instruction->prefixes[j] != P_A32 && - instruction->prefixes[j] != P_O32 && bits == 32)) { + instruction->prefixes[j] != P_O32 && bits == 32) || + (instruction->prefixes[j] == P_A32 && + instruction->prefixes[j] != P_O32 && bits == 64)) { isize++; } } return isize * instruction->times; } - temp++; } return -1; /* didn't match any instruction */ } @@ -622,7 +642,7 @@ long insn_size(long segment, long offset, int bits, unsigned long cp, and return the signed value*/ static int is_sbyte(insn * ins, int op, int size) { - signed long v; + int32_t v; int ret; ret = !(ins->forw_ref && ins->oprs[op].opflags) && /* dead in the water on forward reference or External */ @@ -632,16 +652,19 @@ static int is_sbyte(insn * ins, int op, int size) v = ins->oprs[op].offset; if (size == 16) - v = (signed short)v; /* sign extend if 16 bits */ + v = (int16_t)v; /* sign extend if 16 bits */ return ret && v >= -128L && v <= 127L; } -static long calcsize(long segment, long offset, int bits, - insn * ins, const char *codes) +static int32_t calcsize(int32_t segment, int32_t offset, int bits, + insn * ins, const int8_t *codes) { - long length = 0; - unsigned char c; + int32_t length = 0; + uint8_t c; + int t; + ins->rex = 0; /* Ensure REX is reset */ + int rex_mask = 0xFF; (void)segment; /* Don't warn that this parameter is unused */ (void)offset; /* Don't warn that this parameter is unused */ @@ -662,6 +685,17 @@ static long calcsize(long segment, long offset, int bits, case 010: case 011: case 012: + if (bits == 64) { + t = regval(&ins->oprs[c - 010]); + if (t >= 0400 && t < 0500) { /* Calculate REX.B */ + if (t < 0410 || (t >= 0440 && t < 0450)) + ins->rex |= 0xF0; /* Set REX.0 */ + else + ins->rex |= 0xF1; /* Set REX.B */ + if (t >= 0440) + ins->rex |= 0xF8; /* Set REX.W */ + } + } codes++, length++; break; case 017: @@ -690,7 +724,7 @@ static long calcsize(long segment, long offset, int bits, case 034: case 035: case 036: - if (ins->oprs[c - 034].type & (BITS16 | BITS32)) + if (ins->oprs[c - 034].type & (BITS16 | BITS32 | BITS64)) length += (ins->oprs[c - 034].type & BITS16) ? 2 : 4; else length += (bits == 16) ? 2 : 4; @@ -707,14 +741,18 @@ static long calcsize(long segment, long offset, int bits, case 045: case 046: length += ((ins->oprs[c - 044].addr_size ? - ins->oprs[c - 044].addr_size : bits) == - 16 ? 2 : 4); + ins->oprs[c - 044].addr_size : bits) >> 3); break; case 050: case 051: case 052: length++; break; + case 054: + case 055: + case 056: + length += 8; /* MOV reg64/imm */ + break; case 060: case 061: case 062: @@ -723,7 +761,7 @@ static long calcsize(long segment, long offset, int bits, case 064: case 065: case 066: - if (ins->oprs[c - 064].type & (BITS16 | BITS32)) + if (ins->oprs[c - 064].type & (BITS16 | BITS32 | BITS64)) length += (ins->oprs[c - 064].type & BITS16) ? 2 : 4; else length += (bits == 16) ? 2 : 4; @@ -757,25 +795,43 @@ static long calcsize(long segment, long offset, int bits, break; case 0300: case 0301: - case 0302: + case 0302: + if (bits == 64) { /* Calculate REX */ + t = ins->oprs[c - 0300].basereg; + if (t >= EXPR_REG_START && t < REG_ENUM_LIMIT) { + t = regvals[t]; + if ((t >= 0410 && t < 0440) || (t >= 0450 && t < 0500)) { + ins->rex |= 0xF1; /* Set REX.B */ + } + } + } length += chsize(&ins->oprs[c - 0300], bits); break; case 0310: - length += (bits == 32); + length += (bits != 16); break; case 0311: - length += (bits == 16); + length += (bits != 32); break; case 0312: + break; + case 0313: + length -= 1; break; case 0320: - length += (bits == 32); + length += (bits != 16); break; case 0321: length += (bits == 16); break; case 0322: break; + case 0323: + rex_mask = 0x07; + break; + case 0324: + length++; + break; case 0330: codes++, length++; break; @@ -804,37 +860,64 @@ static long calcsize(long segment, long offset, int bits, default: /* can't do it by 'case' statements */ if (c >= 0100 && c <= 0277) { /* it's an EA */ ea ea_data; + int rfield; + ea_data.rex = 0; /* Ensure ea.REX is initially 0 */ + + if (bits == 64) { + if (c <= 0177) /* pick rfield from operand b */ + rfield = regval(&ins->oprs[c & 7]); + else + rfield = c & 7; + } else + rfield = 0; + if (!process_ea - (&ins->oprs[(c >> 3) & 7], &ea_data, bits, 0, - ins->forw_ref)) { + (&ins->oprs[(c >> 3) & 7], &ea_data, bits, + rfield, ins->forw_ref)) { errfunc(ERR_NONFATAL, "invalid effective address"); return -1; - } else + } else { + if (bits == 64) + ins->rex |= ea_data.rex; length += ea_data.size; + } } else errfunc(ERR_PANIC, "internal instruction table corrupt" ": instruction code 0x%02X given", c); } - return length; -} -static void gencode(long segment, long offset, int bits, - insn * ins, const char *codes, long insn_end) + if (bits == 64) { + ins->rex &= rex_mask; + if (ins->rex) + length += 1; + } + +return length; } + +static void gencode(int32_t segment, int32_t offset, int bits, + insn * ins, const int8_t *codes, int32_t insn_end) { - static char condval[] = { /* conditional opcodes */ + static int8_t condval[] = { /* conditional opcodes */ 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2, 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5, 0x0, 0xA, 0xA, 0xB, 0x8, 0x4 }; - unsigned char c; - unsigned char bytes[4]; - long data, size; - + uint8_t c; + uint8_t bytes[4]; + int32_t size; + int64_t data; + while (*codes) switch (c = *codes++) { case 01: case 02: case 03: + if(ins->rex && (bits == 64)) { /* REX Supercedes all other Prefixes */ + ins->rex = (ins->rex&0x0F)+0x40; + out(offset, segment, &ins->rex, OUT_RAWDATA + 1, NO_SEG, NO_SEG); + ins->rex = 0; + offset += 1; + } out(offset, segment, codes, OUT_RAWDATA + c, NO_SEG, NO_SEG); codes += c; offset += c; @@ -883,7 +966,13 @@ static void gencode(long segment, long offset, int bits, case 010: case 011: case 012: - bytes[0] = *codes++ + regval(&ins->oprs[c - 010]); + if(ins->rex && (bits == 64)) { /* REX Supercedes all other Prefixes */ + ins->rex = (ins->rex&0x0F)+0x40; + out(offset, segment, &ins->rex, OUT_RAWDATA + 1, NO_SEG, NO_SEG); + ins->rex = 0; + offset += 1; + } + bytes[0] = *codes++ + ((regval(&ins->oprs[c - 010])) & 7); out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG); offset += 1; break; @@ -1006,7 +1095,7 @@ static void gencode(long segment, long offset, int bits, case 046: data = ins->oprs[c - 044].offset; size = ((ins->oprs[c - 044].addr_size ? - ins->oprs[c - 044].addr_size : bits) == 16 ? 2 : 4); + ins->oprs[c - 044].addr_size : bits) >> 3); if (size == 2 && (data < -65536L || data > 65535L)) errfunc(ERR_WARNING, "word value exceeds bounds"); out(offset, segment, &data, OUT_ADDRESS + size, @@ -1027,6 +1116,15 @@ static void gencode(long segment, long offset, int bits, out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG); offset += 1; break; + + case 054: + case 055: + case 056: + data = (int64_t)ins->oprs[c - 054].offset; + out(offset, segment, &data, OUT_ADDRESS + 8, + ins->oprs[c - 054].segment, ins->oprs[c - 054].wrt); + offset += 8; + break; case 060: case 061: @@ -1047,12 +1145,12 @@ static void gencode(long segment, long offset, int bits, case 064: case 065: case 066: - if (ins->oprs[c - 064].type & (BITS16 | BITS32)) + if (ins->oprs[c - 064].type & (BITS16 | BITS32 | BITS64)) size = (ins->oprs[c - 064].type & BITS16) ? 2 : 4; else size = (bits == 16) ? 2 : 4; if (ins->oprs[c - 064].segment != segment) { - long reltype = (size == 2 ? OUT_REL2ADR : OUT_REL4ADR); + int32_t reltype = (size == 2 ? OUT_REL2ADR : OUT_REL4ADR); data = ins->oprs[c - 064].offset; out(offset, segment, &data, reltype + insn_end - offset, ins->oprs[c - 064].segment, ins->oprs[c - 064].wrt); @@ -1104,6 +1202,12 @@ static void gencode(long segment, long offset, int bits, case 0133: case 0134: case 0135: + if(ins->rex && (bits == 64)) { /* REX Supercedes all other Prefixes */ + ins->rex = (ins->rex&0x0F)+0x40; + out(offset, segment, &ins->rex, OUT_RAWDATA + 1, NO_SEG, NO_SEG); + ins->rex = 0; + offset += 1; + } codes++; bytes[0] = *codes++; if (is_sbyte(ins, c - 0133, 16)) @@ -1131,6 +1235,12 @@ static void gencode(long segment, long offset, int bits, case 0143: case 0144: case 0145: + if(ins->rex && (bits == 64)) { /* REX Supercedes all other Prefixes */ + ins->rex = (ins->rex&0x0F)+0x40; + out(offset, segment, &ins->rex, OUT_RAWDATA + 1, NO_SEG, NO_SEG); + ins->rex = 0; + offset += 1; + } codes++; bytes[0] = *codes++; if (is_sbyte(ins, c - 0143, 32)) @@ -1152,7 +1262,7 @@ static void gencode(long segment, long offset, int bits, break; case 0310: - if (bits == 32) { + if (bits != 16) { *bytes = 0x67; out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG); @@ -1162,7 +1272,7 @@ static void gencode(long segment, long offset, int bits, break; case 0311: - if (bits == 16) { + if (bits != 32) { *bytes = 0x67; out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG); @@ -1174,8 +1284,12 @@ static void gencode(long segment, long offset, int bits, case 0312: break; + case 0313: + ins->rex = 0; + break; + case 0320: - if (bits == 32) { + if (bits != 16) { *bytes = 0x66; out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG); @@ -1195,8 +1309,13 @@ static void gencode(long segment, long offset, int bits, break; case 0322: + case 0323: + break; + + case 0324: + ins->rex |= 0xF8; break; - + case 0330: *bytes = *codes++ ^ condval[ins->condition]; out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG); @@ -1219,7 +1338,7 @@ static void gencode(long segment, long offset, int bits, if (ins->oprs[0].segment != NO_SEG) errfunc(ERR_PANIC, "non-constant BSS size in pass two"); else { - long size = ins->oprs[0].offset << (c - 0340); + int32_t size = ins->oprs[0].offset << (c - 0340); if (size > 0) out(offset, segment, NULL, OUT_RESERVE + size, NO_SEG, NO_SEG); @@ -1239,12 +1358,12 @@ static void gencode(long segment, long offset, int bits, break; default: /* can't do it by 'case' statements */ - if (c >= 0100 && c <= 0277) { /* it's an EA */ + if ( c >= 0100 && c <= 0277) { /* it's an EA */ ea ea_data; int rfield; - unsigned char *p; - long s; - + uint8_t *p; + int32_t s; + if (c <= 0177) /* pick rfield from operand b */ rfield = regval(&ins->oprs[c & 7]); else /* rfield is constant */ @@ -1255,7 +1374,7 @@ static void gencode(long segment, long offset, int bits, ins->forw_ref)) { errfunc(ERR_NONFATAL, "invalid effective address"); } - + p = bytes; *p++ = ea_data.modrm; if (ea_data.sib_present) @@ -1281,11 +1400,12 @@ static void gencode(long segment, long offset, int bits, } s++; break; + case 8: case 2: case 4: data = ins->oprs[(c >> 3) & 7].offset; - out(offset, segment, &data, - OUT_ADDRESS + ea_data.bytes, + out(offset, segment, &data, /* RIP = Relative, not Absolute */ + (ea_data.rip ? OUT_REL4ADR : OUT_ADDRESS) + ea_data.bytes, ins->oprs[(c >> 3) & 7].segment, ins->oprs[(c >> 3) & 7].wrt); s += ea_data.bytes; @@ -1298,8 +1418,6 @@ static void gencode(long segment, long offset, int bits, } } -#include "regvals.c" - static int regval(operand * o) { if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) { @@ -1308,9 +1426,9 @@ static int regval(operand * o) return regvals[o->basereg]; } -static int matches(struct itemplate *itemp, insn * instruction) +static int matches(struct itemplate *itemp, insn * instruction, int bits) { - int i, size[3], asize, oprs, ret; + int i, b, x, size[3], asize, oprs, ret; ret = 100; @@ -1332,7 +1450,7 @@ static int matches(struct itemplate *itemp, insn * instruction) for (i = 0; i < itemp->operands; i++) if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON | TO)) return 0; - + /* * Check that the operand flags all match up */ @@ -1344,7 +1462,6 @@ static int matches(struct itemplate *itemp, insn * instruction) (instruction->oprs[i].type & SIZE_MASK)) return 0; else -/* ret = 1; */ return 1; } @@ -1373,6 +1490,10 @@ static int matches(struct itemplate *itemp, insn * instruction) size[i] = BITS16; } else if (itemp->flags & IF_SD) { size[i] = BITS32; + } else if (itemp->flags & IF_SQ) { + if (bits != 64) + return 2; + size[i] = BITS64; } } else { asize = 0; @@ -1385,10 +1506,15 @@ static int matches(struct itemplate *itemp, insn * instruction) } else if (itemp->flags & IF_SD) { asize = BITS32; oprs = itemp->operands; + } else if (itemp->flags & IF_SQ) { + if (bits != 64) + return 2; + asize = BITS64; + oprs = itemp->operands; } size[0] = size[1] = size[2] = asize; } - + if (itemp->flags & (IF_SM | IF_SM2)) { oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands); asize = 0; @@ -1404,22 +1530,44 @@ static int matches(struct itemplate *itemp, insn * instruction) oprs = itemp->operands; } - for (i = 0; i < itemp->operands; i++) + for (i = 0; i < itemp->operands; i++) { if (!(itemp->opd[i] & SIZE_MASK) && (instruction->oprs[i].type & SIZE_MASK & ~size[i])) -/* ret = 2; */ return 2; + if ( (((itemp->opd[i] & SIZE_MASK) == BITS64) || + ((instruction->oprs[i].type & SIZE_MASK) == BITS64)) + && bits != 64) + return 2; + + x = instruction->oprs[i].indexreg; + b = instruction->oprs[i].basereg; + + if (x != -1 && x >= EXPR_REG_START && x < REG_ENUM_LIMIT) + x = regvals[x]; + if (b != -1 && b >= EXPR_REG_START && b < REG_ENUM_LIMIT) + b = regvals[b]; + + if (((b >= 0400 && b <= 0500) || (x >= 0400 && x < 0500)) && bits != 64) + return 2; + } + /* * Check template is okay at the set cpu level */ - if ((itemp->flags & IF_PLEVEL) > cpu) + if (((itemp->flags & IF_PLEVEL) > cpu)) return 3; + + /* + * Check if instruction is available in long mode + */ + if ((itemp->flags & IF_NOLONG) && (bits == 64)) + return 4; /* * Check if special handling needed for Jumps */ - if ((unsigned char)(itemp->code[0]) >= 0370) + if ((uint8_t)(itemp->code[0]) >= 0370) return 99; return ret; @@ -1428,195 +1576,202 @@ static int matches(struct itemplate *itemp, insn * instruction) static ea *process_ea(operand * input, ea * output, int addrbits, int rfield, int forw_ref) { - if (!(REGISTER & ~input->type)) { /* it's a single register */ - static int regs[] = { - R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH, - R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI, - R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI, - R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7, - R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7 - }; + + int rip = FALSE; /* Used for RIP-relative addressing */ + + + if (!(REGISTER & ~input->type)) { /* register direct */ int i; - - for (i = 0; i < elements(regs); i++) - if (input->basereg == regs[i]) - break; - if (i < elements(regs)) { - output->sib_present = FALSE; /* no SIB necessary */ - output->bytes = 0; /* no offset necessary either */ - output->modrm = 0xC0 | (rfield << 3) | (i & 7); - } else + if ( input->basereg < EXPR_REG_START /* Verify as Register */ + || input->basereg >= REG_ENUM_LIMIT) return NULL; + i = regvals[input->basereg]; + if ( i >= 0100 && i < 0210) /* GPR's, MMX & XMM only */ + return NULL; + + if (i >= 0400 && i < 0500) { /* Calculate REX.B */ + if (i < 0410 || (i >= 0440 && i < 0450)) + output->rex |= 0xF0; /* Set REX.0 */ + else + output->rex |= 0xF1; /* Set REX.B */ + if (i >= 0440) + output->rex |= 0xF8; /* Set REX.W */ + } + + if ((rfield >= 0400 && rfield < 0500) || /* Calculate REX.R */ + (rfield >= 0120 && rfield < 0200 && /* Include CR/DR/TR... */ + !(rfield & 0010))) { /* ... extensions, only */ + if ((rfield >= 0400 && rfield < 0410) || (rfield >= 0440 && rfield < 0450)) + output->rex |= 0xF0; /* Set REX.0 */ + else + output->rex |= 0xF4; /* Set REX.R */ + if (rfield >= 0440) + output->rex |= 0xF8; /* Set REX.W */ + } + + output->sib_present = FALSE; /* no SIB necessary */ + output->bytes = 0; /* no offset necessary either */ + output->modrm = 0xC0 | ((rfield & 7) << 3) | (i & 7); } else { /* it's a memory reference */ + if (input->basereg == -1 && (input->indexreg == -1 || input->scale == 0)) { /* it's a pure offset */ if (input->addr_size) addrbits = input->addr_size; + + if (rfield >= 0400 && rfield < 0500) { /* Calculate REX.R */ + if (rfield < 0410 || (rfield >= 0440 && rfield < 0450)) + output->rex |= 0xF0; /* Set REX.0 */ + else + output->rex |= 0xF4; /* Set REX.R */ + if (rfield >= 0440) + output->rex |= 0xF8; /* Set REX.W */ + } + output->sib_present = FALSE; - output->bytes = (addrbits == 32 ? 4 : 2); - output->modrm = (addrbits == 32 ? 5 : 6) | (rfield << 3); + output->bytes = (addrbits != 16 ? 4 : 2); + output->modrm = (addrbits != 16 ? 5 : 6) | ((rfield & 7) << 3); } else { /* it's an indirection */ int i = input->indexreg, b = input->basereg, s = input->scale; - long o = input->offset, seg = input->segment; + int32_t o = input->offset, seg = input->segment; int hb = input->hintbase, ht = input->hinttype; int t; + int it, bt; if (s == 0) i = -1; /* make this easy, at least */ + + if (i != -1 && i >= EXPR_REG_START + && i < REG_ENUM_LIMIT) + it = regvals[i]; + else + it = -1; + + if (b != -1 && b >= EXPR_REG_START + && b < REG_ENUM_LIMIT) + bt = regvals[b]; + else + bt = -1; + + /* check for a 32/64-bit memory reference... */ + if ((it >= 0020 && it < 0030) || (it >= 0430 && it < 0460) || + (bt >= 0020 && bt < 0030) || (bt >= 0430 && bt < 0460) || + bt == 0500) { + /* it must be a 32/64-bit memory reference. Firstly we have + * to check that all registers involved are type E/Rxx. */ + t = 1; + if (it != -1) { + if (it < 0020 || (it >= 0030 && it < 0430) || it >= 0460) + return NULL; + if (it >= 0440) + t = 2; + else + t = 0; + } - if (i == R_EAX || i == R_EBX || i == R_ECX || i == R_EDX - || i == R_EBP || i == R_ESP || i == R_ESI || i == R_EDI - || b == R_EAX || b == R_EBX || b == R_ECX || b == R_EDX - || b == R_EBP || b == R_ESP || b == R_ESI || b == R_EDI) { - /* it must be a 32-bit memory reference. Firstly we have - * to check that all registers involved are type Exx. */ - if (i != -1 && i != R_EAX && i != R_EBX && i != R_ECX - && i != R_EDX && i != R_EBP && i != R_ESP && i != R_ESI - && i != R_EDI) - return NULL; - if (b != -1 && b != R_EAX && b != R_EBX && b != R_ECX - && b != R_EDX && b != R_EBP && b != R_ESP && b != R_ESI - && b != R_EDI) - return NULL; - + if (bt != -1) { + if (bt < 0020 || (bt >= 0030 && bt < 0430) || (bt >= 0460 && bt < 0500)) + return NULL; + if (bt == 0500) { + bt = b = -1; + rip = TRUE; + } else if (bt >= 0440) { + if (t < 1) + return NULL; + } else { + if (t > 1) + return NULL; + } + } + /* While we're here, ensure the user didn't specify WORD. */ if (input->addr_size == 16) return NULL; - /* now reorganise base/index */ - if (s == 1 && b != i && b != -1 && i != -1 && - ((hb == b && ht == EAH_NOTBASE) - || (hb == i && ht == EAH_MAKEBASE))) - t = b, b = i, i = t; /* swap if hints say so */ - if (b == i) /* convert EAX+2*EAX to 3*EAX */ - b = -1, s++; - if (b == -1 && s == 1 && !(hb == i && ht == EAH_NOTBASE)) - b = i, i = -1; /* make single reg base, unless hint */ - if (((s == 2 && i != R_ESP + /* now reorganize base/index */ + if (s == 1 && bt != it && bt != -1 && it != -1 && + ((hb == bt && ht == EAH_NOTBASE) + || (hb == it && ht == EAH_MAKEBASE))) + t = bt, bt = it, it = t; /* swap if hints say so */ + if (bt == it) /* convert EAX+2*EAX to 3*EAX */ + bt = -1, s++; + if (bt == -1 && s == 1 && !(hb == it && ht == EAH_NOTBASE)) + bt = i, it = -1; /* make single reg base, unless hint */ + if (((s == 2 && (it & 7) != (REG_NUM_ESP & 7) && !(input->eaflags & EAF_TIMESTWO)) || s == 3 - || s == 5 || s == 9) && b == -1) - b = i, s--; /* convert 3*EAX to EAX+2*EAX */ - if (i == -1 && b != R_ESP + || s == 5 || s == 9) && bt == -1) + bt = it, s--; /* convert 3*EAX to EAX+2*EAX */ + if (it == -1 && (bt & 7) != (REG_NUM_ESP & 7) && (input->eaflags & EAF_TIMESTWO)) - i = b, b = -1, s = 1; + it = bt, bt = -1, s = 1; /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */ - if (s == 1 && i == R_ESP) /* swap ESP into base if scale is 1 */ - i = b, b = R_ESP; - if (i == R_ESP - || (s != 1 && s != 2 && s != 4 && s != 8 && i != -1)) + if (s == 1 && (it & 7) == (REG_NUM_ESP & 7)) /* swap ESP into base if scale is 1 */ + t = it, it = bt, bt = t; + if ((it & 7) == (REG_NUM_ESP & 7) + || (s != 1 && s != 2 && s != 4 && s != 8 && it != -1)) return NULL; /* wrong, for various reasons */ - if (i == -1 && b != R_ESP) { /* no SIB needed */ + if (i >= 0400 && i < 0500) { /* Calculate REX.I */ + if (i < 0410 || (i >= 0440 && i < 0450)) + output->rex |= 0xF0; /* Set REX.0 */ + else + output->rex |= 0xF2; /* Set REX.I */ + if (i >= 0440) + output->rex |= 0xF8; /* Set REX.W */ + } + + if (b >= 0400 && b < 0500) { /* Calculate REX.B */ + if (b < 0410 || (b >= 0440 && b < 0450)) + output->rex |= 0xF0; /* Set REX.0 */ + else + output->rex |= 0xF1; /* Set REX.B */ + if (b >= 0440) + output->rex |= 0xF8; /* Set REX.W */ + } + + if (rfield >= 0400 && rfield < 0500) { /* Calculate REX.R */ + if (rfield < 0410 || (rfield >= 0440 && rfield < 0450)) + output->rex |= 0xF0; /* Set REX.0 */ + else + output->rex |= 0xF4; /* Set REX.R */ + if (rfield >= 0440) + output->rex |= 0xF8; /* Set REX.W */ + } + + if (it == -1 && (bt & 7) != (REG_NUM_ESP & 7)) { /* no SIB needed */ int mod, rm; - switch (b) { - case R_EAX: - rm = 0; - break; - case R_ECX: - rm = 1; - break; - case R_EDX: - rm = 2; - break; - case R_EBX: - rm = 3; - break; - case R_EBP: + + if (bt == -1) { rm = 5; - break; - case R_ESI: - rm = 6; - break; - case R_EDI: - rm = 7; - break; - case -1: - rm = 5; - break; - default: /* should never happen */ - return NULL; - } - if (b == -1 || (b != R_EBP && o == 0 && - seg == NO_SEG && !forw_ref && - !(input->eaflags & - (EAF_BYTEOFFS | EAF_WORDOFFS)))) mod = 0; - else if (input->eaflags & EAF_BYTEOFFS || - (o >= -128 && o <= 127 && seg == NO_SEG - && !forw_ref - && !(input->eaflags & EAF_WORDOFFS))) { - mod = 1; - } else - mod = 2; + } else { + rm = (bt & 7); + if (rm != (REG_NUM_EBP & 7) && o == 0 && + seg == NO_SEG && !forw_ref && + !(input->eaflags & + (EAF_BYTEOFFS | EAF_WORDOFFS))) + mod = 0; + else if (input->eaflags & EAF_BYTEOFFS || + (o >= -128 && o <= 127 && seg == NO_SEG + && !forw_ref + && !(input->eaflags & EAF_WORDOFFS))) + mod = 1; + else + mod = 2; + } output->sib_present = FALSE; - output->bytes = (b == -1 || mod == 2 ? 4 : mod); - output->modrm = (mod << 6) | (rfield << 3) | rm; + output->bytes = (bt == -1 || mod == 2 ? 4 : mod); + output->modrm = (mod << 6) | ((rfield & 7) << 3) | rm; } else { /* we need a SIB */ int mod, scale, index, base; - - switch (b) { - case R_EAX: - base = 0; - break; - case R_ECX: - base = 1; - break; - case R_EDX: - base = 2; - break; - case R_EBX: - base = 3; - break; - case R_ESP: - base = 4; - break; - case R_EBP: - case -1: - base = 5; - break; - case R_ESI: - base = 6; - break; - case R_EDI: - base = 7; - break; - default: /* then what the smeg is it? */ - return NULL; /* panic */ - } - - switch (i) { - case R_EAX: - index = 0; - break; - case R_ECX: - index = 1; - break; - case R_EDX: - index = 2; - break; - case R_EBX: - index = 3; - break; - case -1: - index = 4; - break; - case R_EBP: - index = 5; - break; - case R_ESI: - index = 6; - break; - case R_EDI: - index = 7; - break; - default: /* then what the smeg is it? */ - return NULL; /* panic */ - } - - if (i == -1) - s = 1; + + if (it == -1) + index = 4, s = 1; + else + index = (it & 7); + switch (s) { case 1: scale = 0; @@ -1633,27 +1788,37 @@ static ea *process_ea(operand * input, ea * output, int addrbits, default: /* then what the smeg is it? */ return NULL; /* panic */ } - - if (b == -1 || (b != R_EBP && o == 0 && + + if (bt == -1) { + base = 5; + mod = 0; + } else { + base = (bt & 7); + if (base != (REG_NUM_EBP & 7) && o == 0 && seg == NO_SEG && !forw_ref && !(input->eaflags & - (EAF_BYTEOFFS | EAF_WORDOFFS)))) - mod = 0; - else if (input->eaflags & EAF_BYTEOFFS || - (o >= -128 && o <= 127 && seg == NO_SEG - && !forw_ref - && !(input->eaflags & EAF_WORDOFFS))) - mod = 1; - else - mod = 2; + (EAF_BYTEOFFS | EAF_WORDOFFS))) + mod = 0; + else if (input->eaflags & EAF_BYTEOFFS || + (o >= -128 && o <= 127 && seg == NO_SEG + && !forw_ref + && !(input->eaflags & EAF_WORDOFFS))) + mod = 1; + else + mod = 2; + } output->sib_present = TRUE; - output->bytes = (b == -1 || mod == 2 ? 4 : mod); - output->modrm = (mod << 6) | (rfield << 3) | 4; + output->bytes = (bt == -1 || mod == 2 ? 4 : mod); + output->modrm = (mod << 6) | ((rfield & 7) << 3) | 4; output->sib = (scale << 6) | (index << 3) | base; } } else { /* it's 16-bit */ int mod, rm; + + /* check for 64-bit long mode */ + if (addrbits == 64) + return NULL; /* check all registers are BX, BP, SI or DI */ if ((b != -1 && b != R_BP && b != R_BX && b != R_SI @@ -1661,8 +1826,8 @@ static ea *process_ea(operand * input, ea * output, int addrbits, && i != R_SI && i != R_DI)) return NULL; - /* ensure the user didn't specify DWORD */ - if (input->addr_size == 32) + /* ensure the user didn't specify DWORD/QWORD */ + if (input->addr_size == 32 || input->addr_size == 64) return NULL; if (s != 1 && i != -1) @@ -1732,10 +1897,25 @@ static ea *process_ea(operand * input, ea * output, int addrbits, output->sib_present = FALSE; /* no SIB - it's 16-bit */ output->bytes = mod; /* bytes of offset needed */ - output->modrm = (mod << 6) | (rfield << 3) | rm; + output->modrm = (mod << 6) | ((rfield & 7) << 3) | rm; } } } + + /* Process RIP-relative Addressing */ + if (rip) { + if ((output->modrm & 0xC7) != 0x05) + return NULL; + output->rip = TRUE; + } else { + output->rip = FALSE; + if (globalbits == 64 && /* Actual Disp32 needs blank SIB on x64 */ + !(output->sib_present) && ((output->modrm & 0xC7) == 0x05)) { + output->sib_present = TRUE; + output->modrm --; /* RM Field = 4 (forward to Base of SIB) */ + output->sib = (4 << 3) | 5; /* Index = 4 (none), Base = 5 */ + } + } output->size = 1 + output->sib_present + output->bytes; return output; } @@ -1743,19 +1923,29 @@ static ea *process_ea(operand * input, ea * output, int addrbits, static int chsize(operand * input, int addrbits) { if (!(MEMORY & ~input->type)) { - int i = input->indexreg, b = input->basereg; + int i, b; + + if ( input->indexreg < EXPR_REG_START /* Verify as Register */ + || input->indexreg >= REG_ENUM_LIMIT) + i = -1; + else + i = regvals[input->indexreg]; + + if ( input->basereg < EXPR_REG_START /* Verify as Register */ + || input->basereg >= REG_ENUM_LIMIT) + b = -1; + else + b = regvals[input->basereg]; if (input->scale == 0) i = -1; if (i == -1 && b == -1) /* pure offset */ return (input->addr_size != 0 && input->addr_size != addrbits); - - if (i == R_EAX || i == R_EBX || i == R_ECX || i == R_EDX - || i == R_EBP || i == R_ESP || i == R_ESI || i == R_EDI - || b == R_EAX || b == R_EBX || b == R_ECX || b == R_EDX - || b == R_EBP || b == R_ESP || b == R_ESI || b == R_EDI) - return (addrbits == 16); + + if ((i >= 0020 && i < 0030) || (i >= 0430 && i < 0440) || + (b >= 0020 && b < 0030) || (b >= 0430 && b < 0440)) + return (addrbits != 32); else return (addrbits == 32); } else @@ -9,9 +9,9 @@ #ifndef NASM_ASSEMBLE_H #define NASM_ASSEMBLE_H -long insn_size(long segment, long offset, int bits, unsigned long cpu, +int32_t insn_size(int32_t segment, int32_t offset, int bits, uint32_t cp, insn * instruction, efunc error); -long assemble(long segment, long offset, int bits, unsigned long cpu, +int32_t assemble(int32_t segment, int32_t offset, int bits, uint32_t cp, insn * instruction, struct ofmt *output, efunc error, ListGen * listgen); @@ -10,6 +10,7 @@ #include <stdio.h> #include <string.h> +#include <inttypes.h> #include "nasm.h" #include "disasm.h" @@ -33,7 +34,7 @@ extern struct itemplate **itable[]; #define SEG_NODISP 64 #define SEG_SIGNED 128 -static int whichreg(long regflags, int regval) +static int whichreg(int32_t regflags, int regval) { #include "regdis.c" @@ -95,7 +96,7 @@ static int whichreg(long regflags, int regval) return 0; } -static const char *whichcond(int condval) +static const int8_t *whichcond(int condval) { static int conds[] = { C_O, C_NO, C_C, C_NC, C_Z, C_NZ, C_NA, C_A, @@ -107,7 +108,7 @@ static const char *whichcond(int condval) /* * Process an effective address (ModRM) specification. */ -static unsigned char *do_ea(unsigned char *data, int modrm, int asize, +static uint8_t *do_ea(uint8_t *data, int modrm, int asize, int segsize, operand * op) { int mod, rm, scale, index, base; @@ -174,7 +175,7 @@ static unsigned char *do_ea(unsigned char *data, int modrm, int asize, break; case 1: op->segment |= SEG_DISP8; - op->offset = (signed char)*data++; + op->offset = (int8_t)*data++; break; case 2: op->segment |= SEG_DISP16; @@ -293,14 +294,14 @@ static unsigned char *do_ea(unsigned char *data, int modrm, int asize, break; case 1: op->segment |= SEG_DISP8; - op->offset = (signed char)*data++; + op->offset = (int8_t)*data++; break; case 2: op->segment |= SEG_DISP32; op->offset = *data++; op->offset |= ((unsigned)*data++) << 8; - op->offset |= ((long)*data++) << 16; - op->offset |= ((long)*data++) << 24; + op->offset |= ((int32_t)*data++) << 16; + op->offset |= ((int32_t)*data++) << 24; break; } return data; @@ -311,11 +312,11 @@ static unsigned char *do_ea(unsigned char *data, int modrm, int asize, * Determine whether the instruction template in t corresponds to the data * stream in data. Return the number of bytes matched if so. */ -static int matches(struct itemplate *t, unsigned char *data, int asize, +static int matches(struct itemplate *t, uint8_t *data, int asize, int osize, int segsize, int rep, insn * ins) { - unsigned char *r = (unsigned char *)(t->code); - unsigned char *origdata = data; + uint8_t *r = (uint8_t *)(t->code); + uint8_t *origdata = data; int a_used = FALSE, o_used = FALSE; int drep = 0; @@ -401,7 +402,7 @@ static int matches(struct itemplate *t, unsigned char *data, int asize, if (*data++) return FALSE; if (c >= 014 && c <= 016) { - ins->oprs[c - 014].offset = (signed char)*data++; + ins->oprs[c - 014].offset = (int8_t)*data++; ins->oprs[c - 014].segment |= SEG_SIGNED; } if (c >= 020 && c <= 022) @@ -416,8 +417,8 @@ static int matches(struct itemplate *t, unsigned char *data, int asize, ins->oprs[c - 034].offset = *data++; ins->oprs[c - 034].offset |= (((unsigned)*data++) << 8); if (osize == 32) { - ins->oprs[c - 034].offset |= (((long)*data++) << 16); - ins->oprs[c - 034].offset |= (((long)*data++) << 24); + ins->oprs[c - 034].offset |= (((int32_t)*data++) << 16); + ins->oprs[c - 034].offset |= (((int32_t)*data++) << 24); } if (segsize != asize) ins->oprs[c - 034].addr_size = asize; @@ -425,21 +426,21 @@ static int matches(struct itemplate *t, unsigned char *data, int asize, if (c >= 040 && c <= 042) { ins->oprs[c - 040].offset = *data++; ins->oprs[c - 040].offset |= (((unsigned)*data++) << 8); - ins->oprs[c - 040].offset |= (((long)*data++) << 16); - ins->oprs[c - 040].offset |= (((long)*data++) << 24); + ins->oprs[c - 040].offset |= (((int32_t)*data++) << 16); + ins->oprs[c - 040].offset |= (((int32_t)*data++) << 24); } if (c >= 044 && c <= 046) { ins->oprs[c - 044].offset = *data++; ins->oprs[c - 044].offset |= (((unsigned)*data++) << 8); if (asize == 32) { - ins->oprs[c - 044].offset |= (((long)*data++) << 16); - ins->oprs[c - 044].offset |= (((long)*data++) << 24); + ins->oprs[c - 044].offset |= (((int32_t)*data++) << 16); + ins->oprs[c - 044].offset |= (((int32_t)*data++) << 24); } if (segsize != asize) ins->oprs[c - 044].addr_size = asize; } if (c >= 050 && c <= 052) { - ins->oprs[c - 050].offset = (signed char)*data++; + ins->oprs[c - 050].offset = (int8_t)*data++; ins->oprs[c - 050].segment |= SEG_RELATIVE; } if (c >= 060 && c <= 062) { @@ -452,8 +453,8 @@ static int matches(struct itemplate *t, unsigned char *data, int asize, ins->oprs[c - 064].offset = *data++; ins->oprs[c - 064].offset |= (((unsigned)*data++) << 8); if (osize == 32) { - ins->oprs[c - 064].offset |= (((long)*data++) << 16); - ins->oprs[c - 064].offset |= (((long)*data++) << 24); + ins->oprs[c - 064].offset |= (((int32_t)*data++) << 16); + ins->oprs[c - 064].offset |= (((int32_t)*data++) << 24); ins->oprs[c - 064].segment |= SEG_32BIT; } else ins->oprs[c - 064].segment &= ~SEG_32BIT; @@ -467,8 +468,8 @@ static int matches(struct itemplate *t, unsigned char *data, int asize, if (c >= 070 && c <= 072) { ins->oprs[c - 070].offset = *data++; ins->oprs[c - 070].offset |= (((unsigned)*data++) << 8); - ins->oprs[c - 070].offset |= (((long)*data++) << 16); - ins->oprs[c - 070].offset |= (((long)*data++) << 24); + ins->oprs[c - 070].offset |= (((int32_t)*data++) << 16); + ins->oprs[c - 070].offset |= (((int32_t)*data++) << 24); ins->oprs[c - 070].segment |= SEG_32BIT | SEG_RELATIVE; } if (c >= 0100 && c < 0130) { @@ -485,8 +486,8 @@ static int matches(struct itemplate *t, unsigned char *data, int asize, if (c >= 0140 && c <= 0142) { ins->oprs[c - 0140].offset = *data++; ins->oprs[c - 0140].offset |= (((unsigned)*data++) << 8); - ins->oprs[c - 0140].offset |= (((long)*data++) << 16); - ins->oprs[c - 0140].offset |= (((long)*data++) << 24); + ins->oprs[c - 0140].offset |= (((int32_t)*data++) << 16); + ins->oprs[c - 0140].offset |= (((int32_t)*data++) << 24); } if (c >= 0200 && c <= 0277) { int modrm = *data++; @@ -574,17 +575,17 @@ static int matches(struct itemplate *t, unsigned char *data, int asize, return data - origdata; } -long disasm(unsigned char *data, char *output, int outbufsize, int segsize, - long offset, int autosync, unsigned long prefer) +int32_t disasm(uint8_t *data, int8_t *output, int outbufsize, int segsize, + int32_t offset, int autosync, uint32_t prefer) { struct itemplate **p, **best_p; int length, best_length = 0; - char *segover; + int8_t *segover; int rep, lock, asize, osize, i, slen, colon; - unsigned char *origdata; + uint8_t *origdata; int works; insn tmp_ins, ins; - unsigned long goodness, best; + uint32_t goodness, best; /* * Scan for prefixes. @@ -793,7 +794,8 @@ long disasm(unsigned char *data, char *output, int outbufsize, int segsize, } else if (!(MEM_OFFS & ~(*p)->opd[i])) { slen += snprintf(output + slen, outbufsize - slen, "[%s%s%s0x%lx]", - (segover ? segover : ""), (segover ? ":" : ""), + ((const char*)segover ? (const char*)segover : ""), /* placate type mistmatch warning */ + ((const char*)segover ? ":" : ""), /* by using (const char*) instead of uint8_t* */ (ins.oprs[i].addr_size == 32 ? "dword " : ins.oprs[i].addr_size == 16 ? "word " : ""), ins.oprs[i].offset); @@ -853,7 +855,7 @@ long disasm(unsigned char *data, char *output, int outbufsize, int segsize, if (ins.oprs[i].segment & SEG_DISP8) { int sign = '+'; if (ins.oprs[i].offset & 0x80) { - ins.oprs[i].offset = -(signed char)ins.oprs[i].offset; + ins.oprs[i].offset = -(int8_t)ins.oprs[i].offset; sign = '-'; } slen += @@ -881,7 +883,7 @@ long disasm(unsigned char *data, char *output, int outbufsize, int segsize, } output[slen] = '\0'; if (segover) { /* unused segment override */ - char *p = output; + int8_t *p = output; int count = slen + 1; while (count--) p[count + 3] = p[count]; @@ -891,7 +893,7 @@ long disasm(unsigned char *data, char *output, int outbufsize, int segsize, return length; } -long eatbyte(unsigned char *data, char *output, int outbufsize) +int32_t eatbyte(uint8_t *data, int8_t *output, int outbufsize) { snprintf(output, outbufsize, "db 0x%02X", *data); return 1; @@ -11,8 +11,8 @@ #define INSN_MAX 32 /* one instruction can't be longer than this */ -long disasm(unsigned char *data, char *output, int outbufsize, int segsize, - long offset, int autosync, unsigned long prefer); -long eatbyte(unsigned char *data, char *output, int outbufsize); +int32_t disasm(uint8_t *data, int8_t *output, int outbufsize, int segsize, + int32_t offset, int autosync, uint32_t prefer); +int32_t eatbyte(uint8_t *data, int8_t *output, int outbufsize); #endif diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src index 6adbcea..18b24ed 100644 --- a/doc/nasmdoc.src +++ b/doc/nasmdoc.src @@ -6,7 +6,7 @@ \M{title}{NASM - The Netwide Assembler} \M{year}{2003} \M{author}{The NASM Development Team} -\M{license}{All rights reserved. This document is redistributable under the licence given in the file "COPYING" distributed in the NASM archive.} +\M{license}{All rights reserved. This document is redistributable under the license given in the file "COPYING" distributed in the NASM archive.} \M{summary}{This file documents NASM, the Netwide Assembler: an assembler targetting the Intel x86 series of processors, with portable source.} \M{infoname}{NASM} \M{infofile}{nasm} @@ -188,7 +188,7 @@ Object File Format \IA{sib}{sib byte} \IR{sib byte} SIB byte \IR{solaris x86} Solaris x86 -\IA{standard section names}{standardised section names} +\IA{standard section names}{standardized section names} \IR{symbols, exporting from dlls} symbols, exporting from DLLs \IR{symbols, importing from dlls} symbols, importing from DLLs \IR{test subdirectory} \c{test} subdirectory @@ -207,6 +207,7 @@ Object File Format \IR{visual c++} Visual C++ \IR{www page} WWW page \IR{win32} Win32 +\IR{win32} Win64 \IR{windows} Windows \IR{windows 95} Windows 95 \IR{windows nt} Windows NT @@ -221,14 +222,14 @@ Object File Format \H{whatsnasm} What Is NASM? -The Netwide Assembler, NASM, is an 80x86 assembler designed for +The Netwide Assembler, NASM, is an 80x86 and x86-64 assembler designed for portability and modularity. It supports a range of object file -formats, including Linux and \c{NetBSD/FreeBSD} \c{a.out}, \c{ELF}, -\c{COFF}, \c{Mach-O}, Microsoft 16-bit \c{OBJ} and \c{Win32}. It will also output -plain binary files. Its syntax is designed to be simple and easy to -understand, similar to Intel's but less complex. It supports \c{Pentium}, -\c{P6}, \c{MMX}, \c{3DNow!}, \c{SSE} and \c{SSE2} opcodes, and has -macro capability. +formats, including Linux and \c{*BSD} \c{a.out}, \c{ELF}, \c{COFF}, \c{Mach-O}, +Microsoft 16-bit \c{OBJ}, \c{Win32} and \c{Win64}. It will also output plain +binary files. Its syntax is designed to be simple and easy to understand, similar +to Intel's but less complex. It supports from the upto and including \c{Pentium}, +\c{P6}, \c{MMX}, \c{3DNow!}, \c{SSE}, \c{SSE2}, \c{SSE3} and \c{x64} opcodes. NASM has +a strong support for macro conventions. \S{yaasm} Why Yet Another Assembler? @@ -241,14 +242,14 @@ assembler around, and that maybe someone ought to write one. \b \i\c{a86} is good, but not free, and in particular you don't get any 32-bit capability until you pay. It's DOS only, too. -\b \i\c{gas} is free, and ports over DOS and Unix, but it's not +\b \i\c{gas} is free, and ports over to DOS and Unix, but it's not very good, since it's designed to be a back end to \i\c{gcc}, which always feeds it correct code. So its error checking is minimal. Also, its syntax is horrible, from the point of view of anyone trying to actually \e{write} anything in it. Plus you can't write 16-bit code in -it (properly). +it (properly.) -\b \i\c{as86} is Minix- and Linux-specific, and (my version at least) +\b \i\c{as86} is specific to Minix and Linux, and (my version at least) doesn't seem to have much (or any) documentation. \b \i\c{MASM} isn't very good, and it's (was) expensive, and it runs only under @@ -257,7 +258,7 @@ DOS. \b \i\c{TASM} is better, but still strives for MASM compatibility, which means millions of directives and tons of red tape. And its syntax is essentially MASM's, with the contradictions and quirks that -entails (although it sorts out some of those by means of Ideal mode). +entails (although it sorts out some of those by means of Ideal mode.) It's expensive too. And it's DOS-only. So here, for your coding pleasure, is NASM. At present it's @@ -269,17 +270,17 @@ know who you are), and we'll improve it out of all recognition. Again. -\S{legal} Licence Conditions +\S{legal} License Conditions Please see the file \c{COPYING}, supplied as part of any NASM -distribution archive, for the \i{licence} conditions under which you +distribution archive, for the \i{license} conditions under which you may use NASM. NASM is now under the so-called GNU Lesser General Public License, LGPL. \H{contact} Contact Information -The current version of NASM (since about 0.98.08) are maintained by a +The current version of NASM (since about 0.98.08) is maintained by a team of developers, accessible through the \c{nasm-devel} mailing list (see below for the link). If you want to report a bug, please read \k{bugs} first. @@ -735,7 +736,7 @@ The syntax is: -O0, but will produce successful assembly more often if branch offset sizes are not specified. Additionally, immediate operands which will fit in a signed byte - are optimised, unless the long form is specified. + are optimized, unless the long form is specified. \b \c{-On} multi-pass optimization, minimize branch offsets; also will minimize signed immediate bytes, overriding size specification @@ -1009,7 +1010,7 @@ on a misunderstanding by the authors. For historical reasons, NASM uses the keyword \i\c{TWORD} where MASM and compatible assemblers use \i\c{TBYTE}. -NASM does not declare \i{uninitialised storage} in the same way as +NASM does not declare \i{uninitialized storage} in the same way as MASM: where a MASM programmer might use \c{stack db 64 dup (?)}, NASM requires \c{stack resb 64}, intended to be read as `reserve 64 bytes'. For a limited amount of compatibility, since NASM treats @@ -1115,15 +1116,15 @@ Pseudo-instructions are things which, though not real x86 machine instructions, are used in the instruction field anyway because that's the most convenient place to put them. The current pseudo-instructions are \i\c{DB}, \i\c{DW}, \i\c{DD}, \i\c{DQ} and -\i\c{DT}, their \i{uninitialised} counterparts \i\c{RESB}, +\i\c{DT}, their \i{uninitialized} counterparts \i\c{RESB}, \i\c{RESW}, \i\c{RESD}, \i\c{RESQ} and \i\c{REST}, the \i\c{INCBIN} command, the \i\c{EQU} command, and the \i\c{TIMES} prefix. -\S{db} \c{DB} and friends: Declaring Initialised Data +\S{db} \c{DB} and friends: Declaring initialized Data \i\c{DB}, \i\c{DW}, \i\c{DD}, \i\c{DQ} and \i\c{DT} are used, much -as in MASM, to declare initialised data in the output file. They can +as in MASM, to declare initialized data in the output file. They can be invoked in a wide range of ways: \I{floating-point}\I{character constant}\I{string constant} @@ -1144,14 +1145,14 @@ be invoked in a wide range of ways: constants as operands. -\S{resb} \c{RESB} and friends: Declaring \i{Uninitialised} Data +\S{resb} \c{RESB} and friends: Declaring \i{Uninitialized} Data \i\c{RESB}, \i\c{RESW}, \i\c{RESD}, \i\c{RESQ} and \i\c{REST} are designed to be used in the BSS section of a module: they declare -\e{uninitialised} storage space. Each takes a single operand, which +\e{uninitialized} storage space. Each takes a single operand, which is the number of bytes, words, doublewords or whatever to reserve. As stated in \k{qsother}, NASM does not support the MASM/TASM syntax -of reserving uninitialised space by writing \I\c{?}\c{DW ?} or +of reserving uninitialized space by writing \I\c{?}\c{DW ?} or similar things: this is what it does instead. The operand to a \c{RESB}-type pseudo-instruction is a \i\e{critical expression}: see \k{crit}. @@ -2740,7 +2741,7 @@ able to nest these loops. NASM provides this level of power by means of a \e{context stack}. The preprocessor maintains a stack of \e{contexts}, each of which is -characterised by a name. You add a new context to the stack using +characterized by a name. You add a new context to the stack using the \i\c{%push} directive, and remove one using \i\c{%pop}. You can define labels that are local to a particular context on the stack. @@ -3004,6 +3005,14 @@ here'. You could then write a macro and then pepper your code with calls to \c{notdeadyet} until you find the crash point. +\S{bitsm} \i\c{__BITS__}: Current BITS Mode + +The \c{__BITS__} standard macro is updated every time that the BITS mode is +set using the \c{BITS XX} or \c{[BITS XX]} directive, where XX is a valid mode +number of 16, 32 or 64. \c{__BITS__} receives the specified mode number and +makes it globally available. This can be very useful for those who utilize +mode-dependent macros. + \S{struc} \i\c{STRUC} and \i\c{ENDSTRUC}: \i{Declaring Structure} Data Types @@ -3374,19 +3383,20 @@ documented along with the formats that implement them, in \k{outfmt}. The \c{BITS} directive specifies whether NASM should generate code \I{16-bit mode, versus 32-bit mode}designed to run on a processor -operating in 16-bit mode, or code designed to run on a processor -operating in 32-bit mode. The syntax is \c{BITS 16} or \c{BITS 32}. +operating in 16-bit mode, 32-bit mode or 64-bit mode. The syntax is +\c{BITS XX}, where XX is 16, 32 or 64. In most cases, you should not need to use \c{BITS} explicitly. The -\c{aout}, \c{coff}, \c{elf}, \c{macho} and \c{win32} object formats, which are -designed for use in 32-bit operating systems, all cause NASM to -select 32-bit mode by default. The \c{obj} object format allows you +\c{aout}, \c{coff}, \c{elf}, \c{macho}, \c{win32} and \c{win64} +object formats, which are designed for use in 32-bit or 64-bit +operating systems, all cause NASM to select 32-bit or 64-bit mode, +respectively, by default. The \c{obj} object format allows you to specify each segment you define as either \c{USE16} or \c{USE32}, and NASM will set its operating mode accordingly, so the use of the \c{BITS} directive is once again unnecessary. The most likely reason for using the \c{BITS} directive is to write -32-bit code in a flat binary file; this is because the \c{bin} +32-bit or 64-bit code in a flat binary file; this is because the \c{bin} output format defaults to 16-bit mode in anticipation of it being used most frequently to write DOS \c{.COM} programs, DOS \c{.SYS} device drivers and boot loader software. @@ -3396,18 +3406,29 @@ You do \e{not} need to specify \c{BITS 32} merely in order to use assembler will generate incorrect code because it will be writing code targeted at a 32-bit platform, to be run on a 16-bit one. -When NASM is in \c{BITS 16} state, instructions which use 32-bit +When NASM is in \c{BITS 16} mode, instructions which use 32-bit data are prefixed with an 0x66 byte, and those referring to 32-bit -addresses have an 0x67 prefix. In \c{BITS 32} state, the reverse is +addresses have an 0x67 prefix. In \c{BITS 32} mode, the reverse is true: 32-bit instructions require no prefixes, whereas instructions using 16-bit data need an 0x66 and those working on 16-bit addresses need an 0x67. +When NASM is in \c{BITS 64} mode, most instructions operate the same +as they do for \c{BITS 32} mode. However, 16-bit addresses are depreciated +in the x86-64 architecture extension and the 0x67 prefix is used for 32-bit +addressing. This is due to the default of 64-bit addressing. When the \c{REX} +prefix is used, the processor does not know how to address the AH, BH, CH or +DH (high 8-bit legacy) registers. This because the x86-64 has added a new +set of registers and the capability to address the low 8-bits of the SP, BP +SI and DI registers as SPL, BPL, SIL and DIL, respectively; but only when +the REX prefix is used. In summary, the \c{REX} prefix causes the addressing +of AH, BH, CH and DH to be replaced by SPL, BPL, SIL and DIL. + The \c{BITS} directive has an exactly equivalent primitive form, -\c{[BITS 16]} and \c{[BITS 32]}. The user-level form is a macro -which has no function other than to call the primitive form. +\c{[BITS 16]}, \c{[BITS 32]} and \c{BITS 64]}. The user-level form is +a macro which has no function other than to call the primitive form. -Note that the space is neccessary, \c{BITS32} will \e{not} work! +Note that the space is neccessary, e.g. \c{BITS32} will \e{not} work! \S{USE16 & USE32} \i\c{USE16} & \i\c{USE32}: Aliases for BITS @@ -3429,9 +3450,9 @@ not (yet) exist. The Unix object formats, and the \c{bin} object format (but see \k{multisec}, all support -the \i{standardised section names} \c{.text}, \c{.data} and \c{.bss} -for the code, data and uninitialised-data sections. The \c{obj} -format, by contrast, does not recognise these section names as being +the \i{standardized section names} \c{.text}, \c{.data} and \c{.bss} +for the code, data and uninitialized-data sections. The \c{obj} +format, by contrast, does not recognize these section names as being special, and indeed will strip off the leading period of any section name that has one. @@ -3607,7 +3628,7 @@ time. The \c{COMMON} directive is used to declare \i\e{common variables}. A common variable is much like a global variable declared in the -uninitialised data section, so that +uninitialized data section, so that \c common intvar 4 @@ -3673,6 +3694,8 @@ Options are: \b\c{CPU PRESCOTT} Prescott instruction set +\b\c{CPU X64} x86-64 (x64/AMD64/EM64T) instruction set + \b\c{CPU IA64} IA64 CPU (in x86 mode) instruction set All options are case insensitive. All instructions will be selected @@ -3710,9 +3733,9 @@ The \c{bin} format supports \i{multiple section names}. For details of how nasm handles sections in the \c{bin} format, see \k{multisec}. Using the \c{bin} format puts NASM by default into 16-bit mode (see -\k{bits}). In order to use \c{bin} to write 32-bit code such as an -OS kernel, you need to explicitly issue the \I\c{BITS}\c{BITS 32} -directive. +\k{bits}). In order to use \c{bin} to write 32-bit or 64-bit code, +such as an OS kernel, you need to explicitly issue the \I\c{BITS}\c{BITS 32} +or \I\c{BITS}\c{BITS 64} directive. \c{bin} has no default output file name extension: instead, it leaves your file name as it is once the original extension has been @@ -3944,7 +3967,7 @@ you can code \c \c segment bss \c -\c ; some uninitialised data +\c ; some uninitialized data \c \c group dgroup data bss @@ -4035,7 +4058,7 @@ resident by the system loader. This is an optimisation for frequently used symbols imported by name. \b \c{nodata} indicates that the exported symbol is a function which -does not make use of any initialised data. +does not make use of any initialized data. \b \c{parm=NNN}, where \c{NNN} is an integer, sets the number of parameter words for the case in which the symbol is a call gate @@ -4185,10 +4208,10 @@ section is code. \b \c{data} and \c{bss} define the section to be a data section, analogously to \c{code}. Data sections are marked as readable and -writable, but not executable. \c{data} declares an initialised data -section, whereas \c{bss} declares an uninitialised data section. +writable, but not executable. \c{data} declares an initialized data +section, whereas \c{bss} declares an uninitialized data section. -\b \c{rdata} declares an initialised data section that is readable +\b \c{rdata} declares an initialized data section that is readable but not writable. Microsoft compilers use this section to place constants in it. @@ -4221,6 +4244,15 @@ qualifiers are: Any other section name is treated by default like \c{.text}. +\H{win64fmt} \i\c{win64}: Microsoft Win64 Object Files + +The \c{win64} output format generates Microsoft Win64 object files, +which is nearly 100% indentical to the \c{win32} object format (\k{win32fmt}) +with the exception that it is meant to target 64-bit code and the x86-64 +platform altogether. This object file is used exactly the same as the \c{win32} +object format (\k{win32fmt}), in NASM, with regard to this exception. + + \H{cofffmt} \i\c{coff}: \i{Common Object File Format} The \c{coff} output type produces \c{COFF} object files suitable for @@ -4312,7 +4344,7 @@ types. \c{elf} defines five special symbols which you can use as the right-hand side of the \c{WRT} operator to obtain PIC relocation types. They are \i\c{..gotpc}, \i\c{..gotoff}, \i\c{..got}, -\i\c{..plt} and \i\c{..sym}. Their functions are summarised here: +\i\c{..plt} and \i\c{..sym}. Their functions are summarized here: \b Referring to the symbol marking the global offset table base using \c{wrt ..gotpc} will end up giving the distance from the @@ -4692,7 +4724,7 @@ the NASM archives, under the name \c{objexe.asm}. \c mov sp,stacktop This initial piece of code sets up \c{DS} to point to the data -segment, and initialises \c{SS} and \c{SP} to point to the top of +segment, and initializes \c{SS} and \c{SP} to point to the top of the provided stack. Notice that interrupts are implicitly disabled for one instruction after a move into \c{SS}, precisely for this situation, so that there's no chance of an interrupt occurring @@ -4728,7 +4760,7 @@ The data segment contains the string we want to display. \c stacktop: The above code declares a stack segment containing 64 bytes of -uninitialised stack space, and points \c{stacktop} at the top of it. +uninitialized stack space, and points \c{stacktop} at the top of it. The directive \c{segment stack stack} defines a segment \e{called} \c{stack}, and also of \e{type} \c{STACK}. The latter is not necessary to the correct running of the program, but linkers are @@ -4816,18 +4848,18 @@ like \c \c section .bss \c -\c ; put uninitialised data here +\c ; put uninitialized data here The \c{bin} format puts the \c{.text} section first in the file, so you can declare data or BSS items before beginning to write code if you want to and the code will still end up at the front of the file where it belongs. -The BSS (uninitialised data) section does not take up space in the +The BSS (uninitialized data) section does not take up space in the \c{.COM} file itself: instead, addresses of BSS items are resolved to point at space beyond the end of the file, on the grounds that this will be free memory when the program is run. Therefore you -should not rely on your BSS being initialised to all zeros when you +should not rely on your BSS being initialized to all zeros when you run. To assemble the above program, you should use a command line like @@ -5133,7 +5165,7 @@ code In large model, the function-call code might look more like this. In this example, it is assumed that \c{DS} already holds the segment -base of the segment \c{_DATA}. If not, you would have to initialise +base of the segment \c{_DATA}. If not, you would have to initialize it first. \c push word [myint] @@ -5191,7 +5223,7 @@ NASM structure definition (using \i\c{STRUC}), or by calculating the one offset and using just that. To do either of these, you should read your C compiler's manual to -find out how it organises data structures. NASM gives no special +find out how it organizes data structures. NASM gives no special alignment to structure members in its own \c{STRUC} macro, so you have to specify alignment yourself if the C compiler generates it. Typically, you might find that a structure like @@ -5413,10 +5445,10 @@ restrictions: \b Procedures and functions must be in a segment whose name is either \c{CODE}, \c{CSEG}, or something ending in \c{_TEXT}. -\b Initialised data must be in a segment whose name is either +\b initialized data must be in a segment whose name is either \c{CONST} or something ending in \c{_DATA}. -\b Uninitialised data must be in a segment whose name is either +\b Uninitialized data must be in a segment whose name is either \c{DATA}, \c{DSEG}, or something ending in \c{_BSS}. \b Any other segments in the object file are completely ignored. @@ -5647,7 +5679,7 @@ NASM structure definition (using \c{STRUC}), or by calculating the one offset and using just that. To do either of these, you should read your C compiler's manual to -find out how it organises data structures. NASM gives no special +find out how it organizes data structures. NASM gives no special alignment to structure members in its own \i\c{STRUC} macro, so you have to specify alignment yourself if the C compiler generates it. Typically, you might find that a structure like @@ -6417,7 +6449,7 @@ the instructions in your code section. Sync points are specified using the \i\c{-s} option: they are measured in terms of the program origin, not the file position. So if you -want to synchronise after 32 bytes of a \c{.COM} file, you would have to +want to synchronize after 32 bytes of a \c{.COM} file, you would have to do \c ndisasm -o100h -s120h file.com @@ -6528,7 +6560,7 @@ This appendix provides a complete list of the machine instructions which NASM will assemble, and a short description of the function of each one. -It is not intended to be exhaustive documentation on the fine +It is not intended to be an exhaustive documentation on the fine details of the instructions' function, such as which exceptions they can trigger: for such documentation, you should go to Intel's Web site, \W{http://developer.intel.com/design/Pentium4/manuals/}\c{http://developer.intel.com/design/Pentium4/manuals/}. @@ -6553,12 +6585,13 @@ The instruction descriptions in this appendix specify their operands using the following notation: \b Registers: \c{reg8} denotes an 8-bit \i{general purpose -register}, \c{reg16} denotes a 16-bit general purpose register, and -\c{reg32} a 32-bit one. \c{fpureg} denotes one of the eight FPU -stack registers, \c{mmxreg} denotes one of the eight 64-bit MMX -registers, and \c{segreg} denotes a segment register. In addition, -some registers (such as \c{AL}, \c{DX} or -\c{ECX}) may be specified explicitly. +register}, \c{reg16} denotes a 16-bit general purpose register, +\c{reg32} a 32-bit one and \c{reg64} a 64-bit one. \c{fpureg} denotes +one of the eight FPU stack registers, \c{mmxreg} denotes one of the +eight 64-bit MMX registers, and \c{segreg} denotes a segment register. +\c{xmmreg} denotes one of the 8, or 16 in x64 long mode, SSE XMM registers. +In addition, some registers (such as \c{AL}, \c{DX}, \c{ECX} or \c{RAX}) +may be specified explicitly. \b Immediate operands: \c{imm} denotes a generic \i{immediate operand}. \c{imm8}, \c{imm16} and \c{imm32} are used when the operand is @@ -6566,7 +6599,8 @@ intended to be a specific size. For some of these instructions, NASM needs an explicit specifier: for example, \c{ADD ESP,16} could be interpreted as either \c{ADD r/m32,imm32} or \c{ADD r/m32,imm8}. NASM chooses the former by default, and so you must specify \c{ADD -ESP,BYTE 16} for the latter. +ESP,BYTE 16} for the latter. There is a special case of the allowance +of an \c{imm64} for particular x64 versions of the MOV instruction. \b Memory references: \c{mem} denotes a generic \i{memory reference}; \c{mem8}, \c{mem16}, \c{mem32}, \c{mem64} and \c{mem80} are used @@ -6578,13 +6612,16 @@ WORD [address]} or \c{DEC DWORD [address]} instead. \b \i{Restricted memory references}: one form of the \c{MOV} instruction allows a memory address to be specified \e{without} allowing the normal range of register combinations and effective -address processing. This is denoted by \c{memoffs8}, \c{memoffs16} -and \c{memoffs32}. +address processing. This is denoted by \c{memoffs8}, \c{memoffs16}, +\c{memoffs32} or \c{memoffs64}. \b Register or memory choices: many instructions can accept either a -register \e{or} a memory reference as an operand. \c{r/m8} is a +register \e{or} a memory reference as an operand. \c{r/m8} is shorthand for \c{reg8/mem8}; similarly \c{r/m16} and \c{r/m32}. -\c{r/m64} is MMX-related, and is a shorthand for \c{mmxreg/mem64}. +On legacy x86 modes, \c{r/m64} is MMX-related, and is shorthand for +\c{mmxreg/mem64}. When utilizing the x86-64 architecture extension, +\c{r/m64} denotes use of a 64-bit GPR as well, and is shorthand for +\c{reg64/mem64}. \H{iref-opc} Key to Opcode Descriptions @@ -6660,7 +6697,8 @@ but generates no code in \c{BITS 16} state; and \c{o32} indicates a \b The codes \c{a16} and \c{a32}, similarly to \c{o16} and \c{o32}, indicate the address size of the given form of the instruction. Where this does not match the \c{BITS} setting, a \c{67} prefix is -required. +required. Please note that \c{a16} is useless in long mode as +16-bit addressing is depreciated on the x86-64 architecture extension. \S{iref-rv} Register Values @@ -6672,19 +6710,43 @@ register, a debug register, an MMX register, or whatever. Therefore there is no problem with registers of different types sharing an encoding value. +Please note that for the register classes listed below, the register +extensions (REX) classes require the use of the REX prefix, in which +is only available when in long mode on the x86-64 processor. This +pretty much goes for any register that has a number higher than 7. + The encodings for the various classes of register are: \b 8-bit general registers: \c{AL} is 0, \c{CL} is 1, \c{DL} is 2, -\c{BL} is 3, \c{AH} is 4, \c{CH} is 5, \c{DH} is 6, and \c{BH} is -7. +\c{BL} is 3, \c{AH} is 4, \c{CH} is 5, \c{DH} is 6 and \c{BH} is +7. Please note that \c{AH}, \c{BH}, \c{CH} and \c{DH} are not +addressable when using the REX prefix in long mode. + +\b 8-bit general register extensions (REX): \c{SPL} is 4, \c{BPL} is 5, +\c{SIL} is 6, \c{DIL} is 7, \c{R8B} is 8, \c{R9B} is 9, \c{R10B} is 10, +\c{R11B} is 11, \c{R12B} is 12, \c{R13B} is 13, \c{R14B} is 14 and +\c{R15B} is 15. \b 16-bit general registers: \c{AX} is 0, \c{CX} is 1, \c{DX} is 2, \c{BX} is 3, \c{SP} is 4, \c{BP} is 5, \c{SI} is 6, and \c{DI} is 7. +\b 16-bit general register extensions (REX): \c{R8W} is 8, \c{R9W} is 9, +\c{R10w} is 10, \c{R11W} is 11, \c{R12W} is 12, \c{R13W} is 13, \c{R14W} +is 14 and \c{R15W} is 15. + \b 32-bit general registers: \c{EAX} is 0, \c{ECX} is 1, \c{EDX} is 2, \c{EBX} is 3, \c{ESP} is 4, \c{EBP} is 5, \c{ESI} is 6, and \c{EDI} is 7. +\b 32-bit general register extensions (REX): \c{R8D} is 8, \c{R9D} is 9, +\c{R10D} is 10, \c{R11D} is 11, \c{R12D} is 12, \c{R13D} is 13, \c{R14D} +is 14 and \c{R15D} is 15. + +\b 64-bit general register extensions (REX): \c{RAX} is 0, \c{RCX} is 1, +\c{RDX} is 2, \c{RBX} is 3, \c{RSP} is 4, \c{RBP} is 5, \c{RSI} is 6, +\c{RDI} is 7, \c{R8} is 8, \c{R9} is 9, \c{R10} is 10, \c{R11} is 11, +\c{R12} is 12, \c{R13} is 13, \c{R14} is 14 and \c{R15} is 15. + \b \i{Segment registers}: \c{ES} is 0, \c{CS} is 1, \c{SS} is 2, \c{DS} is 3, \c{FS} is 4, and \c{GS} is 5. @@ -6696,9 +6758,19 @@ is 0, \c{ST1} is 1, \c{ST2} is 2, \c{ST3} is 3, \c{ST4} is 4, \c{MM3} is 3, \c{MM4} is 4, \c{MM5} is 5, \c{MM6} is 6, and \c{MM7} is 7. +\b 128-bit \i{XMM (SSE) registers}: \c{XMM0} is 0, \c{XMM1} is 1, +\c{XMM2} is 2, \c{XMM3} is 3, \c{XMM4} is 4, \c{XMM5} is 5, \c{XMM6} is +6 and \c{XMM7} is 7. + +\b 128-bit \i{XMM (SSE) register} extensions (REX): \c{XMM8} is 8, +\c{XMM9} is 9, \c{XMM10} is 10, \c{XMM11} is 11, \c{XMM12} is 12, +\c{XMM13} is 13, \c{XMM14} is 14 and \c{XMM15} is 15. + \b \i{Control registers}: \c{CR0} is 0, \c{CR2} is 2, \c{CR3} is 3, and \c{CR4} is 4. +\b \i{Control register} extensions: \c{CR8} is 8. + \b \i{Debug registers}: \c{DR0} is 0, \c{DR1} is 1, \c{DR2} is 2, \c{DR3} is 3, \c{DR6} is 6, and \c{DR7} is 7. @@ -6947,13 +7019,67 @@ is not \c{[EBP]} as the above rules would suggest, but instead long, and no registers are added to the displacement. \b If \c{mod} is 0, \c{r/m} is 4 (meaning the SIB byte is present) -and \c{base} is 4, the effective address encoded is not +and \c{base} is 5, the effective address encoded is not \c{[EBP+index]} as the above rules would suggest, but instead \c{[disp32+index]}: the displacement field is present and is four bytes long, and there is no base register (but the index register is still processed in the normal way). +\S{iref-rex} Register Extensions: The \i{REX} Prefix + +The Register Extensions, or \i{REX} for short, prefix is the means +of accessing extended registers on the x86-64 architecture. \i{REX} +is considered an instruction prefix, but is required to be after +all other prefixes and thus immediately before the first instruction +opcode itself. So overall, \i{REX} can be thought of as an "Opcode +Prefix" instead. The \i{REX} prefix itself is indicated by a value +of 0x4X, where X is one of 16 different combinations of the actual +\i{REX} flags. + +The \i{REX} prefix flags consist of four 1-bit extensions fields. +These flags are found in the lower nibble of the actual \i{REX} +prefix opcode. Below is the list of \i{REX} prefix flags, from +high bit to low bit. + +\c{REX.W}: When set, this flag indicates the use of a 64-bit operand, +as opposed to the default of using 32-bit operands as found in 32-bit +Protected Mode. + +\c{REX.R}: When set, this flag extends the \c{reg (spare)} field of +the \c{ModRM} byte. Overall, this raises the amount of addressable +registers in this field from 8 to 16. + +\c{REX.X}: When set, this flag extends the \c{index} field of the +\c{SIB} byte. Overall, this raises the amount of addressable +registers in this field from 8 to 16. + +\c{REX.B}: When set, this flag extends the \c{r/m} field of the +\c{ModRM} byte. This flag can also represent an extension to the +opcode register \c{(/r)} field. The determination of which is used +varies depending on which instruction is used. Overall, this raises +the amount of addressable registers in these fields from 8 to 16. + +Interal use of the \i{REX} prefix by the processor is consistent, +yet non-trivial. Most instructions use the \i{REX} prefix as +indicated by the above flags. Some instructions require the \i{REX} +prefix to be present even if the flags are empty. Some instructions +default to a 64-bit operand and require the \i{REX} prefix only for +actual register extensions, and thus ignores the \c{REX.W} field +completely. + +At any rate, NASM is designed to handle, and fully supports, the +\i{REX} prefix internally. Please read the appropriate processor +documentation for further information on the \i{REX} prefix. + +You may have noticed that opcodes 0x40 through 0x4F are actually +opcodes for the INC/DEC instructions for each General Purpose +Register. This is, of course, correct... for legacy x86. While +in long mode, opcodes 0x40 through 0x4F are reserved for use as +the REX prefix. The other opcode forms of the INC/DEC instructions +are used instead. + + \H{iref-flg} Key to Instruction Flags Given along with each instruction in this appendix is a set of @@ -7004,6 +7130,10 @@ be supported on any given machine. part of the new instruction set in the Pentium 4 and Intel Xeon processors. These instructions are also known as SSE2 instructions. +\b \c{X64} indicates that the instruction was introduced as part of +the new instruction set in the x86-64 architecture extension, +commonly referred to as x64, AMD64 or EM64T. + \H{iref-inst} x86 Instruction Set @@ -7882,7 +8012,7 @@ being executed on. It fills the four registers \c{EAX}, \c{EBX}, \c{ECX} and \c{EDX} with information, which varies depending on the input contents of \c{EAX}. -\c{CPUID} also acts as a barrier to serialise instruction execution: +\c{CPUID} also acts as a barrier to serialize instruction execution: executing the \c{CPUID} instruction guarantees that all the effects (memory modification, flag modification, register modification) of previous instructions have been completed before the next @@ -8785,12 +8915,12 @@ flag the new \c{ST7} (previously \c{ST0}) as empty. See also \c{FDECSTP} (\k{insFDECSTP}). -\S{insFINIT} \i\c{FINIT}, \i\c{FNINIT}: Initialise Floating-Point Unit +\S{insFINIT} \i\c{FINIT}, \i\c{FNINIT}: initialize Floating-Point Unit \c FINIT ; 9B DB E3 [8086,FPU] \c FNINIT ; DB E3 [8086,FPU] -\c{FINIT} initialises the FPU to its default state. It flags all +\c{FINIT} initializes the FPU to its default state. It flags all registers as empty, without actually change their values, clears the top of stack pointer. \c{FNINIT} does the same, without first waiting for pending exceptions to clear. @@ -8980,7 +9110,7 @@ the power of that integer, and stores the result in \c{ST0}. \c FSETPM ; DB E4 [286,FPU] -This instruction initialises protected mode on the 287 floating-point +This instruction initializes protected mode on the 287 floating-point coprocessor. It is only meaningful on that processor: the 387 and above treat the instruction as a no-operation. @@ -9210,7 +9340,7 @@ without checking for pending unmasked floating-point exceptions Unlike the \c{FSAVE/FNSAVE} instructions, the processor retains the contents of the \c{FPU}, \c{MMX} and \c{SSE} state in the processor -after the state has been saved. This instruction has been optimised +after the state has been saved. This instruction has been optimized to maximize floating-point save performance. @@ -9571,8 +9701,8 @@ As a convenience, NASM does not require you to jump to a far symbol by coding the cumbersome \c{JMP SEG routine:routine}, but instead allows the easier synonym \c{JMP FAR routine}. -The \c{CALL r/m} forms given above are near calls; NASM will accept -the \c{NEAR} keyword (e.g. \c{CALL NEAR [address]}), even though it +The \c{JMP r/m} forms given above are near calls; NASM will accept +the \c{NEAR} keyword (e.g. \c{JMP NEAR [address]}), even though it is not strictly necessary. @@ -9715,7 +9845,7 @@ See also \c{SFENCE} (\k{insSFENCE}) and \c{MFENCE} (\k{insMFENCE}). \c LLDT r/m16 ; 0F 00 /2 [286,PRIV] \c{LGDT} and \c{LIDT} both take a 6-byte memory area as an operand: -they load a 32-bit linear address and a 16-bit size limit from that +they load a 16-bit size limit and a 32-bit linear address from that area (in the opposite order) into the \c{GDTR} (global descriptor table register) or \c{IDTR} (interrupt descriptor table register). These are the only instructions which directly use \e{linear} addresses, rather @@ -13,6 +13,7 @@ #include <stddef.h> #include <string.h> #include <ctype.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" @@ -46,8 +47,8 @@ static int *opflags; static struct eval_hints *hint; extern int in_abs_seg; /* ABSOLUTE segment flag */ -extern long abs_seg; /* ABSOLUTE segment */ -extern long abs_offset; /* ABSOLUTE segment offset */ +extern int32_t abs_seg; /* ABSOLUTE segment */ +extern int32_t abs_offset; /* ABSOLUTE segment offset */ /* * Unimportant cleanup is done to avoid confusing people who are trying @@ -69,7 +70,7 @@ static void begintemp(void) tempexpr_size = ntempexpr = 0; } -static void addtotemp(long type, long value) +static void addtotemp(int32_t type, int64_t value) { while (ntempexpr >= tempexpr_size) { tempexpr_size += TEMPEXPR_DELTA; @@ -116,7 +117,7 @@ static expr *add_vectors(expr * p, expr * q) addtotemp(p->type, p->value); lasttype = p++->type; } else { /* *p and *q have same type */ - long sum = p->value + q->value; + int32_t sum = p->value + q->value; if (sum) addtotemp(p->type, sum); lasttype = p->type; @@ -150,7 +151,7 @@ static expr *add_vectors(expr * p, expr * q) * multiplied. This allows [eax*1+ebx] to hint EBX rather than EAX * as the base register. */ -static expr *scalar_mult(expr * vect, long scalar, int affect_hints) +static expr *scalar_mult(expr * vect, int32_t scalar, int affect_hints) { expr *p = vect; @@ -166,7 +167,7 @@ static expr *scalar_mult(expr * vect, long scalar, int affect_hints) return vect; } -static expr *scalarvect(long scalar) +static expr *scalarvect(int32_t scalar) { begintemp(); addtotemp(EXPR_SIMPLE, scalar); @@ -187,7 +188,7 @@ static expr *unknown_expr(void) */ static expr *segment_part(expr * e) { - long seg; + int32_t seg; if (is_unknown(e)) return unknown_expr(); @@ -208,7 +209,7 @@ static expr *segment_part(expr * e) " is already a segment base"); return NULL; } else { - long base = outfmt->segbase(seg + 1); + int32_t base = outfmt->segbase(seg + 1); begintemp(); addtotemp((base == NO_SEG ? EXPR_UNKNOWN : EXPR_SEGBASE + base), @@ -279,7 +280,7 @@ static expr *rexp0(int critical) if (is_just_unknown(e) || is_just_unknown(f)) e = unknown_expr(); else - e = scalarvect((long)(reloc_value(e) || reloc_value(f))); + e = scalarvect((int32_t)(reloc_value(e) || reloc_value(f))); } return e; } @@ -306,7 +307,7 @@ static expr *rexp1(int critical) if (is_just_unknown(e) || is_just_unknown(f)) e = unknown_expr(); else - e = scalarvect((long)(!reloc_value(e) ^ !reloc_value(f))); + e = scalarvect((int32_t)(!reloc_value(e) ^ !reloc_value(f))); } return e; } @@ -331,7 +332,7 @@ static expr *rexp2(int critical) if (is_just_unknown(e) || is_just_unknown(f)) e = unknown_expr(); else - e = scalarvect((long)(reloc_value(e) && reloc_value(f))); + e = scalarvect((int32_t)(reloc_value(e) && reloc_value(f))); } return e; } @@ -339,7 +340,7 @@ static expr *rexp2(int critical) static expr *rexp3(int critical) { expr *e, *f; - long v; + int32_t v; e = expr0(critical); if (!e) @@ -498,7 +499,7 @@ static expr *expr3(int critical) e = scalarvect(reloc_value(e) << reloc_value(f)); break; case TOKEN_SHR: - e = scalarvect(((unsigned long)reloc_value(e)) >> + e = scalarvect(((uint32_t)reloc_value(e)) >> reloc_value(f)); break; } @@ -573,29 +574,29 @@ static expr *expr5(int critical) if (is_just_unknown(e) || is_just_unknown(f)) e = unknown_expr(); else - e = scalarvect(((unsigned long)reloc_value(e)) / - ((unsigned long)reloc_value(f))); + e = scalarvect(((uint32_t)reloc_value(e)) / + ((uint32_t)reloc_value(f))); break; case '%': if (is_just_unknown(e) || is_just_unknown(f)) e = unknown_expr(); else - e = scalarvect(((unsigned long)reloc_value(e)) % - ((unsigned long)reloc_value(f))); + e = scalarvect(((uint32_t)reloc_value(e)) % + ((uint32_t)reloc_value(f))); break; case TOKEN_SDIV: if (is_just_unknown(e) || is_just_unknown(f)) e = unknown_expr(); else - e = scalarvect(((signed long)reloc_value(e)) / - ((signed long)reloc_value(f))); + e = scalarvect(((int32_t)reloc_value(e)) / + ((int32_t)reloc_value(f))); break; case TOKEN_SMOD: if (is_just_unknown(e) || is_just_unknown(f)) e = unknown_expr(); else - e = scalarvect(((signed long)reloc_value(e)) % - ((signed long)reloc_value(f))); + e = scalarvect(((int32_t)reloc_value(e)) % + ((int32_t)reloc_value(f))); break; } } @@ -604,9 +605,9 @@ static expr *expr5(int critical) static expr *expr6(int critical) { - long type; + int32_t type; expr *e; - long label_seg, label_ofs; + int32_t label_seg, label_ofs; if (i == '-') { i = scan(scpriv, tokval); @@ -761,7 +762,7 @@ expr *evaluate(scanner sc, void *scprivate, struct tokenval *tv, else i = tokval->t_type; - while (ntempexprs) /* initialise temporary storage */ + while (ntempexprs) /* initialize temporary storage */ nasm_free(tempexprs[--ntempexprs]); e = bexpr(critical); @@ -780,7 +781,7 @@ expr *evaluate(scanner sc, void *scprivate, struct tokenval *tv, if (is_just_unknown(f)) g = unknown_expr(); else { - long value; + int64_t value; begintemp(); if (!is_reloc(f)) { error(ERR_NONFATAL, "invalid right-hand operand to WRT"); @@ -11,6 +11,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <inttypes.h> #include "nasm.h" @@ -25,9 +26,9 @@ * => we only have to worry about _one_ bit shift to the left */ -static int ieee_multiply(unsigned short *to, unsigned short *from) +static int ieee_multiply(uint16_t *to, uint16_t *from) { - unsigned long temp[MANT_WORDS * 2]; + uint32_t temp[MANT_WORDS * 2]; int i, j; for (i = 0; i < MANT_WORDS * 2; i++) @@ -35,8 +36,8 @@ static int ieee_multiply(unsigned short *to, unsigned short *from) for (i = 0; i < MANT_WORDS; i++) for (j = 0; j < MANT_WORDS; j++) { - unsigned long n; - n = (unsigned long)to[i] * (unsigned long)from[j]; + uint32_t n; + n = (uint32_t)to[i] * (uint32_t)from[j]; temp[i + j] += n >> 16; temp[i + j + 1] += n & 0xFFFF; } @@ -56,14 +57,14 @@ static int ieee_multiply(unsigned short *to, unsigned short *from) } } -static void ieee_flconvert(char *string, unsigned short *mant, - long *exponent, efunc error) +static void ieee_flconvert(int8_t *string, uint16_t *mant, + int32_t *exponent, efunc error) { - char digits[MANT_DIGITS]; - char *p, *q, *r; - unsigned short mult[MANT_WORDS], bit; - unsigned short *m; - long tenpwr, twopwr; + int8_t digits[MANT_DIGITS]; + int8_t *p, *q, *r; + uint16_t mult[MANT_WORDS], bit; + uint16_t *m; + int32_t tenpwr, twopwr; int extratwos, started, seendot; p = digits; @@ -118,7 +119,7 @@ static void ieee_flconvert(char *string, unsigned short *mant, started = FALSE; twopwr = 0; while (m < mant + MANT_WORDS) { - unsigned short carry = 0; + uint16_t carry = 0; while (p > q && !p[-1]) p--; if (p <= q) @@ -183,9 +184,9 @@ static void ieee_flconvert(char *string, unsigned short *mant, /* * Shift a mantissa to the right by i (i < 16) bits. */ -static void ieee_shr(unsigned short *mant, int i) +static void ieee_shr(uint16_t *mant, int i) { - unsigned short n = 0, m; + uint16_t n = 0, m; int j; for (j = 0; j < MANT_WORDS; j++) { @@ -198,7 +199,7 @@ static void ieee_shr(unsigned short *mant, int i) /* * Round a mantissa off after i words. */ -static int ieee_round(unsigned short *mant, int i) +static int ieee_round(uint16_t *mant, int i) { if (mant[i] & 0x8000) { do { @@ -212,11 +213,11 @@ static int ieee_round(unsigned short *mant, int i) #define put(a,b) ( (*(a)=(b)), ((a)[1]=(b)>>8) ) -static int to_double(char *str, long sign, unsigned char *result, +static int to_double(int8_t *str, int32_t sign, uint8_t *result, efunc error) { - unsigned short mant[MANT_WORDS]; - long exponent; + uint16_t mant[MANT_WORDS]; + int32_t exponent; sign = (sign < 0 ? 0x8000L : 0L); @@ -274,11 +275,11 @@ static int to_double(char *str, long sign, unsigned char *result, return 1; /* success */ } -static int to_float(char *str, long sign, unsigned char *result, +static int to_float(int8_t *str, int32_t sign, uint8_t *result, efunc error) { - unsigned short mant[MANT_WORDS]; - long exponent; + uint16_t mant[MANT_WORDS]; + int32_t exponent; sign = (sign < 0 ? 0x8000L : 0L); @@ -329,11 +330,11 @@ static int to_float(char *str, long sign, unsigned char *result, return 1; } -static int to_ldoub(char *str, long sign, unsigned char *result, +static int to_ldoub(int8_t *str, int32_t sign, uint8_t *result, efunc error) { - unsigned short mant[MANT_WORDS]; - long exponent; + uint16_t mant[MANT_WORDS]; + int32_t exponent; sign = (sign < 0 ? 0x8000L : 0L); @@ -390,7 +391,7 @@ static int to_ldoub(char *str, long sign, unsigned char *result, return 1; } -int float_const(char *number, long sign, unsigned char *result, int bytes, +int float_const(int8_t *number, int32_t sign, uint8_t *result, int bytes, efunc error) { if (bytes == 4) @@ -10,7 +10,7 @@ #ifndef NASM_FLOAT_H #define NASM_FLOAT_H -int float_const(char *number, long sign, unsigned char *result, int bytes, +int float_const(int8_t *number, int32_t sign, uint8_t *result, int bytes, efunc error); #endif @@ -15,34 +15,42 @@ ; see the comment at the top of assemble.c. For a detailed description ; of the flags (fourth field), please see insns.h. ; -AAA void \1\x37 8086 -AAD void \2\xD5\x0A 8086 -AAD imm \1\xD5\24 8086,SB -AAM void \2\xD4\x0A 8086 -AAM imm \1\xD4\24 8086,SB -AAS void \1\x3F 8086 +AAA void \1\x37 8086,NOLONG +AAD void \2\xD5\x0A 8086,NOLONG +AAD imm \1\xD5\24 8086,SB,NOLONG +AAM void \2\xD4\x0A 8086,NOLONG +AAM imm \1\xD4\24 8086,SB,NOLONG +AAS void \1\x3F 8086,NOLONG ADC mem,reg8 \300\1\x10\101 8086,SM ADC reg8,reg8 \1\x10\101 8086 ADC mem,reg16 \320\300\1\x11\101 8086,SM ADC reg16,reg16 \320\1\x11\101 8086 ADC mem,reg32 \321\300\1\x11\101 386,SM ADC reg32,reg32 \321\1\x11\101 386 +ADC mem,reg64 \321\300\1\x11\101 X64,SM +ADC reg64,reg64 \321\1\x11\101 X64 ADC reg8,mem \301\1\x12\110 8086,SM ADC reg8,reg8 \1\x12\110 8086 ADC reg16,mem \320\301\1\x13\110 8086,SM ADC reg16,reg16 \320\1\x13\110 8086 ADC reg32,mem \321\301\1\x13\110 386,SM ADC reg32,reg32 \321\1\x13\110 386 +ADC reg64,mem \321\301\1\x13\110 X64,SM +ADC reg64,reg64 \321\1\x13\110 X64 ADC rm16,imm8 \320\300\1\x83\202\15 8086 ADC rm32,imm8 \321\300\1\x83\202\15 386 +ADC rm64,imm8 \321\300\1\x83\202\15 X64 ADC reg_al,imm \1\x14\21 8086,SM ADC reg_ax,sbyte \320\1\x83\202\15 8086,SM,ND ADC reg_ax,imm \320\1\x15\31 8086,SM ADC reg_eax,sbyte \321\1\x83\202\15 386,SM,ND ADC reg_eax,imm \321\1\x15\41 386,SM +ADC reg_rax,sbyte \321\1\x83\202\15 X64,SM,ND +ADC reg_rax,imm \321\1\x15\41 X64,SM ADC rm8,imm \300\1\x80\202\21 8086,SM ADC rm16,imm \320\300\134\1\x81\202\131 8086,SM ADC rm32,imm \321\300\144\1\x81\202\141 386,SM +ADC rm64,imm \321\300\144\1\x81\202\141 X64,SM ADC mem,imm8 \300\1\x80\202\21 8086,SM ADC mem,imm16 \320\300\134\1\x81\202\131 8086,SM ADC mem,imm32 \321\300\144\1\x81\202\141 386,SM @@ -52,22 +60,30 @@ ADD mem,reg16 \320\300\1\x01\101 8086,SM ADD reg16,reg16 \320\1\x01\101 8086 ADD mem,reg32 \321\300\1\x01\101 386,SM ADD reg32,reg32 \321\1\x01\101 386 +ADD mem,reg64 \321\300\1\x01\101 X64,SM +ADD reg64,reg64 \321\1\x01\101 X64 ADD reg8,mem \301\1\x02\110 8086,SM ADD reg8,reg8 \1\x02\110 8086 ADD reg16,mem \320\301\1\x03\110 8086,SM ADD reg16,reg16 \320\1\x03\110 8086 ADD reg32,mem \321\301\1\x03\110 386,SM ADD reg32,reg32 \321\1\x03\110 386 +ADD reg64,mem \321\301\1\x03\110 X64,SM +ADD reg64,reg64 \321\1\x03\110 X64 ADD rm16,imm8 \320\300\1\x83\200\15 8086 ADD rm32,imm8 \321\300\1\x83\200\15 386 +ADD rm64,imm8 \321\300\1\x83\200\15 X64 ADD reg_al,imm \1\x04\21 8086,SM ADD reg_ax,sbyte \320\1\x83\200\15 8086,SM,ND ADD reg_ax,imm \320\1\x05\31 8086,SM ADD reg_eax,sbyte \321\1\x83\200\15 386,SM,ND ADD reg_eax,imm \321\1\x05\41 386,SM +ADD reg_rax,sbyte \321\1\x83\200\15 X64,SM,ND +ADD reg_rax,imm \323\1\x05\41 X64,SM ADD rm8,imm \300\1\x80\200\21 8086,SM ADD rm16,imm \320\300\134\1\x81\200\131 8086,SM ADD rm32,imm \321\300\144\1\x81\200\141 386,SM +ADD rm64,imm \321\300\144\1\x81\200\141 X64,SM ADD mem,imm8 \300\1\x80\200\21 8086,SM ADD mem,imm16 \320\300\134\1\x81\200\131 8086,SM ADD mem,imm32 \321\300\144\1\x81\200\141 386,SM @@ -77,91 +93,122 @@ AND mem,reg16 \320\300\1\x21\101 8086,SM AND reg16,reg16 \320\1\x21\101 8086 AND mem,reg32 \321\300\1\x21\101 386,SM AND reg32,reg32 \321\1\x21\101 386 +AND mem,reg64 \321\300\1\x21\101 X64,SM +AND reg64,reg64 \321\1\x21\101 X64 AND reg8,mem \301\1\x22\110 8086,SM AND reg8,reg8 \1\x22\110 8086 AND reg16,mem \320\301\1\x23\110 8086,SM AND reg16,reg16 \320\1\x23\110 8086 AND reg32,mem \321\301\1\x23\110 386,SM AND reg32,reg32 \321\1\x23\110 386 +AND reg64,mem \321\301\1\x23\110 X64,SM +AND reg64,reg64 \321\1\x23\110 X64 AND rm16,imm8 \320\300\1\x83\204\15 8086 AND rm32,imm8 \321\300\1\x83\204\15 386 +AND rm64,imm8 \321\300\1\x83\204\15 X64 AND reg_al,imm \1\x24\21 8086,SM AND reg_ax,sbyte \320\1\x83\204\15 8086,SM,ND AND reg_ax,imm \320\1\x25\31 8086,SM AND reg_eax,sbyte \321\1\x83\204\15 386,SM,ND AND reg_eax,imm \321\1\x25\41 386,SM +AND reg_rax,sbyte \321\1\x83\204\15 X64,SM,ND +AND reg_rax,imm \324\1\x25\41 X64,SM AND rm8,imm \300\1\x80\204\21 8086,SM AND rm16,imm \320\300\134\1\x81\204\131 8086,SM AND rm32,imm \321\300\144\1\x81\204\141 386,SM +AND rm64,imm \321\300\144\1\x81\204\141 X64,SM AND mem,imm8 \300\1\x80\204\21 8086,SM AND mem,imm16 \320\300\134\1\x81\204\131 8086,SM AND mem,imm32 \321\300\144\1\x81\204\141 386,SM -ARPL mem,reg16 \300\1\x63\101 286,PROT,SM -ARPL reg16,reg16 \1\x63\101 286,PROT -BOUND reg16,mem \320\301\1\x62\110 186 -BOUND reg32,mem \321\301\1\x62\110 386 +ARPL mem,reg16 \300\1\x63\101 286,PROT,SM,NOLONG +ARPL reg16,reg16 \1\x63\101 286,PROT,NOLONG +BOUND reg16,mem \320\301\1\x62\110 186,NOLONG +BOUND reg32,mem \321\301\1\x62\110 386,NOLONG BSF reg16,mem \320\301\2\x0F\xBC\110 386,SM BSF reg16,reg16 \320\2\x0F\xBC\110 386 BSF reg32,mem \321\301\2\x0F\xBC\110 386,SM BSF reg32,reg32 \321\2\x0F\xBC\110 386 +BSF reg64,mem \321\301\2\x0F\xBC\110 X64,SM +BSF reg64,reg64 \321\2\x0F\xBC\110 X64 BSR reg16,mem \320\301\2\x0F\xBD\110 386,SM BSR reg16,reg16 \320\2\x0F\xBD\110 386 BSR reg32,mem \321\301\2\x0F\xBD\110 386,SM BSR reg32,reg32 \321\2\x0F\xBD\110 386 +BSR reg64,mem \321\301\2\x0F\xBD\110 X64,SM +BSR reg64,reg64 \321\2\x0F\xBD\110 X64 BSWAP reg32 \321\1\x0F\10\xC8 486 +BSWAP reg64 \321\1\x0F\10\xC8 X64 BT mem,reg16 \320\300\2\x0F\xA3\101 386,SM BT reg16,reg16 \320\2\x0F\xA3\101 386 BT mem,reg32 \321\300\2\x0F\xA3\101 386,SM BT reg32,reg32 \321\2\x0F\xA3\101 386 +BT mem,reg64 \321\300\2\x0F\xA3\101 X64,SM +BT reg64,reg64 \321\2\x0F\xA3\101 X64 BT rm16,imm \320\300\2\x0F\xBA\204\25 386,SB BT rm32,imm \321\300\2\x0F\xBA\204\25 386,SB +BT rm64,imm \321\300\2\x0F\xBA\204\25 X64,SB BTC mem,reg16 \320\300\2\x0F\xBB\101 386,SM BTC reg16,reg16 \320\2\x0F\xBB\101 386 BTC mem,reg32 \321\300\2\x0F\xBB\101 386,SM BTC reg32,reg32 \321\2\x0F\xBB\101 386 +BTC mem,reg64 \321\300\2\x0F\xBB\101 X64,SM +BTC reg64,reg64 \321\2\x0F\xBB\101 X64 BTC rm16,imm \320\300\2\x0F\xBA\207\25 386,SB BTC rm32,imm \321\300\2\x0F\xBA\207\25 386,SB +BTC rm64,imm \321\300\2\x0F\xBA\207\25 X64,SB BTR mem,reg16 \320\300\2\x0F\xB3\101 386,SM BTR reg16,reg16 \320\2\x0F\xB3\101 386 BTR mem,reg32 \321\300\2\x0F\xB3\101 386,SM BTR reg32,reg32 \321\2\x0F\xB3\101 386 +BTR mem,reg64 \321\300\2\x0F\xB3\101 X64,SM +BTR reg64,reg64 \321\2\x0F\xB3\101 X64 BTR rm16,imm \320\300\2\x0F\xBA\206\25 386,SB BTR rm32,imm \321\300\2\x0F\xBA\206\25 386,SB +BTR rm64,imm \321\300\2\x0F\xBA\206\25 X64,SB BTS mem,reg16 \320\300\2\x0F\xAB\101 386,SM BTS reg16,reg16 \320\2\x0F\xAB\101 386 BTS mem,reg32 \321\300\2\x0F\xAB\101 386,SM BTS reg32,reg32 \321\2\x0F\xAB\101 386 +BTS mem,reg64 \321\300\2\x0F\xAB\101 X64,SM +BTS reg64,reg64 \321\2\x0F\xAB\101 X64 BTS rm16,imm \320\300\2\x0F\xBA\205\25 386,SB BTS rm32,imm \321\300\2\x0F\xBA\205\25 386,SB +BTS rm64,imm \321\300\2\x0F\xBA\205\25 X64,SB CALL imm \322\1\xE8\64 8086 CALL imm|near \322\1\xE8\64 8086 -CALL imm|far \322\1\x9A\34\37 8086,ND +CALL imm|far \322\1\x9A\34\37 8086,ND,NOLONG CALL imm16 \320\1\xE8\64 8086 CALL imm16|near \320\1\xE8\64 8086 -CALL imm16|far \320\1\x9A\34\37 8086,ND +CALL imm16|far \320\1\x9A\34\37 8086,ND,NOLONG CALL imm32 \321\1\xE8\64 386 CALL imm32|near \321\1\xE8\64 386 -CALL imm32|far \321\1\x9A\34\37 386,ND -CALL imm:imm \322\1\x9A\35\30 8086 -CALL imm16:imm \320\1\x9A\31\30 8086 -CALL imm:imm16 \320\1\x9A\31\30 8086 -CALL imm32:imm \321\1\x9A\41\30 386 -CALL imm:imm32 \321\1\x9A\41\30 386 +CALL imm32|far \321\1\x9A\34\37 386,ND,NOLONG +CALL imm:imm \322\1\x9A\35\30 8086,NOLONG +CALL imm16:imm \320\1\x9A\31\30 8086,NOLONG +CALL imm:imm16 \320\1\x9A\31\30 8086,NOLONG +CALL imm32:imm \321\1\x9A\41\30 386,NOLONG +CALL imm:imm32 \321\1\x9A\41\30 386,NOLONG CALL mem|far \322\300\1\xFF\203 8086 CALL mem16|far \320\300\1\xFF\203 8086 CALL mem32|far \321\300\1\xFF\203 386 CALL mem|near \322\300\1\xFF\202 8086 CALL mem16|near \320\300\1\xFF\202 8086 -CALL mem32|near \321\300\1\xFF\202 386 +CALL mem32|near \321\300\1\xFF\202 386,NOLONG +CALL mem64|near \321\300\1\xFF\202 X64 CALL reg16 \320\300\1\xFF\202 8086 -CALL reg32 \321\300\1\xFF\202 386 +CALL reg32 \321\300\1\xFF\202 386,NOLONG +CALL reg64 \321\300\1\xFF\202 X64 CALL mem \322\300\1\xFF\202 8086 CALL mem16 \320\300\1\xFF\202 8086 -CALL mem32 \321\300\1\xFF\202 386 +CALL mem32 \321\300\1\xFF\202 386,NOLONG +CALL mem64 \321\300\1\xFF\202 X64 CBW void \320\1\x98 8086 CDQ void \321\1\x99 386 +CDQE void \324\1\x98 X64 CLC void \1\xF8 8086 CLD void \1\xFC 8086 +CLFLUSH mem8 \300\2\x0F\x80\207 X64,AMD,SM +CLGI void \3\x0F\x01\xDD X64,AMD CLI void \1\xFA 8086 CLTS void \2\x0F\x06 286,PRIV CMC void \1\xF5 8086 @@ -171,27 +218,36 @@ CMP mem,reg16 \320\300\1\x39\101 8086,SM CMP reg16,reg16 \320\1\x39\101 8086 CMP mem,reg32 \321\300\1\x39\101 386,SM CMP reg32,reg32 \321\1\x39\101 386 +CMP mem,reg64 \321\300\1\x39\101 X64,SM +CMP reg64,reg64 \321\1\x39\101 X64 CMP reg8,mem \301\1\x3A\110 8086,SM CMP reg8,reg8 \1\x3A\110 8086 CMP reg16,mem \320\301\1\x3B\110 8086,SM CMP reg16,reg16 \320\1\x3B\110 8086 CMP reg32,mem \321\301\1\x3B\110 386,SM CMP reg32,reg32 \321\1\x3B\110 386 +CMP reg64,mem \321\301\1\x3B\110 X64,SM +CMP reg64,reg64 \321\1\x3B\110 X64 CMP rm16,imm8 \320\300\1\x83\207\15 8086 CMP rm32,imm8 \321\300\1\x83\207\15 386 +CMP rm64,imm8 \321\300\1\x83\207\15 X64 CMP reg_al,imm \1\x3C\21 8086,SM CMP reg_ax,sbyte \320\1\x83\207\15 8086,SM,ND CMP reg_ax,imm \320\1\x3D\31 8086,SM CMP reg_eax,sbyte \321\1\x83\207\15 386,SM,ND CMP reg_eax,imm \321\1\x3D\41 386,SM +CMP reg_rax,sbyte \321\1\x83\207\15 X64,SM,ND +CMP reg_rax,imm \321\1\x3D\41 X64,SM CMP rm8,imm \300\1\x80\207\21 8086,SM CMP rm16,imm \320\300\134\1\x81\207\131 8086,SM CMP rm32,imm \321\300\144\1\x81\207\141 386,SM +CMP rm64,imm \321\300\144\1\x81\207\141 X64,SM CMP mem,imm8 \300\1\x80\207\21 8086,SM CMP mem,imm16 \320\300\134\1\x81\207\131 8086,SM CMP mem,imm32 \321\300\144\1\x81\207\141 386,SM CMPSB void \332\1\xA6 8086 CMPSD void \332\321\1\xA7 386 +CMPSQ void \332\324\1\xA7 X64 CMPSW void \332\320\1\xA7 8086 CMPXCHG mem,reg8 \300\2\x0F\xB0\101 PENT,SM CMPXCHG reg8,reg8 \2\x0F\xB0\101 PENT @@ -199,6 +255,8 @@ CMPXCHG mem,reg16 \320\300\2\x0F\xB1\101 PENT,SM CMPXCHG reg16,reg16 \320\2\x0F\xB1\101 PENT CMPXCHG mem,reg32 \321\300\2\x0F\xB1\101 PENT,SM CMPXCHG reg32,reg32 \321\2\x0F\xB1\101 PENT +CMPXCHG mem,reg64 \321\300\2\x0F\xB1\101 X64,SM +CMPXCHG reg64,reg64 \321\2\x0F\xB1\101 X64 CMPXCHG486 mem,reg8 \300\2\x0F\xA6\101 486,SM,UNDOC CMPXCHG486 reg8,reg8 \2\x0F\xA6\101 486,UNDOC CMPXCHG486 mem,reg16 \320\300\2\x0F\xA7\101 486,SM,UNDOC @@ -206,21 +264,25 @@ CMPXCHG486 reg16,reg16 \320\2\x0F\xA7\101 486,UNDOC CMPXCHG486 mem,reg32 \321\300\2\x0F\xA7\101 486,SM,UNDOC CMPXCHG486 reg32,reg32 \321\2\x0F\xA7\101 486,UNDOC CMPXCHG8B mem \300\2\x0F\xC7\201 PENT +CMPXCHG16B mem \324\300\2\x0F\xC7\201 X64 CPUID void \2\x0F\xA2 PENT +CQO void \324\1\x99 X64 CWD void \320\1\x99 8086 CWDE void \321\1\x98 386 -DAA void \1\x27 8086 -DAS void \1\x2F 8086 +DAA void \1\x27 8086,NOLONG +DAS void \1\x2F 8086,NOLONG DB ignore ignore ignore DD ignore ignore ignore -DEC reg16 \320\10\x48 8086 -DEC reg32 \321\10\x48 386 +DEC reg16 \320\10\x48 8086,NOLONG +DEC reg32 \321\10\x48 386,NOLONG DEC rm8 \300\1\xFE\201 8086 DEC rm16 \320\300\1\xFF\201 8086 DEC rm32 \321\300\1\xFF\201 386 +DEC rm64 \321\300\1\xFF\201 X64 DIV rm8 \300\1\xF6\206 8086 DIV rm16 \320\300\1\xF7\206 8086 DIV rm32 \321\300\1\xF7\206 386 +DIV rm64 \321\300\1\xF7\206 X64 DQ ignore ignore ignore DT ignore ignore ignore DW ignore ignore ignore @@ -422,13 +484,17 @@ ICEBP void \1\xF1 386,ND IDIV rm8 \300\1\xF6\207 8086 IDIV rm16 \320\300\1\xF7\207 8086 IDIV rm32 \321\300\1\xF7\207 386 +IDIV rm64 \321\300\1\xF7\207 X64 IMUL rm8 \300\1\xF6\205 8086 IMUL rm16 \320\300\1\xF7\205 8086 IMUL rm32 \321\300\1\xF7\205 386 +IMUL rm64 \321\300\1\xF7\205 X64 IMUL reg16,mem \320\301\2\x0F\xAF\110 386,SM IMUL reg16,reg16 \320\2\x0F\xAF\110 386 IMUL reg32,mem \321\301\2\x0F\xAF\110 386,SM IMUL reg32,reg32 \321\2\x0F\xAF\110 386 +IMUL reg64,mem \321\301\2\x0F\xAF\110 X64,SM +IMUL reg64,reg64 \321\2\x0F\xAF\110 X64 IMUL reg16,mem,imm8 \320\301\1\x6B\110\16 186,SM IMUL reg16,mem,sbyte \320\301\1\x6B\110\16 186,SM,ND IMUL reg16,mem,imm16 \320\301\1\x69\110\32 186,SM @@ -445,6 +511,14 @@ IMUL reg32,reg32,imm8 \321\1\x6B\110\16 386 IMUL reg32,reg32,sbyte \321\1\x6B\110\16 386,SM,ND IMUL reg32,reg32,imm32 \321\1\x69\110\42 386 IMUL reg32,reg32,imm \321\145\1\x69\110\142 386,SM,ND +IMUL reg64,mem,imm8 \321\301\1\x6B\110\16 X64,SM +IMUL reg64,mem,sbyte \321\301\1\x6B\110\16 X64,SM,ND +IMUL reg64,mem,imm32 \321\301\1\x69\110\42 X64,SM +IMUL reg64,mem,imm \321\301\145\1\x69\110\142 X64,SM,ND +IMUL reg64,reg64,imm8 \321\1\x6B\110\16 X64 +IMUL reg64,reg64,sbyte \321\1\x6B\110\16 X64,SM,ND +IMUL reg64,reg64,imm32 \321\1\x69\110\42 X64 +IMUL reg64,reg64,imm \321\145\1\x69\110\142 X64,SM,ND IMUL reg16,imm8 \320\1\x6B\100\15 186 IMUL reg16,sbyte \320\1\x6B\100\15 186,SM,ND IMUL reg16,imm16 \320\1\x69\100\31 186 @@ -453,17 +527,21 @@ IMUL reg32,imm8 \321\1\x6B\100\15 386 IMUL reg32,sbyte \321\1\x6B\100\15 386,SM,ND IMUL reg32,imm32 \321\1\x69\100\41 386 IMUL reg32,imm \321\144\1\x69\100\141 386,SM,ND +IMUL reg64,sbyte \321\1\x6B\100\15 X64,SM,ND +IMUL reg64,imm32 \321\1\x69\100\41 X64 +IMUL reg64,imm \321\144\1\x69\100\141 X64,SM,ND IN reg_al,imm \1\xE4\25 8086,SB IN reg_ax,imm \320\1\xE5\25 8086,SB IN reg_eax,imm \321\1\xE5\25 386,SB IN reg_al,reg_dx \1\xEC 8086 IN reg_ax,reg_dx \320\1\xED 8086 IN reg_eax,reg_dx \321\1\xED 386 -INC reg16 \320\10\x40 8086 -INC reg32 \321\10\x40 386 +INC reg16 \320\10\x40 8086,NOLONG +INC reg32 \321\10\x40 386,NOLONG INC rm8 \300\1\xFE\200 8086 INC rm16 \320\300\1\xFF\200 8086 INC rm32 \321\300\1\xFF\200 386 +INC rm64 \321\300\1\xFF\200 X64 INCBIN ignore ignore ignore INSB void \1\x6C 186 INSD void \321\1\x6D 386 @@ -473,58 +551,68 @@ INT01 void \1\xF1 386,ND INT1 void \1\xF1 386 INT03 void \1\xCC 8086,ND INT3 void \1\xCC 8086 -INTO void \1\xCE 8086 +INTO void \1\xCE 8086,NOLONG INVD void \2\x0F\x08 486,PRIV INVLPG mem \300\2\x0F\x01\207 486,PRIV +INVLPGA void \3\x0F\x01\xDF X64,AMD IRET void \322\1\xCF 8086 IRETD void \321\1\xCF 386 +IRETQ void \324\1\xCF X64 IRETW void \320\1\xCF 8086 -JCXZ imm \310\1\xE3\50 8086 +JCXZ imm \310\1\xE3\50 8086,NOLONG JECXZ imm \311\1\xE3\50 386 JMP imm|short \1\xEB\50 8086 JMP imm \371\1\xEB\50 8086,ND JMP imm \322\1\xE9\64 8086 JMP imm|near \322\1\xE9\64 8086,ND -JMP imm|far \322\1\xEA\34\37 8086,ND +JMP imm|far \322\1\xEA\34\37 8086,ND,NOLONG JMP imm16 \320\1\xE9\64 8086 JMP imm16|near \320\1\xE9\64 8086,ND -JMP imm16|far \320\1\xEA\34\37 8086,ND +JMP imm16|far \320\1\xEA\34\37 8086,ND,NOLONG JMP imm32 \321\1\xE9\64 386 JMP imm32|near \321\1\xE9\64 386,ND -JMP imm32|far \321\1\xEA\34\37 386,ND -JMP imm:imm \322\1\xEA\35\30 8086 -JMP imm16:imm \320\1\xEA\31\30 8086 -JMP imm:imm16 \320\1\xEA\31\30 8086 -JMP imm32:imm \321\1\xEA\41\30 386 -JMP imm:imm32 \321\1\xEA\41\30 386 +JMP imm32|far \321\1\xEA\34\37 386,ND,NOLONG +JMP imm:imm \322\1\xEA\35\30 8086,NOLONG +JMP imm16:imm \320\1\xEA\31\30 8086,NOLONG +JMP imm:imm16 \320\1\xEA\31\30 8086,NOLONG +JMP imm32:imm \321\1\xEA\41\30 386,NOLONG +JMP imm:imm32 \321\1\xEA\41\30 386,NOLONG JMP mem|far \322\300\1\xFF\205 8086 JMP mem16|far \320\300\1\xFF\205 8086 JMP mem32|far \321\300\1\xFF\205 386 JMP mem|near \322\300\1\xFF\204 8086 JMP mem16|near \320\300\1\xFF\204 8086 -JMP mem32|near \321\300\1\xFF\204 386 +JMP mem32|near \321\300\1\xFF\204 386,NOLONG +JMP mem64|near \321\300\1\xFF\204 X64 JMP reg16 \320\300\1\xFF\204 8086 -JMP reg32 \321\300\1\xFF\204 386 +JMP reg32 \321\300\1\xFF\204 386,NOLONG +JMP reg64 \321\300\1\xFF\204 X64 JMP mem \322\300\1\xFF\204 8086 JMP mem16 \320\300\1\xFF\204 8086 -JMP mem32 \321\300\1\xFF\204 386 +JMP mem32 \321\300\1\xFF\204 386,NOLONG +JMP mem64 \321\300\1\xFF\204 X64 JMPE imm \322\2\x0F\xB8\64 IA64 JMPE imm16 \320\2\x0F\xB8\64 IA64 JMPE imm32 \321\2\x0F\xB8\64 IA64 JMPE rm16 \320\2\x0F\x00\206 IA64 JMPE rm32 \321\2\x0F\x00\206 IA64 +JRCXZ imm \300\1\xE3\50 X64 LAHF void \1\x9F 8086 LAR reg16,mem \320\301\2\x0F\x02\110 286,PROT,SM LAR reg16,reg16 \320\2\x0F\x02\110 286,PROT LAR reg32,mem \321\301\2\x0F\x02\110 386,PROT,SM LAR reg32,reg32 \321\2\x0F\x02\110 386,PROT -LDS reg16,mem \320\301\1\xC5\110 8086 -LDS reg32,mem \321\301\1\xC5\110 386 +LAR reg64,mem \321\301\2\x0F\x02\110 X64,SM +LAR reg64,reg64 \321\2\x0F\x02\110 X64,PROT +LDS reg16,mem \320\301\1\xC5\110 8086,NOLONG +LDS reg32,mem \321\301\1\xC5\110 386,NOLONG LEA reg16,mem \320\301\1\x8D\110 8086 LEA reg32,mem \321\301\1\x8D\110 386 +LEA reg64,mem \321\301\1\x8D\110 X64 LEAVE void \1\xC9 186 -LES reg16,mem \320\301\1\xC4\110 8086 -LES reg32,mem \321\301\1\xC4\110 386 +LES reg16,mem \320\301\1\xC4\110 8086,NOLONG +LES reg32,mem \321\301\1\xC4\110 386,NOLONG +LFENCE void \3\x0F\xAE\xE8 X64,AMD LFS reg16,mem \320\301\2\x0F\xB4\110 386 LFS reg32,mem \321\301\2\x0F\xB4\110 386 LGDT mem \300\2\x0F\x01\202 286,PRIV @@ -541,31 +629,40 @@ LOADALL void \2\x0F\x07 386,UNDOC LOADALL286 void \2\x0F\x05 286,UNDOC LODSB void \1\xAC 8086 LODSD void \321\1\xAD 386 +LODSQ void \324\1\xAD X64 LODSW void \320\1\xAD 8086 LOOP imm \312\1\xE2\50 8086 -LOOP imm,reg_cx \310\1\xE2\50 8086 +LOOP imm,reg_cx \310\1\xE2\50 8086,NOLONG LOOP imm,reg_ecx \311\1\xE2\50 386 +LOOP imm,reg_rcx \313\1\xE2\50 X64 LOOPE imm \312\1\xE1\50 8086 -LOOPE imm,reg_cx \310\1\xE1\50 8086 +LOOPE imm,reg_cx \310\1\xE1\50 8086,NOLONG LOOPE imm,reg_ecx \311\1\xE1\50 386 +LOOPE imm,reg_rcx \313\1\xE1\50 X64 LOOPNE imm \312\1\xE0\50 8086 -LOOPNE imm,reg_cx \310\1\xE0\50 8086 +LOOPNE imm,reg_cx \310\1\xE0\50 8086,NOLONG LOOPNE imm,reg_ecx \311\1\xE0\50 386 +LOOPNE imm,reg_rcx \313\1\xE0\50 X64 LOOPNZ imm \312\1\xE0\50 8086 -LOOPNZ imm,reg_cx \310\1\xE0\50 8086 +LOOPNZ imm,reg_cx \310\1\xE0\50 8086,NOLONG LOOPNZ imm,reg_ecx \311\1\xE0\50 386 +LOOPNZ imm,reg_rcx \313\1\xE0\50 X64 LOOPZ imm \312\1\xE1\50 8086 -LOOPZ imm,reg_cx \310\1\xE1\50 8086 +LOOPZ imm,reg_cx \310\1\xE1\50 8086,NOLONG LOOPZ imm,reg_ecx \311\1\xE1\50 386 +LOOPZ imm,reg_rcx \313\1\xE1\50 X64 LSL reg16,mem \320\301\2\x0F\x03\110 286,PROT,SM LSL reg16,reg16 \320\2\x0F\x03\110 286,PROT LSL reg32,mem \321\301\2\x0F\x03\110 386,PROT,SM LSL reg32,reg32 \321\2\x0F\x03\110 386,PROT +LSL reg64,mem \321\301\2\x0F\x03\110 X64,SM +LSL reg64,reg64 \321\2\x0F\x03\110 X64,PROT LSS reg16,mem \320\301\2\x0F\xB2\110 386 LSS reg32,mem \321\301\2\x0F\xB2\110 386 LTR mem \300\1\x0F\17\203 286,PROT,PRIV -LTR mem16 \300\1\x0F\17\203 286,PROT,PRIV -LTR reg16 \1\x0F\17\203 286,PROT,PRIV +LTR mem16 \300\1\x0F\17\203 286,PROT,PRIV,NOLONG +LTR reg16 \1\x0F\17\203 286,PROT,PRIV,NOLONG +MFENCE void \3\x0F\xAE\xF0 X64,AMD MONITOR void \3\x0F\x01\xC8 PRESCOTT MONITOR reg_eax,reg_ecx,reg_edx \3\x0F\x01\xC8 PRESCOTT,ND MOV mem,reg_sreg \300\1\x8C\101 8086,SM @@ -577,89 +674,136 @@ MOV reg_sreg,reg32 \1\x8E\110 386 MOV reg_al,mem_offs \301\1\xA0\45 8086,SM MOV reg_ax,mem_offs \301\320\1\xA1\45 8086,SM MOV reg_eax,mem_offs \301\321\1\xA1\45 386,SM +MOV reg_rax,mem_offs \301\321\1\xA1\45 X64,SM MOV mem_offs,reg_al \300\1\xA2\44 8086,SM MOV mem_offs,reg_ax \300\320\1\xA3\44 8086,SM MOV mem_offs,reg_eax \300\321\1\xA3\44 386,SM +MOV mem_offs,reg_rax \300\321\1\xA3\44 X64,SM +MOV reg32,reg_c8reg \3\xF0\x0F\x20\101 NOLONG +MOV reg_c8reg,reg32 \3\xF0\x0F\x22\110 NOLONG +MOV reg32,reg_c8reg \321\2\x0F\x20\101 X64 +MOV reg64,reg_c8reg \323\2\x0F\x20\101 X64 +MOV reg_c8reg,reg32 \321\2\x0F\x22\110 X64 +MOV reg_c8reg,reg64 \323\2\x0F\x22\110 X64 MOV reg32,reg_creg \2\x0F\x20\101 386,PRIV -MOV reg32,reg_dreg \2\x0F\x21\101 386,PRIV -MOV reg32,reg_treg \2\x0F\x24\101 386,PRIV +MOV reg64,reg_creg \323\2\x0F\x20\101 X64 MOV reg_creg,reg32 \2\x0F\x22\110 386,PRIV +MOV reg_creg,reg64 \323\2\x0F\x22\110 X64 +MOV reg32,reg_dreg \2\x0F\x21\101 386,PRIV +MOV reg64,reg_dreg \323\2\x0F\x21\101 X64 MOV reg_dreg,reg32 \2\x0F\x23\110 386,PRIV +MOV reg_dreg,reg64 \323\2\x0F\x23\110 X64 +MOV reg32,reg_treg \2\x0F\x24\101 386,PRIV +MOV reg64,reg_treg \323\2\x0F\x24\101 X64 MOV reg_treg,reg32 \2\x0F\x26\110 386,PRIV +MOV reg_treg,reg64 \323\2\x0F\x26\110 X64 MOV mem,reg8 \300\1\x88\101 8086,SM MOV reg8,reg8 \1\x88\101 8086 MOV mem,reg16 \320\300\1\x89\101 8086,SM MOV reg16,reg16 \320\1\x89\101 8086 MOV mem,reg32 \321\300\1\x89\101 386,SM MOV reg32,reg32 \321\1\x89\101 386 +MOV mem,reg64 \321\300\1\x89\101 X64,SM +MOV reg64,reg64 \321\1\x89\101 X64 MOV reg8,mem \301\1\x8A\110 8086,SM MOV reg8,reg8 \1\x8A\110 8086 MOV reg16,mem \320\301\1\x8B\110 8086,SM MOV reg16,reg16 \320\1\x8B\110 8086 MOV reg32,mem \321\301\1\x8B\110 386,SM MOV reg32,reg32 \321\1\x8B\110 386 +MOV reg64,mem \321\301\1\x8B\110 X64,SM +MOV reg64,reg64 \321\1\x8B\110 X64 MOV reg8,imm \10\xB0\21 8086,SM MOV reg16,imm \320\10\xB8\31 8086,SM MOV reg32,imm \321\10\xB8\41 386,SM +MOV reg64,imm \321\10\xB8\55 X64,SM MOV rm8,imm \300\1\xC6\200\21 8086,SM MOV rm16,imm \320\300\1\xC7\200\31 8086,SM MOV rm32,imm \321\300\1\xC7\200\41 386,SM +MOV rm64,imm \321\300\1\xC7\200\41 X64,SM MOV mem,imm8 \300\1\xC6\200\21 8086,SM MOV mem,imm16 \320\300\1\xC7\200\31 8086,SM MOV mem,imm32 \321\300\1\xC7\200\41 386,SM MOVD mmxreg,mem \301\2\x0F\x6E\110 PENT,MMX,SD MOVD mmxreg,reg32 \2\x0F\x6E\110 PENT,MMX +MOVD mmxreg,reg64 \2\x0F\x6E\110 X64,MMX MOVD mem,mmxreg \300\2\x0F\x7E\101 PENT,MMX,SD MOVD reg32,mmxreg \2\x0F\x7E\101 PENT,MMX +MOVD reg64,mmxreg \2\x0F\x7E\101 X64,MMX +MOVD xmmreg,mem \320\301\2\x0F\x6E\110 X64,SD +MOVD xmmreg,reg32 \320\2\x0F\x6E\110 X64 +MOVD xmmreg,reg64 \320\2\x0F\x6E\110 X64 +MOVD mem,xmmreg \320\300\2\x0F\x7E\101 X64,SD +MOVD reg32,xmmreg \320\2\x0F\x7E\101 X64,SSE +MOVD reg64,xmmreg \320\2\x0F\x7E\101 X64,SSE +MOVMSKPD reg32,xmmreg \320\2\x0F\x50\101 X64,SSE +MOVMSKPS reg32,xmmreg \2\x0F\x50\101 X64,SSE MOVQ mmxreg,mem \301\2\x0F\x6F\110 PENT,MMX,SM MOVQ mmxreg,mmxreg \2\x0F\x6F\110 PENT,MMX MOVQ mem,mmxreg \300\2\x0F\x7F\101 PENT,MMX,SM MOVQ mmxreg,mmxreg \2\x0F\x7F\101 PENT,MMX MOVSB void \1\xA4 8086 MOVSD void \321\1\xA5 386 +MOVSQ void \324\1\xA5 X64 MOVSW void \320\1\xA5 8086 MOVSX reg16,mem \320\301\2\x0F\xBE\110 386,SB MOVSX reg16,reg8 \320\2\x0F\xBE\110 386 MOVSX reg32,rm8 \321\301\2\x0F\xBE\110 386 MOVSX reg32,rm16 \321\301\2\x0F\xBF\110 386 +MOVSX reg64,rm8 \321\301\2\x0F\xBE\110 X64 +MOVSX reg64,rm16 \321\301\2\x0F\xBF\110 X64 +MOVSX reg64,rm32 \321\301\1\x63\110 X64 MOVZX reg16,mem \320\301\2\x0F\xB6\110 386,SB MOVZX reg16,reg8 \320\2\x0F\xB6\110 386 MOVZX reg32,rm8 \321\301\2\x0F\xB6\110 386 MOVZX reg32,rm16 \321\301\2\x0F\xB7\110 386 +MOVZX reg64,rm8 \321\301\2\x0F\xB6\110 X64 +MOVZX reg64,rm16 \321\301\2\x0F\xB7\110 X64 MUL rm8 \300\1\xF6\204 8086 MUL rm16 \320\300\1\xF7\204 8086 MUL rm32 \321\300\1\xF7\204 386 +MUL rm64 \321\300\1\xF7\204 X64 MWAIT void \3\x0F\x01\xC9 PRESCOTT MWAIT reg_eax,reg_ecx \3\x0F\x01\xC9 PRESCOTT,ND NEG rm8 \300\1\xF6\203 8086 NEG rm16 \320\300\1\xF7\203 8086 NEG rm32 \321\300\1\xF7\203 386 +NEG rm64 \321\300\1\xF7\203 X64 NOP void \1\x90 8086 NOT rm8 \300\1\xF6\202 8086 NOT rm16 \320\300\1\xF7\202 8086 NOT rm32 \321\300\1\xF7\202 386 +NOT rm64 \321\300\1\xF7\202 X64 OR mem,reg8 \300\1\x08\101 8086,SM OR reg8,reg8 \1\x08\101 8086 OR mem,reg16 \320\300\1\x09\101 8086,SM OR reg16,reg16 \320\1\x09\101 8086 OR mem,reg32 \321\300\1\x09\101 386,SM OR reg32,reg32 \321\1\x09\101 386 +OR mem,reg64 \321\300\1\x09\101 X64,SM +OR reg64,reg64 \321\1\x09\101 X64 OR reg8,mem \301\1\x0A\110 8086,SM OR reg8,reg8 \1\x0A\110 8086 OR reg16,mem \320\301\1\x0B\110 8086,SM OR reg16,reg16 \320\1\x0B\110 8086 OR reg32,mem \321\301\1\x0B\110 386,SM OR reg32,reg32 \321\1\x0B\110 386 +OR reg64,mem \321\301\1\x0B\110 X64,SM +OR reg64,reg64 \321\1\x0B\110 X64 OR rm16,imm8 \320\300\1\x83\201\15 8086 OR rm32,imm8 \321\300\1\x83\201\15 386 +OR rm64,imm8 \321\300\1\x83\201\15 X64 OR reg_al,imm \1\x0C\21 8086,SM OR reg_ax,sbyte \320\1\x83\201\15 8086,SM,ND OR reg_ax,imm \320\1\x0D\31 8086,SM OR reg_eax,sbyte \321\1\x83\201\15 386,SM,ND OR reg_eax,imm \321\1\x0D\41 386,SM +OR reg_rax,sbyte \321\1\x83\201\15 X64,SM,ND +OR reg_rax,imm \321\1\x0D\41 X64,SM OR rm8,imm \300\1\x80\201\21 8086,SM OR rm16,imm \320\300\134\1\x81\201\131 8086,SM OR rm32,imm \321\300\144\1\x81\201\141 386,SM +OR rm64,imm \321\300\144\1\x81\201\141 X64,SM OR mem,imm8 \300\1\x80\201\21 8086,SM OR mem,imm16 \320\300\134\1\x81\201\131 8086,SM OR mem,imm32 \321\300\144\1\x81\201\141 386,SM @@ -698,6 +842,7 @@ PAND mmxreg,mem \301\2\x0F\xDB\110 PENT,MMX,SM PAND mmxreg,mmxreg \2\x0F\xDB\110 PENT,MMX PANDN mmxreg,mem \301\2\x0F\xDF\110 PENT,MMX,SM PANDN mmxreg,mmxreg \2\x0F\xDF\110 PENT,MMX +PAUSE void \2\xF3\x90 X64,AMD PAVEB mmxreg,mem \301\2\x0F\x50\110 PENT,MMX,SM,CYRIX PAVEB mmxreg,mmxreg \2\x0F\x50\110 PENT,MMX,CYRIX PAVGUSB mmxreg,mem \301\2\x0F\x0F\110\01\xBF PENT,3DNOW,SM @@ -769,22 +914,29 @@ PMVLZB mmxreg,mem \301\2\x0F\x5B\110 PENT,MMX,SM,CYRIX PMVNZB mmxreg,mem \301\2\x0F\x5A\110 PENT,MMX,SM,CYRIX PMVZB mmxreg,mem \301\2\x0F\x58\110 PENT,MMX,SM,CYRIX POP reg16 \320\10\x58 8086 -POP reg32 \321\10\x58 386 +POP reg32 \321\10\x58 386,NOLONG +POP reg64 \323\10\x58 X64 POP rm16 \320\300\1\x8F\200 8086 -POP rm32 \321\300\1\x8F\200 386 +POP rm32 \321\300\1\x8F\200 386,NOLONG +POP rm64 \323\300\1\x8F\200 X64 POP reg_cs \1\x0F 8086,UNDOC,ND -POP reg_dess \4 8086 +POP reg_dess \4 8086,NOLONG POP reg_fsgs \1\x0F\5 386 -POPA void \322\1\x61 186 -POPAD void \321\1\x61 386 -POPAW void \320\1\x61 186 +POPA void \322\1\x61 186,NOLONG +POPAD void \321\1\x61 386,NOLONG +POPAW void \320\1\x61 186,NOLONG POPF void \322\1\x9D 8086 -POPFD void \321\1\x9D 386 +POPFD void \321\1\x9D 386,NOLONG +POPFQ void \321\1\x9D X64 POPFW void \320\1\x9D 8086 POR mmxreg,mem \301\2\x0F\xEB\110 PENT,MMX,SM POR mmxreg,mmxreg \2\x0F\xEB\110 PENT,MMX PREFETCH mem \2\x0F\x0D\200 PENT,3DNOW,SM PREFETCHW mem \2\x0F\x0D\201 PENT,3DNOW,SM +PREFETCHNTA mem \2\x0F\x18\200 X64,AMD,SM +PREFETCHT0 mem \2\x0F\x18\200 X64,AMD,SM +PREFETCHT1 mem \2\x0F\x18\201 X64,AMD,SM +PREFETCHT2 mem \2\x0F\x18\202 X64,AMD,SM PSLLD mmxreg,mem \301\2\x0F\xF2\110 PENT,MMX,SM PSLLD mmxreg,mmxreg \2\x0F\xF2\110 PENT,MMX PSLLD mmxreg,imm \2\x0F\x72\206\25 PENT,MMX @@ -838,22 +990,26 @@ PUNPCKLDQ mmxreg,mmxreg \2\x0F\x62\110 PENT,MMX PUNPCKLWD mmxreg,mem \301\2\x0F\x61\110 PENT,MMX,SM PUNPCKLWD mmxreg,mmxreg \2\x0F\x61\110 PENT,MMX PUSH reg16 \320\10\x50 8086 -PUSH reg32 \321\10\x50 386 +PUSH reg32 \321\10\x50 386,NOLONG +PUSH reg64 \323\10\x50 X64 PUSH rm16 \320\300\1\xFF\206 8086 -PUSH rm32 \321\300\1\xFF\206 386 -PUSH reg_cs \6 8086 -PUSH reg_dess \6 8086 +PUSH rm32 \321\300\1\xFF\206 386,NOLONG +PUSH rm64 \323\300\1\xFF\206 X64 +PUSH reg_cs \6 8086,NOLONG +PUSH reg_dess \6 8086,NOLONG PUSH reg_fsgs \1\x0F\7 386 PUSH imm8 \1\x6A\14 186 PUSH sbyte \1\x6A\14 186,ND PUSH imm16 \320\133\1\x68\130 186 -PUSH imm32 \321\143\1\x68\140 386 +PUSH imm32 \321\143\1\x68\140 386,NOLONG +PUSH imm64 \321\143\1\x68\140 X64 PUSH imm \1\x68\34 186 -PUSHA void \322\1\x60 186 -PUSHAD void \321\1\x60 386 -PUSHAW void \320\1\x60 186 +PUSHA void \322\1\x60 186,NOLONG +PUSHAD void \321\1\x60 386,NOLONG +PUSHAW void \320\1\x60 186,NOLONG PUSHF void \322\1\x9C 8086 -PUSHFD void \321\1\x9C 386 +PUSHFD void \321\1\x9C 386,NOLONG +PUSHFQ void \321\1\x9C X64 PUSHFW void \320\1\x9C 8086 PXOR mmxreg,mem \301\2\x0F\xEF\110 PENT,MMX,SM PXOR mmxreg,mmxreg \2\x0F\xEF\110 PENT,MMX @@ -866,6 +1022,9 @@ RCL rm16,imm \320\300\1\xC1\202\25 186,SB RCL rm32,unity \321\300\1\xD1\202 386 RCL rm32,reg_cl \321\300\1\xD3\202 386 RCL rm32,imm \321\300\1\xC1\202\25 386,SB +RCL rm64,unity \321\300\1\xD1\202 X64 +RCL rm64,reg_cl \321\300\1\xD3\202 X64 +RCL rm64,imm \321\300\1\xC1\202\25 X64,SB RCR rm8,unity \300\1\xD0\203 8086 RCR rm8,reg_cl \300\1\xD2\203 8086 RCR rm8,imm \300\1\xC0\203\25 186,SB @@ -875,10 +1034,14 @@ RCR rm16,imm \320\300\1\xC1\203\25 186,SB RCR rm32,unity \321\300\1\xD1\203 386 RCR rm32,reg_cl \321\300\1\xD3\203 386 RCR rm32,imm \321\300\1\xC1\203\25 386,SB +RCR rm64,unity \321\300\1\xD1\203 X64 +RCR rm64,reg_cl \321\300\1\xD3\203 X64 +RCR rm64,imm \321\300\1\xC1\203\25 X64,SB RDSHR rm32 \321\300\2\x0F\x36\200 P6,CYRIX,SMM RDMSR void \2\x0F\x32 PENT,PRIV RDPMC void \2\x0F\x33 P6 RDTSC void \2\x0F\x31 PENT +RDTSCP void \3\x0F\x01\xF9 X64 RESB imm \340 8086 RESD ignore ignore ignore RESQ ignore ignore ignore @@ -899,6 +1062,9 @@ ROL rm16,imm \320\300\1\xC1\200\25 186,SB ROL rm32,unity \321\300\1\xD1\200 386 ROL rm32,reg_cl \321\300\1\xD3\200 386 ROL rm32,imm \321\300\1\xC1\200\25 386,SB +ROL rm64,unity \321\300\1\xD1\200 X64 +ROL rm64,reg_cl \321\300\1\xD3\200 X64 +ROL rm64,imm \321\300\1\xC1\200\25 X64,SB ROR rm8,unity \300\1\xD0\201 8086 ROR rm8,reg_cl \300\1\xD2\201 8086 ROR rm8,imm \300\1\xC0\201\25 186,SB @@ -908,6 +1074,9 @@ ROR rm16,imm \320\300\1\xC1\201\25 186,SB ROR rm32,unity \321\300\1\xD1\201 386 ROR rm32,reg_cl \321\300\1\xD3\201 386 ROR rm32,imm \321\300\1\xC1\201\25 386,SB +ROR rm64,unity \321\300\1\xD1\201 X64 +ROR rm64,reg_cl \321\300\1\xD3\201 X64 +ROR rm64,imm \321\300\1\xC1\201\25 X64,SB RSDC reg_sreg,mem80 \301\2\x0F\x79\110 486,CYRIX,SMM RSLDT mem80 \300\2\x0F\x7B\200 486,CYRIX,SMM RSM void \2\x0F\xAA PENT,SMM @@ -922,6 +1091,9 @@ SAL rm16,imm \320\300\1\xC1\204\25 186,ND,SB SAL rm32,unity \321\300\1\xD1\204 386,ND SAL rm32,reg_cl \321\300\1\xD3\204 386,ND SAL rm32,imm \321\300\1\xC1\204\25 386,ND,SB +SAL rm64,unity \321\300\1\xD1\204 X64,ND +SAL rm64,reg_cl \321\300\1\xD3\204 X64,ND +SAL rm64,imm \321\300\1\xC1\204\25 X64,ND,SB SALC void \1\xD6 8086,UNDOC SAR rm8,unity \300\1\xD0\207 8086 SAR rm8,reg_cl \300\1\xD2\207 8086 @@ -932,34 +1104,47 @@ SAR rm16,imm \320\300\1\xC1\207\25 186,SB SAR rm32,unity \321\300\1\xD1\207 386 SAR rm32,reg_cl \321\300\1\xD3\207 386 SAR rm32,imm \321\300\1\xC1\207\25 386,SB +SAR rm64,unity \321\300\1\xD1\207 X64 +SAR rm64,reg_cl \321\300\1\xD3\207 X64 +SAR rm64,imm \321\300\1\xC1\207\25 X64,SB SBB mem,reg8 \300\1\x18\101 8086,SM SBB reg8,reg8 \1\x18\101 8086 SBB mem,reg16 \320\300\1\x19\101 8086,SM SBB reg16,reg16 \320\1\x19\101 8086 SBB mem,reg32 \321\300\1\x19\101 386,SM SBB reg32,reg32 \321\1\x19\101 386 +SBB mem,reg64 \321\300\1\x19\101 X64,SM +SBB reg64,reg64 \321\1\x19\101 X64 SBB reg8,mem \301\1\x1A\110 8086,SM SBB reg8,reg8 \1\x1A\110 8086 SBB reg16,mem \320\301\1\x1B\110 8086,SM SBB reg16,reg16 \320\1\x1B\110 8086 SBB reg32,mem \321\301\1\x1B\110 386,SM SBB reg32,reg32 \321\1\x1B\110 386 +SBB reg64,mem \321\301\1\x1B\110 X64,SM +SBB reg64,reg64 \321\1\x1B\110 X64 SBB rm16,imm8 \320\300\1\x83\203\15 8086 SBB rm32,imm8 \321\300\1\x83\203\15 386 +SBB rm64,imm8 \321\300\1\x83\203\15 X64 SBB reg_al,imm \1\x1C\21 8086,SM SBB reg_ax,sbyte \320\1\x83\203\15 8086,SM,ND SBB reg_ax,imm \320\1\x1D\31 8086,SM SBB reg_eax,sbyte \321\1\x83\203\15 386,SM,ND SBB reg_eax,imm \321\1\x1D\41 386,SM +SBB reg_rax,sbyte \321\1\x83\203\15 X64,SM,ND +SBB reg_rax,imm \321\1\x1D\41 X64,SM SBB rm8,imm \300\1\x80\203\21 8086,SM SBB rm16,imm \320\300\134\1\x81\203\131 8086,SM SBB rm32,imm \321\300\144\1\x81\203\141 386,SM +SBB rm64,imm \321\300\144\1\x81\203\141 X64,SM SBB mem,imm8 \300\1\x80\203\21 8086,SM SBB mem,imm16 \320\300\134\1\x81\203\131 8086,SM SBB mem,imm32 \321\300\144\1\x81\203\141 386,SM SCASB void \332\1\xAE 8086 SCASD void \332\321\1\xAF 386 +SCASQ void \332\324\1\xAF X64 SCASW void \332\320\1\xAF 8086 +SFENCE void \3\x0F\xAE\xF8 X64,AMD SGDT mem \300\2\x0F\x01\200 286 SHL rm8,unity \300\1\xD0\204 8086 SHL rm8,reg_cl \300\1\xD2\204 8086 @@ -970,14 +1155,21 @@ SHL rm16,imm \320\300\1\xC1\204\25 186,SB SHL rm32,unity \321\300\1\xD1\204 386 SHL rm32,reg_cl \321\300\1\xD3\204 386 SHL rm32,imm \321\300\1\xC1\204\25 386,SB +SHL rm64,unity \321\300\1\xD1\204 X64 +SHL rm64,reg_cl \321\300\1\xD3\204 X64 +SHL rm64,imm \321\300\1\xC1\204\25 X64,SB SHLD mem,reg16,imm \300\320\2\x0F\xA4\101\26 386,SM2,SB,AR2 SHLD reg16,reg16,imm \320\2\x0F\xA4\101\26 386,SM2,SB,AR2 SHLD mem,reg32,imm \300\321\2\x0F\xA4\101\26 386,SM2,SB,AR2 SHLD reg32,reg32,imm \321\2\x0F\xA4\101\26 386,SM2,SB,AR2 +SHLD mem,reg64,imm \300\321\2\x0F\xA4\101\26 X64,SM2,SB,AR2 +SHLD reg64,reg64,imm \321\2\x0F\xA4\101\26 X64,SM2,SB,AR2 SHLD mem,reg16,reg_cl \300\320\2\x0F\xA5\101 386,SM SHLD reg16,reg16,reg_cl \320\2\x0F\xA5\101 386 SHLD mem,reg32,reg_cl \300\321\2\x0F\xA5\101 386,SM SHLD reg32,reg32,reg_cl \321\2\x0F\xA5\101 386 +SHLD mem,reg64,reg_cl \300\321\2\x0F\xA5\101 X64,SM +SHLD reg64,reg64,reg_cl \321\2\x0F\xA5\101 X64 SHR rm8,unity \300\1\xD0\205 8086 SHR rm8,reg_cl \300\1\xD2\205 8086 SHR rm8,imm \300\1\xC0\205\25 186,SB @@ -987,19 +1179,27 @@ SHR rm16,imm \320\300\1\xC1\205\25 186,SB SHR rm32,unity \321\300\1\xD1\205 386 SHR rm32,reg_cl \321\300\1\xD3\205 386 SHR rm32,imm \321\300\1\xC1\205\25 386,SB +SHR rm64,unity \321\300\1\xD1\205 X64 +SHR rm64,reg_cl \321\300\1\xD3\205 X64 +SHR rm64,imm \321\300\1\xC1\205\25 X64,SB SHRD mem,reg16,imm \300\320\2\x0F\xAC\101\26 386,SM2,SB,AR2 SHRD reg16,reg16,imm \320\2\x0F\xAC\101\26 386,SM2,SB,AR2 SHRD mem,reg32,imm \300\321\2\x0F\xAC\101\26 386,SM2,SB,AR2 SHRD reg32,reg32,imm \321\2\x0F\xAC\101\26 386,SM2,SB,AR2 +SHRD mem,reg64,imm \300\321\2\x0F\xAC\101\26 X64,SM2,SB,AR2 +SHRD reg64,reg64,imm \321\2\x0F\xAC\101\26 X64,SM2,SB,AR2 SHRD mem,reg16,reg_cl \300\320\2\x0F\xAD\101 386,SM SHRD reg16,reg16,reg_cl \320\2\x0F\xAD\101 386 SHRD mem,reg32,reg_cl \300\321\2\x0F\xAD\101 386,SM SHRD reg32,reg32,reg_cl \321\2\x0F\xAD\101 386 +SHRD mem,reg64,reg_cl \300\321\2\x0F\xAD\101 X64,SM +SHRD reg64,reg64,reg_cl \321\2\x0F\xAD\101 X64 SIDT mem \300\2\x0F\x01\201 286 SLDT mem \300\1\x0F\17\200 286 SLDT mem16 \300\1\x0F\17\200 286 SLDT reg16 \320\1\x0F\17\200 286 SLDT reg32 \321\1\x0F\17\200 386 +SKINIT void \3\x0F\x01\xDE X64 SMI void \1\xF1 386,UNDOC SMINT void \2\x0F\x38 P6,CYRIX ; Older Cyrix chips had this; they had to move due to conflict with MMX @@ -1010,42 +1210,54 @@ SMSW reg16 \320\2\x0F\x01\204 286 SMSW reg32 \321\2\x0F\x01\204 386 STC void \1\xF9 8086 STD void \1\xFD 8086 +STGI void \3\x0F\x01\xDC X64 STI void \1\xFB 8086 STOSB void \1\xAA 8086 STOSD void \321\1\xAB 386 +STOSQ void \324\1\xAB X64 STOSW void \320\1\xAB 8086 STR mem \300\1\x0F\17\201 286,PROT STR mem16 \300\1\x0F\17\201 286,PROT STR reg16 \320\1\x0F\17\201 286,PROT STR reg32 \321\1\x0F\17\201 386,PROT +STR reg64 \321\1\x0F\17\201 X64 SUB mem,reg8 \300\1\x28\101 8086,SM SUB reg8,reg8 \1\x28\101 8086 SUB mem,reg16 \320\300\1\x29\101 8086,SM SUB reg16,reg16 \320\1\x29\101 8086 SUB mem,reg32 \321\300\1\x29\101 386,SM SUB reg32,reg32 \321\1\x29\101 386 +SUB mem,reg64 \321\300\1\x29\101 X64,SM +SUB reg64,reg64 \321\1\x29\101 X64 SUB reg8,mem \301\1\x2A\110 8086,SM SUB reg8,reg8 \1\x2A\110 8086 SUB reg16,mem \320\301\1\x2B\110 8086,SM SUB reg16,reg16 \320\1\x2B\110 8086 SUB reg32,mem \321\301\1\x2B\110 386,SM SUB reg32,reg32 \321\1\x2B\110 386 +SUB reg64,mem \321\301\1\x2B\110 X64,SM +SUB reg64,reg64 \321\1\x2B\110 X64 SUB rm16,imm8 \320\300\1\x83\205\15 8086 SUB rm32,imm8 \321\300\1\x83\205\15 386 +SUB rm64,imm8 \321\300\1\x83\205\15 X64 SUB reg_al,imm \1\x2C\21 8086,SM SUB reg_ax,sbyte \320\1\x83\205\15 8086,SM,ND SUB reg_ax,imm \320\1\x2D\31 8086,SM SUB reg_eax,sbyte \321\1\x83\205\15 386,SM,ND SUB reg_eax,imm \321\1\x2D\41 386,SM +SUB reg_rax,sbyte \321\1\x83\205\15 X64,SM,ND +SUB reg_rax,imm \321\1\x2D\41 X64,SM SUB rm8,imm \300\1\x80\205\21 8086,SM SUB rm16,imm \320\300\134\1\x81\205\131 8086,SM SUB rm32,imm \321\300\144\1\x81\205\141 386,SM +SUB rm64,imm \321\300\144\1\x81\205\141 X64,SM SUB mem,imm8 \300\1\x80\205\21 8086,SM SUB mem,imm16 \320\300\134\1\x81\205\131 8086,SM SUB mem,imm32 \321\300\144\1\x81\205\141 386,SM SVDC mem80,reg_sreg \300\2\x0F\x78\101 486,CYRIX,SMM SVLDT mem80 \300\2\x0F\x7A\200 486,CYRIX,SMM SVTS mem80 \300\2\x0F\x7C\200 486,CYRIX,SMM +SWAPGS void \3\x0F\x01\xF8 X64 SYSCALL void \2\x0F\x05 P6,AMD SYSENTER void \2\x0F\x34 P6 SYSEXIT void \2\x0F\x35 P6,PRIV @@ -1056,15 +1268,20 @@ TEST mem,reg16 \320\300\1\x85\101 8086,SM TEST reg16,reg16 \320\1\x85\101 8086 TEST mem,reg32 \321\300\1\x85\101 386,SM TEST reg32,reg32 \321\1\x85\101 386 +TEST mem,reg64 \321\300\1\x85\101 X64,SM +TEST reg64,reg64 \321\1\x85\101 X64 TEST reg8,mem \301\1\x84\110 8086,SM TEST reg16,mem \320\301\1\x85\110 8086,SM TEST reg32,mem \321\301\1\x85\110 386,SM +TEST reg64,mem \321\301\1\x85\110 X64,SM TEST reg_al,imm \1\xA8\21 8086,SM TEST reg_ax,imm \320\1\xA9\31 8086,SM TEST reg_eax,imm \321\1\xA9\41 386,SM +TEST reg_rax,imm \321\1\xA9\41 X64,SM TEST rm8,imm \300\1\xF6\200\21 8086,SM TEST rm16,imm \320\300\1\xF7\200\31 8086,SM TEST rm32,imm \321\300\1\xF7\200\41 386,SM +TEST rm64,imm \321\300\1\xF7\200\41 X64,SM TEST mem,imm8 \300\1\xF6\200\21 8086,SM TEST mem,imm16 \320\300\1\xF7\200\31 8086,SM TEST mem,imm32 \321\300\1\xF7\200\41 386,SM @@ -1100,26 +1317,33 @@ XADD mem,reg16 \320\300\2\x0F\xC1\101 486,SM XADD reg16,reg16 \320\2\x0F\xC1\101 486 XADD mem,reg32 \321\300\2\x0F\xC1\101 486,SM XADD reg32,reg32 \321\2\x0F\xC1\101 486 +XADD mem,reg64 \321\300\2\x0F\xC1\101 X64,SM +XADD reg64,reg64 \321\2\x0F\xC1\101 X64 XBTS reg16,mem \320\301\2\x0F\xA6\110 386,SW,UNDOC,ND XBTS reg16,reg16 \320\2\x0F\xA6\110 386,UNDOC,ND XBTS reg32,mem \321\301\2\x0F\xA6\110 386,SD,UNDOC,ND XBTS reg32,reg32 \321\2\x0F\xA6\110 386,UNDOC,ND -XCHG reg_ax,reg16 \320\11\x90 8086 -XCHG reg_eax,reg32 \321\11\x90 386 -XCHG reg16,reg_ax \320\10\x90 8086 -XCHG reg32,reg_eax \321\10\x90 386 +XCHG reg_ax,reg16 \320\11\x90 8086,NOLONG +XCHG reg_eax,reg32 \321\11\x90 386,NOLONG +XCHG reg16,reg_ax \320\10\x90 8086,NOLONG +XCHG reg32,reg_eax \321\10\x90 386,NOLONG +XCHG reg_rax,reg_rax \321\11\x90 X64 XCHG reg8,mem \301\1\x86\110 8086,SM XCHG reg8,reg8 \1\x86\110 8086 XCHG reg16,mem \320\301\1\x87\110 8086,SM XCHG reg16,reg16 \320\1\x87\110 8086 XCHG reg32,mem \321\301\1\x87\110 386,SM XCHG reg32,reg32 \321\1\x87\110 386 +XCHG reg64,mem \321\301\1\x87\110 X64,SM +XCHG reg64,reg64 \321\1\x87\110 X64 XCHG mem,reg8 \300\1\x86\101 8086,SM XCHG reg8,reg8 \1\x86\101 8086 XCHG mem,reg16 \320\300\1\x87\101 8086,SM XCHG reg16,reg16 \320\1\x87\101 8086 XCHG mem,reg32 \321\300\1\x87\101 386,SM XCHG reg32,reg32 \321\1\x87\101 386 +XCHG mem,reg64 \321\300\1\x87\101 X64,SM +XCHG reg64,reg64 \321\1\x87\101 X64 XLATB void \1\xD7 8086 XLAT void \1\xD7 8086 XOR mem,reg8 \300\1\x30\101 8086,SM @@ -1128,22 +1352,30 @@ XOR mem,reg16 \320\300\1\x31\101 8086,SM XOR reg16,reg16 \320\1\x31\101 8086 XOR mem,reg32 \321\300\1\x31\101 386,SM XOR reg32,reg32 \321\1\x31\101 386 +XOR mem,reg64 \321\300\1\x31\101 X64,SM +XOR reg64,reg64 \321\1\x31\101 X64 XOR reg8,mem \301\1\x32\110 8086,SM XOR reg8,reg8 \1\x32\110 8086 XOR reg16,mem \320\301\1\x33\110 8086,SM XOR reg16,reg16 \320\1\x33\110 8086 XOR reg32,mem \321\301\1\x33\110 386,SM XOR reg32,reg32 \321\1\x33\110 386 +XOR reg64,mem \321\301\1\x33\110 X64,SM +XOR reg64,reg64 \321\1\x33\110 X64 XOR rm16,imm8 \320\300\1\x83\206\15 8086 XOR rm32,imm8 \321\300\1\x83\206\15 386 +XOR rm64,imm8 \321\300\1\x83\206\15 X64 XOR reg_al,imm \1\x34\21 8086,SM XOR reg_ax,sbyte \320\1\x83\206\15 8086,SM,ND XOR reg_ax,imm \320\1\x35\31 8086,SM XOR reg_eax,sbyte \321\1\x83\206\15 386,SM,ND XOR reg_eax,imm \321\1\x35\41 386,SM +XOR reg_rax,sbyte \321\1\x83\206\15 X64,SM,ND +XOR reg_rax,imm \321\1\x35\41 X64,SM XOR rm8,imm \300\1\x80\206\21 8086,SM XOR rm16,imm \320\300\134\1\x81\206\131 8086,SM XOR rm32,imm \321\300\144\1\x81\206\141 386,SM +XOR rm64,imm \321\300\144\1\x81\206\141 X64,SM XOR mem,imm8 \300\1\x80\206\21 8086,SM XOR mem,imm16 \320\300\134\1\x81\206\131 8086,SM XOR mem,imm32 \321\300\144\1\x81\206\141 386,SM @@ -1152,6 +1384,8 @@ CMOVcc reg16,mem \320\301\1\x0F\330\x40\110 P6,SM CMOVcc reg16,reg16 \320\1\x0F\330\x40\110 P6 CMOVcc reg32,mem \321\301\1\x0F\330\x40\110 P6,SM CMOVcc reg32,reg32 \321\1\x0F\330\x40\110 P6 +CMOVcc reg64,mem \321\301\1\x0F\330\x40\110 X64,SM +CMOVcc reg64,reg64 \321\1\x0F\330\x40\110 X64 Jcc imm|near \322\1\x0F\330\x80\64 386 Jcc imm16|near \320\1\x0F\330\x80\64 386 Jcc imm32|near \321\1\x0F\330\x80\64 386 @@ -1678,12 +1912,17 @@ MOVSLDUP xmmreg,xmmreg \3\xF3\x0F\x12\110 PRESCOTT,SSE3 VMCALL void \3\x0F\x01\xC1 VMX VMCLEAR mem \3\x66\x0F\xC7\206 VMX VMLAUNCH void \3\x0F\x01\xC2 VMX +VMLOAD void \3\x0F\x01\xDA X64,VMX +VMMCALL void \3\x0F\x01\xD9 X64,VMX VMPTRLD mem \2\x0F\xC7\206 VMX VMPTRST mem \2\x0F\xC7\207 VMX VMREAD mem,reg32 \2\x0F\x78\101 VMX VMREAD reg32,reg32 \2\x0F\x78\101 VMX VMRESUME void \3\x0F\x01\xC3 VMX +VMRUN void \3\x0F\x01\xD8 X64,VMX +VMSAVE void \3\x0F\x01\xDB X64,VMX VMWRITE reg32,mem \2\x0F\x79\110 VMX VMWRITE reg32,reg32 \2\x0F\x79\110 VMX VMXOFF void \3\x0F\x01\xC4 VMX VMXON mem \3\xF3\x0F\xC7\206 VMX + @@ -22,9 +22,9 @@ struct itemplate { int opcode; /* the token, passed from "parser.c" */ int operands; /* number of operands */ - long opd[3]; /* bit flags for operand types */ - const char *code; /* the code it assembles to */ - unsigned long flags; /* some flags */ + int32_t opd[3]; /* bit flags for operand types */ + const int8_t *code; /* the code it assembles to */ + uint32_t flags; /* some flags */ }; /* @@ -63,14 +63,16 @@ struct itemplate { #define IF_SM2 0x00000002UL /* size match first two operands */ #define IF_SB 0x00000004UL /* unsized operands can't be non-byte */ #define IF_SW 0x00000008UL /* unsized operands can't be non-word */ -#define IF_SD 0x00000010UL /* unsized operands can't be nondword */ -#define IF_AR0 0x00000020UL /* SB, SW, SD applies to argument 0 */ -#define IF_AR1 0x00000040UL /* SB, SW, SD applies to argument 1 */ -#define IF_AR2 0x00000060UL /* SB, SW, SD applies to argument 2 */ -#define IF_ARMASK 0x00000060UL /* mask for unsized argument spec */ +#define IF_SD 0x00000010UL /* unsized operands can't be non-dword */ +#define IF_SQ 0x00000020UL /* unsized operands can't be non-qword */ +#define IF_AR0 0x00000040UL /* SB, SW, SD applies to argument 0 */ +#define IF_AR1 0x00000080UL /* SB, SW, SD applies to argument 1 */ +#define IF_AR2 0x000000C0UL /* SB, SW, SD applies to argument 2 */ +#define IF_ARMASK 0x000000C0UL /* mask for unsized argument spec */ #define IF_PRIV 0x00000100UL /* it's a privileged instruction */ #define IF_SMM 0x00000200UL /* it's only valid in SMM */ #define IF_PROT 0x00000400UL /* it's protected mode only */ +#define IF_NOLONG 0x00000800UL /* it's not available in long mode */ #define IF_UNDOC 0x00001000UL /* it's an undocumented instruction */ #define IF_FPU 0x00002000UL /* it's an FPU instruction */ #define IF_MMX 0x00004000UL /* it's an MMX instruction */ @@ -93,6 +95,7 @@ struct itemplate { #define IF_KATMAI 0x07000000UL /* Katmai instructions */ #define IF_WILLAMETTE 0x08000000UL /* Willamette instructions */ #define IF_PRESCOTT 0x09000000UL /* Prescott instructions */ +#define IF_X64 0x0A000000UL /* x86-64 instructions */ #define IF_IA64 0x0F000000UL /* IA64 instructions */ #define IF_CYRIX 0x10000000UL /* Cyrix-specific instruction */ #define IF_AMD 0x20000000UL /* AMD-specific instruction */ @@ -69,6 +69,7 @@ if ( !defined($output) || $output eq 'a' ) { print A "/* This file auto-generated from insns.dat by insns.pl" . " - don't edit it */\n\n"; + print A "#include \<inttypes.h\>\n\n"; print A "#include \"nasm.h\"\n"; print A "#include \"insns.h\"\n"; print A "\n"; @@ -97,6 +98,7 @@ if ( !defined($output) || $output eq 'd' ) { print D "/* This file auto-generated from insns.dat by insns.pl" . " - don't edit it */\n\n"; + print D "#include \<inttypes.h\>\n\n"; print D "#include \"nasm.h\"\n"; print D "#include \"insns.h\"\n"; print D "\n"; @@ -161,8 +163,9 @@ if ( !defined($output) || $output eq 'n' ) { print N "/* This file is auto-generated from insns.dat by insns.pl" . " - don't edit it */\n\n"; print N "/* This file in included by names.c */\n\n"; + print N "#include \<inttypes.h\>\n\n"; - print N "static const char *insn_names[] = {"; + print N "static const int8_t *insn_names[] = {"; $first = 1; foreach $i (@opcodes) { print N "," if ( !$first ); @@ -173,7 +176,7 @@ if ( !defined($output) || $output eq 'n' ) { } print N "\n};\n\n"; print N "/* Conditional instructions */\n"; - print N "static const char *icn[] = {"; + print N "static const int8_t *icn[] = {"; $first = 1; foreach $i (@opcodes_cc) { print N "," if ( !$first ); @@ -9,6 +9,8 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <inttypes.h> + #include "nasm.h" #include "nasmlib.h" @@ -55,12 +57,12 @@ union label { /* actual label structures */ struct { - long segment, offset; - char *label, *special; + int32_t segment, offset; + int8_t *label, *special; int is_global, is_norm; } defn; struct { - long movingon, dummy; + int32_t movingon, dummy; union label *next; } admin; }; @@ -68,7 +70,7 @@ union label { /* actual label structures */ struct permts { /* permanent text storage */ struct permts *next; /* for the linked list */ int size, usage; /* size and used space in ... */ - char data[PERMTS_SIZE]; /* ... the data block itself */ + int8_t data[PERMTS_SIZE]; /* ... the data block itself */ }; extern int global_offset_changed; /* defined in nasm.c */ @@ -79,24 +81,24 @@ static struct permts *perm_head; /* start of perm. text storage */ static struct permts *perm_tail; /* end of perm. text storage */ static void init_block(union label *blk); -static char *perm_copy(char *string1, char *string2); +static int8_t *perm_copy(int8_t *string1, int8_t *string2); -static char *prevlabel; +static int8_t *prevlabel; -static int initialised = FALSE; +static int initialized = FALSE; -char lprefix[PREFIX_MAX] = { 0 }; -char lpostfix[PREFIX_MAX] = { 0 }; +int8_t lprefix[PREFIX_MAX] = { 0 }; +int8_t lpostfix[PREFIX_MAX] = { 0 }; /* * Internal routine: finds the `union label' corresponding to the * given label name. Creates a new one, if it isn't found, and if * `create' is TRUE. */ -static union label *find_label(char *label, int create) +static union label *find_label(int8_t *label, int create) { int hash = 0; - char *p, *prev; + int8_t *p, *prev; int prevlen; union label *lptr; @@ -144,11 +146,11 @@ static union label *find_label(char *label, int create) return NULL; } -int lookup_label(char *label, long *segment, long *offset) +int lookup_label(int8_t *label, int32_t *segment, int32_t *offset) { union label *lptr; - if (!initialised) + if (!initialized) return 0; lptr = find_label(label, 0); @@ -160,11 +162,11 @@ int lookup_label(char *label, long *segment, long *offset) return 0; } -int is_extern(char *label) +int is_extern(int8_t *label) { union label *lptr; - if (!initialised) + if (!initialized) return 0; lptr = find_label(label, 0); @@ -174,7 +176,7 @@ int is_extern(char *label) return 0; } -void redefine_label(char *label, long segment, long offset, char *special, +void redefine_label(int8_t *label, int32_t segment, int32_t offset, int8_t *special, int is_norm, int isextrn, struct ofmt *ofmt, efunc error) { @@ -215,12 +217,12 @@ void redefine_label(char *label, long segment, long offset, char *special, if (pass0 == 1) { exi = !!(lptr->defn.is_global & GLOBAL_BIT); if (exi) { - char *xsymbol; + int8_t *xsymbol; int slen; slen = strlen(lprefix); slen += strlen(lptr->defn.label); slen += strlen(lpostfix); - slen++; /* room for that null char */ + slen++; /* room for that null int8_t */ xsymbol = nasm_malloc(slen); snprintf(xsymbol, slen, "%s%s%s", lprefix, lptr->defn.label, lpostfix); @@ -247,7 +249,7 @@ void redefine_label(char *label, long segment, long offset, char *special, /* if (pass0 == 1) */ } -void define_label(char *label, long segment, long offset, char *special, +void define_label(int8_t *label, int32_t segment, int32_t offset, int8_t *special, int is_norm, int isextrn, struct ofmt *ofmt, efunc error) { union label *lptr; @@ -283,7 +285,7 @@ void define_label(char *label, long segment, long offset, char *special, if (pass0 == 1 || (!is_norm && !isextrn && (segment & 1))) { exi = !!(lptr->defn.is_global & GLOBAL_BIT); if (exi) { - char *xsymbol; + int8_t *xsymbol; int slen; slen = strlen(lprefix); slen += strlen(lptr->defn.label); @@ -314,7 +316,7 @@ void define_label(char *label, long segment, long offset, char *special, } /* if (pass0 == 1) */ } -void define_common(char *label, long segment, long size, char *special, +void define_common(int8_t *label, int32_t segment, int32_t size, int8_t *special, struct ofmt *ofmt, efunc error) { union label *lptr; @@ -342,7 +344,7 @@ void define_common(char *label, long segment, long size, char *special, special); } -void declare_as_global(char *label, char *special, efunc error) +void declare_as_global(int8_t *label, int8_t *special, efunc error) { union label *lptr; @@ -392,7 +394,7 @@ int init_labels(void) prevlabel = ""; - initialised = TRUE; + initialized = TRUE; return 0; } @@ -401,7 +403,7 @@ void cleanup_labels(void) { int i; - initialised = FALSE; + initialized = FALSE; for (i = 0; i < LABEL_HASHES; i++) { union label *lptr, *lhold; @@ -434,9 +436,9 @@ static void init_block(union label *blk) blk[LABEL_BLOCK - 1].admin.next = NULL; } -static char *perm_copy(char *string1, char *string2) +static int8_t *perm_copy(int8_t *string1, int8_t *string2) { - char *p, *q; + int8_t *p, *q; int len = strlen(string1) + strlen(string2) + 1; if (perm_tail->size - perm_tail->usage < len) { @@ -6,19 +6,19 @@ * distributed in the NASM archive. */ -extern char lprefix[PREFIX_MAX]; -extern char lpostfix[PREFIX_MAX]; +extern int8_t lprefix[PREFIX_MAX]; +extern int8_t lpostfix[PREFIX_MAX]; -int lookup_label(char *label, long *segment, long *offset); -int is_extern(char *label); -void define_label(char *label, long segment, long offset, char *special, +int lookup_label(int8_t *label, int32_t *segment, int32_t *offset); +int is_extern(int8_t *label); +void define_label(int8_t *label, int32_t segment, int32_t offset, int8_t *special, int is_norm, int isextrn, struct ofmt *ofmt, efunc error); -void redefine_label(char *label, long segment, long offset, char *special, +void redefine_label(int8_t *label, int32_t segment, int32_t offset, int8_t *special, int is_norm, int isextrn, struct ofmt *ofmt, efunc error); -void define_common(char *label, long segment, long size, char *special, +void define_common(int8_t *label, int32_t segment, int32_t size, int8_t *special, struct ofmt *ofmt, efunc error); -void declare_as_global(char *label, char *special, efunc error); +void declare_as_global(int8_t *label, int8_t *special, efunc error); int init_labels(void); void cleanup_labels(void); diff --git a/lcc/lin-aout.c b/lcc/lin-aout.c index e4ac48f..9685e57 100644 --- a/lcc/lin-aout.c +++ b/lcc/lin-aout.c @@ -8,31 +8,31 @@ #define NASMPATH "/usr/local/bin/nasm" -char *cpp[] = { LCCDIR "cpp", "-D__STDC__=1", +int8_t *cpp[] = { LCCDIR "cpp", "-D__STDC__=1", "-Di386", "-D__i386", "-D__i386__", "-Dlinux", "-D__linux", "-D__linux__", "-Dunix", "-D__unix", "-D__unix__", "$1", "$2", "$3", 0 }; -char *include[] = { "-I" LCCDIR "include", "-I/usr/local/include", +int8_t *include[] = { "-I" LCCDIR "include", "-I/usr/local/include", "-I/usr/include", 0 }; -char *com[] = { LCCDIR "rcc", "-target=x86/nasm", +int8_t *com[] = { LCCDIR "rcc", "-target=x86/nasm", "$1", "$2", "$3", 0 }; -char *as[] = { NASMPATH, "-a", "-faout", "-o", "$3", "$1", "$2", 0 }; -char *ld[] = { "/usr/bin/ld", "-m", "i386linux", +int8_t *as[] = { NASMPATH, "-a", "-faout", "-o", "$3", "$1", "$2", 0 }; +int8_t *ld[] = { "/usr/bin/ld", "-m", "i386linux", "-L/usr/i486-linuxaout/lib", "-o", "$3", "$1", "/usr/i486-linuxaout/lib/crt0.o", "$2", "", "-lc", 0 }; -static char *bbexit = LCCDIR "bbexit.o"; +static int8_t *bbexit = LCCDIR "bbexit.o"; -extern char *concat(char *, char *); -extern int access(const char *, int); +extern int8_t *concat(int8_t *, int8_t *); +extern int access(const int8_t *, int); -int option(char *arg) +int option(int8_t *arg) { if (strncmp(arg, "-lccdir=", 8) == 0) { cpp[0] = concat(&arg[8], "/cpp"); diff --git a/lcc/lin-elf.c b/lcc/lin-elf.c index 693309f..2f15de3 100644 --- a/lcc/lin-elf.c +++ b/lcc/lin-elf.c @@ -8,19 +8,19 @@ #define NASMPATH "/usr/local/bin/nasm" -char *cpp[] = { LCCDIR "cpp", "-D__STDC__=1", +int8_t *cpp[] = { LCCDIR "cpp", "-D__STDC__=1", "-D__ELF__", "-Di386", "-D__i386", "-D__i386__", "-Dlinux", "-D__linux", "-D__linux__", "$1", "$2", "$3", 0 }; -char *include[] = { "-I" LCCDIR "include", "-I/usr/local/include", +int8_t *include[] = { "-I" LCCDIR "include", "-I/usr/local/include", "-I/usr/include", 0 }; -char *com[] = { LCCDIR "rcc", "-target=x86/nasm", +int8_t *com[] = { LCCDIR "rcc", "-target=x86/nasm", "$1", "$2", "$3", 0 }; -char *as[] = { NASMPATH, "-a", "-felf", "-o", "$3", "$1", "$2", 0 }; -char *ld[] = { "/usr/bin/ld", "-m", "elf_i386", +int8_t *as[] = { NASMPATH, "-a", "-felf", "-o", "$3", "$1", "$2", 0 }; +int8_t *ld[] = { "/usr/bin/ld", "-m", "elf_i386", "-dynamic-linker", "/lib/ld-linux.so.1", "-L/usr/i486-linux/lib", "-o", "$3", "$1", @@ -28,12 +28,12 @@ char *ld[] = { "/usr/bin/ld", "-m", "elf_i386", "$2", "", "-lc", "", "/usr/lib/crtend.o", "/usr/lib/crtn.o", 0 }; -static char *bbexit = LCCDIR "bbexit.o"; +static int8_t *bbexit = LCCDIR "bbexit.o"; -extern char *concat(char *, char *); -extern int access(const char *, int); +extern int8_t *concat(int8_t *, int8_t *); +extern int access(const int8_t *, int); -int option(char *arg) +int option(int8_t *arg) { if (strncmp(arg, "-lccdir=", 8) == 0) { cpp[0] = concat(&arg[8], "/cpp"); @@ -13,6 +13,7 @@ #include <stddef.h> #include <string.h> #include <ctype.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" @@ -30,19 +31,19 @@ static struct MacroInhibit { int inhibiting; } *mistack; -static char xdigit[] = "0123456789ABCDEF"; +static int8_t xdigit[] = "0123456789ABCDEF"; #define HEX(a,b) (*(a)=xdigit[((b)>>4)&15],(a)[1]=xdigit[(b)&15]); -static char listline[LIST_MAX_LEN]; +static int8_t listline[LIST_MAX_LEN]; static int listlinep; -static char listdata[2 * LIST_INDENT]; /* we need less than that actually */ -static long listoffset; +static int8_t listdata[2 * LIST_INDENT]; /* we need less than that actually */ +static int32_t listoffset; -static long listlineno; +static int32_t listlineno; -static long listp; +static int32_t listp; static int suppress; /* for INCBIN & TIMES special cases */ @@ -77,7 +78,7 @@ static void list_emit(void) listdata[0] = '\0'; } -static void list_init(char *fname, efunc error) +static void list_init(int8_t *fname, efunc error) { listfp = fopen(fname, "w"); if (!listfp) { @@ -111,7 +112,7 @@ static void list_cleanup(void) fclose(listfp); } -static void list_out(long offset, char *str) +static void list_out(int32_t offset, int8_t *str) { if (strlen(listdata) + strlen(str) > LIST_HEXBIT) { strcat(listdata, "-"); @@ -122,9 +123,9 @@ static void list_out(long offset, char *str) strcat(listdata, str); } -static void list_output(long offset, const void *data, unsigned long type) +static void list_output(int32_t offset, const void *data, uint32_t type) { - unsigned long typ, size; + uint32_t typ, size; if (!listp || suppress || user_nolist) /* fbk - 9/2/00 */ return; @@ -132,9 +133,10 @@ static void list_output(long offset, const void *data, unsigned long type) typ = type & OUT_TYPMASK; size = type & OUT_SIZMASK; + if (typ == OUT_RAWDATA) { - unsigned char const *p = data; - char q[3]; + uint8_t const *p = data; + int8_t q[3]; while (size--) { HEX(q, *p); q[2] = '\0'; @@ -142,9 +144,9 @@ static void list_output(long offset, const void *data, unsigned long type) p++; } } else if (typ == OUT_ADDRESS) { - unsigned long d = *(long *)data; - char q[11]; - unsigned char p[4], *r = p; + uint64_t d = *(int64_t *)data; + int8_t q[20]; + uint8_t p[8], *r = p; if (size == 4) { q[0] = '['; q[9] = ']'; @@ -155,6 +157,20 @@ static void list_output(long offset, const void *data, unsigned long type) HEX(q + 5, p[2]); HEX(q + 7, p[3]); list_out(offset, q); + } else if (size == 8) { + q[0] = '['; + q[17] = ']'; + q[18] = '\0'; + WRITEDLONG(r, d); + HEX(q + 1, p[0]); + HEX(q + 3, p[1]); + HEX(q + 5, p[2]); + HEX(q + 7, p[3]); + HEX(q + 9, p[4]); + HEX(q + 11, p[5]); + HEX(q + 13, p[6]); + HEX(q + 15, p[7]); + list_out(offset, q); } else { q[0] = '['; q[5] = ']'; @@ -165,9 +181,9 @@ static void list_output(long offset, const void *data, unsigned long type) list_out(offset, q); } } else if (typ == OUT_REL2ADR) { - unsigned long d = *(long *)data; - char q[11]; - unsigned char p[4], *r = p; + uint32_t d = *(int32_t *)data; + int8_t q[11]; + uint8_t p[4], *r = p; q[0] = '('; q[5] = ')'; q[6] = '\0'; @@ -176,9 +192,9 @@ static void list_output(long offset, const void *data, unsigned long type) HEX(q + 3, p[1]); list_out(offset, q); } else if (typ == OUT_REL4ADR) { - unsigned long d = *(long *)data; - char q[11]; - unsigned char p[4], *r = p; + uint32_t d = *(int32_t *)data; + int8_t q[11]; + uint8_t p[4], *r = p; q[0] = '('; q[9] = ')'; q[10] = '\0'; @@ -189,13 +205,13 @@ static void list_output(long offset, const void *data, unsigned long type) HEX(q + 7, p[3]); list_out(offset, q); } else if (typ == OUT_RESERVE) { - char q[20]; + int8_t q[20]; snprintf(q, sizeof(q), "<res %08lX>", size); list_out(offset, q); } } -static void list_line(int type, char *line) +static void list_line(int type, int8_t *line) { if (!listp) return; @@ -19,7 +19,7 @@ undef $tasm_count; open(OUTPUT,">macros.c") or die "unable to open macros.c\n"; print OUTPUT "/* This file auto-generated from standard.mac by macros.pl" . -" - don't edit it */\n\n#include <stddef.h>\n\nstatic const char *stdmac[] = {\n"; +" - don't edit it */\n\n#include <stddef.h>\n#include <inttypes.h>\n\nstatic const int8_t *stdmac[] = {\n"; foreach $fname ( @ARGV ) { open(INPUT,$fname) or die "unable to open $fname\n"; @@ -7,7 +7,7 @@ * distributed in the NASM archive. */ -static const char *conditions[] = { /* condition code names */ +static const int8_t *conditions[] = { /* condition code names */ "a", "ae", "b", "be", "c", "e", "g", "ge", "l", "le", "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no", "np", "ns", "nz", "o", "p", "pe", "po", "s", "z" @@ -11,6 +11,7 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" @@ -28,15 +29,15 @@ struct forwrefinfo { /* info held on forward refs. */ int operand; }; -static int get_bits(char *value); -static unsigned long get_cpu(char *cpu_str); -static void parse_cmdline(int, char **); -static void assemble_file(char *); -static int getkw(char **directive, char **value); +static int get_bits(int8_t *value); +static uint32_t get_cpu(int8_t *cpu_str); +static void parse_cmdline(int, int8_t **); +static void assemble_file(int8_t *); +static int getkw(int8_t **directive, int8_t **value); static void register_output_formats(void); -static void report_error_gnu(int severity, const char *fmt, ...); -static void report_error_vc(int severity, const char *fmt, ...); -static void report_error_common(int severity, const char *fmt, +static void report_error_gnu(int severity, const int8_t *fmt, ...); +static void report_error_vc(int severity, const int8_t *fmt, ...); +static void report_error_common(int severity, const int8_t *fmt, va_list args); static int is_suppressed_warning(int severity); static void usage(void); @@ -45,10 +46,11 @@ static efunc report_error; static int using_debug_info, opt_verbose_info; int tasm_compatible_mode = FALSE; int pass0; +int maxbits = 0; -static char inname[FILENAME_MAX]; -static char outname[FILENAME_MAX]; -static char listname[FILENAME_MAX]; +static int8_t inname[FILENAME_MAX]; +static int8_t outname[FILENAME_MAX]; +static int8_t listname[FILENAME_MAX]; static int globallineno; /* for forward-reference tracking */ /* static int pass = 0; */ static struct ofmt *ofmt = NULL; @@ -58,14 +60,14 @@ static FILE *error_file; /* Where to write error messages */ static FILE *ofile = NULL; int optimizing = -1; /* number of optimization passes to take */ static int sb, cmd_sb = 16; /* by default */ -static unsigned long cmd_cpu = IF_PLEVEL; /* highest level by default */ -static unsigned long cpu = IF_PLEVEL; /* passed to insn_size & assemble.c */ +static uint32_t cmd_cpu = IF_PLEVEL; /* highest level by default */ +static uint32_t cpu = IF_PLEVEL; /* passed to insn_size & assemble.c */ int global_offset_changed; /* referenced in labels.c */ static loc_t location; int in_abs_seg; /* Flag we are in ABSOLUTE seg */ -long abs_seg; /* ABSOLUTE segment basis */ -long abs_offset; /* ABSOLUTE offset */ +int32_t abs_seg; /* ABSOLUTE segment basis */ +int32_t abs_offset; /* ABSOLUTE offset */ static struct RAA *offsets; @@ -84,7 +86,7 @@ static enum op_type operating_mode; * Which of the suppressible warnings are suppressed. Entry zero * doesn't do anything. Initial defaults are given here. */ -static char suppressed[1 + ERR_WARN_MAX] = { +static int8_t suppressed[1 + ERR_WARN_MAX] = { 0, TRUE, TRUE, TRUE, FALSE, TRUE }; @@ -92,7 +94,7 @@ static char suppressed[1 + ERR_WARN_MAX] = { * The option names for the suppressible warnings. As before, entry * zero does nothing. */ -static const char *suppressed_names[1 + ERR_WARN_MAX] = { +static const int8_t *suppressed_names[1 + ERR_WARN_MAX] = { NULL, "macro-params", "macro-selfref", "orphan-labels", "number-overflow", "gnu-elf-extensions" @@ -102,7 +104,7 @@ static const char *suppressed_names[1 + ERR_WARN_MAX] = { * The explanations for the suppressible warnings. As before, entry * zero does nothing. */ -static const char *suppressed_what[1 + ERR_WARN_MAX] = { +static const int8_t *suppressed_what[1 + ERR_WARN_MAX] = { NULL, "macro calls with wrong no. of params", "cyclic macro self-references", @@ -117,8 +119,8 @@ static const char *suppressed_what[1 + ERR_WARN_MAX] = { * not preprocess their source file. */ -static void no_pp_reset(char *, int, efunc, evalfunc, ListGen *); -static char *no_pp_getline(void); +static void no_pp_reset(int8_t *, int, efunc, evalfunc, ListGen *); +static int8_t *no_pp_getline(void); static void no_pp_cleanup(int); static Preproc no_pp = { no_pp_reset, @@ -138,7 +140,7 @@ static int want_usage; static int terminate_after_phase; int user_nolist = 0; /* fbk 9/2/00 */ -static void nasm_fputs(const char *line, FILE * outfile) +static void nasm_fputs(const int8_t *line, FILE * outfile) { if (outfile) { fputs(line, outfile); @@ -147,7 +149,7 @@ static void nasm_fputs(const char *line, FILE * outfile) puts(line); } -int main(int argc, char **argv) +int main(int argc, int8_t **argv) { pass0 = 1; want_usage = terminate_after_phase = FALSE; @@ -155,7 +157,7 @@ int main(int argc, char **argv) nasm_set_malloc_error(report_error); offsets = raa_init(); - forwrefs = saa_init((long)sizeof(struct forwrefinfo)); + forwrefs = saa_init((int32_t)sizeof(struct forwrefinfo)); preproc = &nasmpp; operating_mode = op_normal; @@ -185,7 +187,7 @@ int main(int argc, char **argv) /* define some macros dependent of command-line */ { - char temp[64]; + int8_t temp[64]; snprintf(temp, sizeof(temp), "__OUTPUT_FORMAT__=%s\n", ofmt->shortname); pp_pre_define(temp); @@ -194,7 +196,7 @@ int main(int argc, char **argv) switch (operating_mode) { case op_depend: { - char *line; + int8_t *line; preproc->reset(inname, 0, report_error, evaluate, &nasmlist); if (outname[0] == '\0') ofmt->filename(inname, outname, report_error); @@ -209,9 +211,9 @@ int main(int argc, char **argv) case op_preprocess: { - char *line; - char *file_name = NULL; - long prior_linnum = 0; + int8_t *line; + int8_t *file_name = NULL; + int32_t prior_linnum = 0; int lineinc = 0; if (*outname) { @@ -231,7 +233,7 @@ int main(int argc, char **argv) /* * We generate %line directives if needed for later programs */ - long linnum = prior_linnum += lineinc; + int32_t linnum = prior_linnum += lineinc; int altline = src_get(&linnum, &file_name); if (altline) { if (altline == 1 && lineinc == 1) @@ -320,7 +322,7 @@ int main(int argc, char **argv) * Get a parameter for a command line option. * First arg must be in the form of e.g. -f... */ -static char *get_param(char *p, char *q, int *advance) +static int8_t *get_param(int8_t *p, int8_t *q, int *advance) { *advance = 0; if (p[2]) { /* the parameter's in the option */ @@ -339,7 +341,7 @@ static char *get_param(char *p, char *q, int *advance) } struct textargs { - const char *label; + const int8_t *label; int value; }; @@ -352,9 +354,9 @@ struct textargs textopts[] = { }; int stopoptions = 0; -static int process_arg(char *p, char *q) +static int process_arg(int8_t *p, int8_t *q) { - char *param; + int8_t *param; int i, advance = 0; if (!p || !p[0]) @@ -513,7 +515,7 @@ static int process_arg(char *p, char *q) case 'r': case 'v': { - const char *nasm_version_string = + const int8_t *nasm_version_string = "NASM version " NASM_VER " compiled on " __DATE__ #ifdef DEBUG " with -DDEBUG" @@ -620,7 +622,7 @@ static int process_arg(char *p, char *q) static void process_respfile(FILE * rfile) { - char *buffer, *p, *q, *prevarg; + int8_t *buffer, *p, *q, *prevarg; int bufsize, prevargsize; bufsize = prevargsize = ARG_BUF_DELTA; @@ -683,10 +685,10 @@ static void process_respfile(FILE * rfile) * argv array. Used by the environment variable and response file * processing. */ -static void process_args(char *args) +static void process_args(int8_t *args) { - char *p, *q, *arg, *prevarg; - char separator = ' '; + int8_t *p, *q, *arg, *prevarg; + int8_t separator = ' '; p = args; if (*p && *p != '-') @@ -707,10 +709,10 @@ static void process_args(char *args) process_arg(arg, NULL); } -static void parse_cmdline(int argc, char **argv) +static void parse_cmdline(int argc, int8_t **argv) { FILE *rfile; - char *envreal, *envcopy = NULL, *p, *arg; + int8_t *envreal, *envcopy = NULL, *p, *arg; *inname = *outname = *listname = '\0'; @@ -738,7 +740,7 @@ static void parse_cmdline(int argc, char **argv) * different to the -@resp file processing below for regular * NASM. */ - char *str = malloc(2048); + int8_t *str = malloc(2048); FILE *f = fopen(&argv[0][1], "r"); if (!str) { printf("out of memory"); @@ -773,12 +775,12 @@ static void parse_cmdline(int argc, char **argv) "no input file specified"); } -static void assemble_file(char *fname) +static void assemble_file(int8_t *fname) { - char *directive, *value, *p, *q, *special, *line, debugid[80]; + int8_t *directive, *value, *p, *q, *special, *line, debugid[80]; insn output_ins; int i, rn_error, validid; - long seg, offs; + int32_t seg, offs; struct tokenval tokval; expr *e; int pass, pass_max; @@ -800,7 +802,7 @@ static void assemble_file(char *fname) def_label = pass > 1 ? redefine_label : define_label; - sb = cmd_sb; /* set 'bits' to command line default */ + globalbits = sb = cmd_sb; /* set 'bits' to command line default */ cpu = cmd_cpu; if (pass0 == 2) { if (*listname) @@ -809,6 +811,7 @@ static void assemble_file(char *fname) in_abs_seg = FALSE; global_offset_changed = FALSE; /* set by redefine_label */ location.segment = ofmt->section(NULL, pass2, &sb); + globalbits = sb; if (pass > 1) { saa_rewind(forwrefs); forwref = saa_rstruct(forwrefs); @@ -833,7 +836,7 @@ static void assemble_file(char *fname) seg = ofmt->section(value, pass2, &sb); if (seg == NO_SEG) { report_error(pass1 == 1 ? ERR_NONFATAL : ERR_PANIC, - "segment name `%s' not recognised", + "segment name `%s' not recognized", value); } else { in_abs_seg = FALSE; @@ -883,7 +886,7 @@ static void assemble_file(char *fname) } /* else pass0 == 1 */ break; case 3: /* [BITS bits] */ - sb = get_bits(value); + globalbits = sb = get_bits(value); break; case 4: /* [GLOBAL symbol:special] */ if (*value == '$') @@ -938,7 +941,7 @@ static void assemble_file(char *fname) break; } if (*p) { - long size; + int64_t size; while (*p && isspace(*p)) *p++ = '\0'; @@ -1216,14 +1219,14 @@ static void assemble_file(char *fname) if (pass1 == 1) { - long l = insn_size(location.segment, offs, sb, cpu, + int32_t l = insn_size(location.segment, offs, sb, cpu, &output_ins, report_error); /* if (using_debug_info) && output_ins.opcode != -1) */ if (using_debug_info) { /* fbk 03/25/01 */ /* this is done here so we can do debug type info */ - long typeinfo = + int32_t typeinfo = TYS_ELEMENTS(output_ins.operands); switch (output_ins.opcode) { case I_RESB: @@ -1333,9 +1336,9 @@ static void assemble_file(char *fname) #endif } /* exit from assemble_file (...) */ -static int getkw(char **directive, char **value) +static int getkw(int8_t **directive, int8_t **value) { - char *p, *q, *buf; + int8_t *p, *q, *buf; buf = *directive; @@ -1419,7 +1422,7 @@ static int getkw(char **directive, char **value) * @param severity the severity of the warning or error * @param fmt the printf style format string */ -static void report_error_gnu(int severity, const char *fmt, ...) +static void report_error_gnu(int severity, const int8_t *fmt, ...) { va_list ap; @@ -1429,8 +1432,8 @@ static void report_error_gnu(int severity, const char *fmt, ...) if (severity & ERR_NOFILE) fputs("nasm: ", error_file); else { - char *currentfile = NULL; - long lineno = 0; + int8_t *currentfile = NULL; + int32_t lineno = 0; src_get(&lineno, ¤tfile); fprintf(error_file, "%s:%ld: ", currentfile, lineno); nasm_free(currentfile); @@ -1455,7 +1458,7 @@ static void report_error_gnu(int severity, const char *fmt, ...) * @param severity the severity of the warning or error * @param fmt the printf style format string */ -static void report_error_vc(int severity, const char *fmt, ...) +static void report_error_vc(int severity, const int8_t *fmt, ...) { va_list ap; @@ -1465,8 +1468,8 @@ static void report_error_vc(int severity, const char *fmt, ...) if (severity & ERR_NOFILE) fputs("nasm: ", error_file); else { - char *currentfile = NULL; - long lineno = 0; + int8_t *currentfile = NULL; + int32_t lineno = 0; src_get(&lineno, ¤tfile); fprintf(error_file, "%s(%ld) : ", currentfile, lineno); nasm_free(currentfile); @@ -1508,7 +1511,7 @@ static int is_suppressed_warning(int severity) * @param severity the severity of the warning or error * @param fmt the printf style format string */ -static void report_error_common(int severity, const char *fmt, +static void report_error_common(int severity, const int8_t *fmt, va_list args) { switch (severity & ERR_MASK) { @@ -1576,9 +1579,9 @@ static void register_output_formats(void) static FILE *no_pp_fp; static efunc no_pp_err; static ListGen *no_pp_list; -static long no_pp_lineinc; +static int32_t no_pp_lineinc; -static void no_pp_reset(char *file, int pass, efunc error, evalfunc eval, +static void no_pp_reset(int8_t *file, int pass, efunc error, evalfunc eval, ListGen * listgen) { src_set_fname(nasm_strdup(file)); @@ -1594,9 +1597,9 @@ static void no_pp_reset(char *file, int pass, efunc error, evalfunc eval, (void)eval; /* placate compilers */ } -static char *no_pp_getline(void) +static int8_t *no_pp_getline(void) { - char *buffer, *p, *q; + int8_t *buffer, *p, *q; int bufsize; bufsize = BUF_DELTA; @@ -1634,9 +1637,9 @@ static char *no_pp_getline(void) buffer[strcspn(buffer, "\r\n\032")] = '\0'; if (!strncmp(buffer, "%line", 5)) { - long ln; + int32_t ln; int li; - char *nm = nasm_malloc(strlen(buffer)); + int8_t *nm = nasm_malloc(strlen(buffer)); if (sscanf(buffer + 5, "%ld+%d %s", &ln, &li, nm) == 3) { nasm_free(src_set_fname(nm)); src_set_linnum(ln); @@ -1658,7 +1661,7 @@ static void no_pp_cleanup(int pass) fclose(no_pp_fp); } -static unsigned long get_cpu(char *value) +static uint32_t get_cpu(int8_t *value) { if (!strcmp(value, "8086")) @@ -1684,6 +1687,9 @@ static unsigned long get_cpu(char *value) return IF_WILLAMETTE; if (!nasm_stricmp(value, "prescott")) return IF_PRESCOTT; + if (!nasm_stricmp(value, "x64") || + !nasm_stricmp(value, "x86-64")) + return IF_X64; if (!nasm_stricmp(value, "ia64") || !nasm_stricmp(value, "ia-64") || !nasm_stricmp(value, "itanium") || @@ -1696,7 +1702,7 @@ static unsigned long get_cpu(char *value) return IF_PLEVEL; /* the maximum level */ } -static int get_bits(char *value) +static int get_bits(int8_t *value) { int i; @@ -1708,9 +1714,21 @@ static int get_bits(char *value) "cannot specify 32-bit segment on processor below a 386"); i = 16; } + } else if (i == 64) { + if (cpu < IF_X64) { + report_error(ERR_NONFATAL, + "cannot specify 64-bit segment on processor below an x86-64"); + i = 16; + } + if (i != maxbits) { + report_error(ERR_NONFATAL, + "%s output format does not support 64-bit code", + ofmt->shortname); + i = 16; + } } else { report_error(pass0 < 2 ? ERR_NONFATAL : ERR_FATAL, - "`%s' is not a valid segment size; must be 16 or 32", + "`%s' is not a valid segment size; must be 16, 32 or 64", value); i = 16; } @@ -66,7 +66,7 @@ struct ofmt; /* * An error reporting function should look like this. */ -typedef void (*efunc) (int severity, const char *fmt, ...); +typedef void (*efunc) (int severity, const int8_t *fmt, ...); /* * These are the error severity codes which get passed as the first @@ -108,7 +108,7 @@ typedef void (*efunc) (int severity, const char *fmt, ...); /* * A label-lookup function should look like this. */ -typedef int (*lfunc) (char *label, long *segment, long *offset); +typedef int (*lfunc) (int8_t *label, int32_t *segment, int32_t *offset); /* * And a label-definition function like this. The boolean parameter @@ -116,8 +116,8 @@ typedef int (*lfunc) (char *label, long *segment, long *offset); * should affect the local-label system), or something odder like * an EQU or a segment-base symbol, which shouldn't. */ -typedef void (*ldfunc) (char *label, long segment, long offset, - char *special, int is_norm, int isextrn, +typedef void (*ldfunc) (int8_t *label, int32_t segment, int32_t offset, + int8_t *special, int is_norm, int isextrn, struct ofmt * ofmt, efunc error); /* @@ -125,12 +125,12 @@ typedef void (*ldfunc) (char *label, long segment, long offset, */ typedef struct { /* - * Called to initialise the listing file generator. Before this + * Called to initialize the listing file generator. Before this * is called, the other routines will silently do nothing when - * called. The `char *' parameter is the file name to write the + * called. The `int8_t *' parameter is the file name to write the * listing to. */ - void (*init) (char *, efunc); + void (*init) (int8_t *, efunc); /* * Called to clear stuff up and close the listing file. @@ -148,7 +148,7 @@ typedef struct { * work with when doing things like uplevel(LIST_TIMES) or * uplevel(LIST_INCBIN). */ - void (*output) (long, const void *, unsigned long); + void (*output) (int32_t, const void *, uint32_t); /* * Called to send a text line to the listing generator. The @@ -156,7 +156,7 @@ typedef struct { * whether the line came directly from an input file or is the * result of a multi-line macro expansion. */ - void (*line) (int, char *); + void (*line) (int, int8_t *); /* * Called to change one of the various levelled mechanisms in @@ -190,8 +190,8 @@ typedef struct { */ struct tokenval { int t_type; - long t_integer, t_inttwo; - char *t_charptr; + int64_t t_integer, t_inttwo; + int8_t *t_charptr; }; typedef int (*scanner) (void *private_data, struct tokenval * tv); @@ -206,7 +206,7 @@ enum { /* token types, other than chars */ TOKEN_ID = 256, TOKEN_NUM, TOKEN_REG, TOKEN_INSN, /* major token types */ TOKEN_ERRNUM, /* numeric constant with error in */ TOKEN_HERE, TOKEN_BASE, /* $ and $$ */ - TOKEN_SPECIAL, /* BYTE, WORD, DWORD, FAR, NEAR, etc */ + TOKEN_SPECIAL, /* BYTE, WORD, DWORD, QWORD, FAR, NEAR, etc */ TOKEN_PREFIX, /* A32, O16, LOCK, REPNZ, TIMES, etc */ TOKEN_SHL, TOKEN_SHR, /* << and >> */ TOKEN_SDIV, TOKEN_SMOD, /* // and %% */ @@ -217,8 +217,8 @@ enum { /* token types, other than chars */ }; typedef struct { - long segment; - long offset; + int32_t segment; + int32_t offset; int known; } loc_t; @@ -235,8 +235,8 @@ typedef struct { * `value' field of zero is insignificant. */ typedef struct { - long type; /* a register, or EXPR_xxx */ - long value; /* must be >= 32 bits */ + int32_t type; /* a register, or EXPR_xxx */ + int64_t value; /* must be >= 32 bits */ } expr; /* @@ -245,7 +245,7 @@ typedef struct { * `operand' structure. */ struct eval_hints { - int base; + int64_t base; int type; }; @@ -300,14 +300,14 @@ typedef struct { * of the pass, an error reporting function, an evaluator * function, and a listing generator to talk to. */ - void (*reset) (char *, int, efunc, evalfunc, ListGen *); + void (*reset) (int8_t *, int, efunc, evalfunc, ListGen *); /* * Called to fetch a line of preprocessed source. The line * returned has been malloc'ed, and so should be freed after * use. */ - char *(*getline) (void); + int8_t *(*getline) (void); /* * Called at the end of a pass. @@ -371,7 +371,7 @@ enum { #define BITS8 0x00000001L #define BITS16 0x00000002L #define BITS32 0x00000004L -#define BITS64 0x00000008L /* FPU only */ +#define BITS64 0x00000008L /* x64 and FPU only */ #define BITS80 0x00000010L /* FPU only */ #define FAR 0x00000020L /* grotty: this means 16:16 or */ /* 16:32, like in CALL/JMP */ @@ -395,8 +395,10 @@ enum { #define REG8 0x00201001L #define REG16 0x00201002L #define REG32 0x00201004L -#define MMXREG 0x00201008L /* MMX registers */ -#define XMMREG 0x00201010L /* XMM Katmai reg */ +#define REG64 0x00201008L /* x64 registers */ +#define REGRIP 0x0020100CL /* RIP register */ +#define MMXREG 0x00201010L /* MMX registers */ +#define XMMREG 0x00201011L /* XMM Katmai reg */ #define FPUREG 0x01000000L /* floating point stack registers */ #define FPU0 0x01000800L /* FPU stack register zero */ @@ -406,13 +408,17 @@ enum { #define REG_AL 0x00211001L /* REG_ACCUM | BITSxx */ #define REG_AX 0x00211002L /* ditto */ #define REG_EAX 0x00211004L /* and again */ -#define REG_COUNT 0x00221000L /* counter: CL, CX or ECX */ +#define REG_RAX 0x00211008L /* and again */ +#define REG_COUNT 0x00221000L /* counter: CL, CX, ECX or RCX */ #define REG_CL 0x00221001L /* REG_COUNT | BITSxx */ #define REG_CX 0x00221002L /* ditto */ #define REG_ECX 0x00221004L /* another one */ +#define REG_RCX 0x00221008L /* another one */ #define REG_DL 0x00241001L #define REG_DX 0x00241002L #define REG_EDX 0x00241004L +#define REG_RDX 0x00241008L +#define REG_RIP 0x0027100CL /* RIP relative addressing */ #define REG_SREG 0x00081002L /* any segment register */ #define REG_CS 0x01081002L /* CS */ #define REG_DESS 0x02081002L /* DS, ES, SS (non-CS 86 registers) */ @@ -422,6 +428,7 @@ enum { #define REG_CREG 0x08101004L /* CRn */ #define REG_DREG 0x10101004L /* DRn */ #define REG_TREG 0x20101004L /* TRn */ +#define REG_C8REG 0x40101004L /* CR8 */ /* special type of EA */ #define MEM_OFFS 0x00604000L /* simple [address] offset */ @@ -448,8 +455,8 @@ enum { /* condition code names */ */ enum { /* instruction prefixes */ PREFIX_ENUM_START = REG_ENUM_LIMIT, - P_A16 = PREFIX_ENUM_START, P_A32, P_LOCK, P_O16, P_O32, P_REP, P_REPE, - P_REPNE, P_REPNZ, P_REPZ, P_TIMES + P_A16 = PREFIX_ENUM_START, P_A32, P_LOCK, P_O16, P_O32, + P_REP, P_REPE, P_REPNE, P_REPNZ, P_REPZ, P_TIMES }; enum { /* extended operand types */ @@ -463,19 +470,19 @@ enum { /* special EA flags */ }; enum { /* values for `hinttype' */ - EAH_NOHINT = 0, /* no hint at all - our discretion */ + EAH_NOHINT = 0, /* no hint at all - our discretion */ EAH_MAKEBASE = 1, /* try to make given reg the base */ - EAH_NOTBASE = 2 /* try _not_ to make reg the base */ + EAH_NOTBASE = 2 /* try _not_ to make reg the base */ }; typedef struct { /* operand to an instruction */ - long type; /* type of operand */ - int addr_size; /* 0 means default; 16; 32 */ + int32_t type; /* type of operand */ + int addr_size; /* 0 means default; 16; 32; 64 */ int basereg, indexreg, scale; /* registers and scale involved */ int hintbase, hinttype; /* hint as to real base register */ - long segment; /* immediate segment, if needed */ - long offset; /* any immediate number */ - long wrt; /* segment base it's relative to */ + int32_t segment; /* immediate segment, if needed */ + int64_t offset; /* any immediate number */ + int32_t wrt; /* segment base it's relative to */ int eaflags; /* special EA flags */ int opflags; /* see OPFLAG_* defines below */ } operand; @@ -485,18 +492,18 @@ typedef struct { /* operand to an instruction */ typedef struct extop { /* extended operand */ struct extop *next; /* linked list */ - long type; /* defined above */ - char *stringval; /* if it's a string, then here it is */ + int32_t type; /* defined above */ + int8_t *stringval; /* if it's a string, then here it is */ int stringlen; /* ... and here's how long it is */ - long segment; /* if it's a number/address, then... */ - long offset; /* ... it's given here ... */ - long wrt; /* ... and here */ + int32_t segment; /* if it's a number/address, then... */ + int64_t offset; /* ... it's given here ... */ + int32_t wrt; /* ... and here */ } extop; #define MAXPREFIX 4 typedef struct { /* an instruction itself */ - char *label; /* the label defined, or NULL */ + int8_t *label; /* the label defined, or NULL */ int prefixes[MAXPREFIX]; /* instruction prefixes, if any */ int nprefix; /* number of entries in above */ int opcode; /* the opcode - not just the string */ @@ -506,8 +513,9 @@ typedef struct { /* an instruction itself */ operand oprs[3]; /* the operands, defined as above */ extop *eops; /* extended operands */ int eops_float; /* true if DD and floating */ - long times; /* repeat count (TIMES prefix) */ + int32_t times; /* repeat count (TIMES prefix) */ int forw_ref; /* is there a forward reference? */ + uint8_t rex; /* Special REX Prefix */ } insn; enum geninfo { GI_SWITCH }; @@ -523,19 +531,20 @@ struct ofmt { * This is a short (one-liner) description of the type of * output generated by the driver. */ - const char *fullname; + const int8_t *fullname; /* * This is a single keyword used to select the driver. */ - const char *shortname; + const int8_t *shortname; + /* * this is reserved for out module specific help. - * It is set to NULL in all the out modules but is not implemented + * It is set to NULL in all the out modules and is not implemented * in the main program */ - const char *helpstring; + const int8_t *helpstring; /* * this is a pointer to the first element of the debug information @@ -552,13 +561,13 @@ struct ofmt { struct dfmt *current_dfmt; /* - * This, if non-NULL, is a NULL-terminated list of `char *'s + * This, if non-NULL, is a NULL-terminated list of `int8_t *'s * pointing to extra standard macros supplied by the object * format (e.g. a sensible initial default value of __SECT__, * and user-level equivalents for any format-specific * directives). */ - const char **stdmac; + const int8_t **stdmac; /* * This procedure is called at the start of an output session. @@ -576,7 +585,7 @@ struct ofmt { * and the second parameter gives the value. This function returns * 1 if recognized, 0 if unrecognized */ - int (*setinfo) (enum geninfo type, char **string); + int (*setinfo) (enum geninfo type, int8_t **string); /* * This procedure is called by assemble() to write actual @@ -587,8 +596,8 @@ struct ofmt { * The `type' argument specifies the type of output data, and * usually the size as well: its contents are described below. */ - void (*output) (long segto, const void *data, unsigned long type, - long segment, long wrt); + void (*output) (int32_t segto, const void *data, uint32_t type, + int32_t segment, int32_t wrt); /* * This procedure is called once for every symbol defined in @@ -618,8 +627,8 @@ struct ofmt { * been an EXTERN, a COMMON or a GLOBAL. The distinction should * be obvious to the output format from the other parameters. */ - void (*symdef) (char *name, long segment, long offset, int is_global, - char *special); + void (*symdef) (int8_t *name, int32_t segment, int32_t offset, int is_global, + int8_t *special); /* * This procedure is called when the source code requests a @@ -636,7 +645,7 @@ struct ofmt { * the segment, by setting `*bits' to 16 or 32. Or, if it * doesn't wish to define a default, it can leave `bits' alone. */ - long (*section) (char *name, int pass, int *bits); + int32_t (*section) (int8_t *name, int pass, int *bits); /* * This procedure is called to modify the segment base values @@ -651,7 +660,7 @@ struct ofmt { * responsible for throwing an error condition if that occurs * in pass two or in a critical expression. */ - long (*segbase) (long segment); + int32_t (*segbase) (int32_t segment); /* * This procedure is called to allow the output driver to @@ -667,7 +676,7 @@ struct ofmt { * should also return non-zero if it correctly processes the * directive. */ - int (*directive) (char *directive, char *value, int pass); + int (*directive) (int8_t *directive, int8_t *value, int pass); /* * This procedure is called before anything else - even before @@ -676,7 +685,7 @@ struct ofmt { * should return its preferred name for the output file in * `outname', if outname[0] is not '\0', and do nothing to * `outname' otherwise. Since it is called before the driver is - * properly initialised, it has to be passed its error handler + * properly initialized, it has to be passed its error handler * separately. * * This procedure may also take its own copy of the input file @@ -686,7 +695,7 @@ struct ofmt { * The parameter `outname' points to an area of storage * guaranteed to be at least FILENAME_MAX in size. */ - void (*filename) (char *inname, char *outname, efunc error); + void (*filename) (int8_t *inname, int8_t *outname, efunc error); /* * This procedure is called after assembly finishes, to allow @@ -713,9 +722,9 @@ struct ofmt { * Also OUT_RESERVE denotes reservation of N bytes of BSS space, * and the contents of the "data" parameter is irrelevant. * - * The "data" parameter for the output function points to a "long", + * The "data" parameter for the output function points to a "int32_t", * containing the address in question, unless the type is - * OUT_RAWDATA, in which case it points to an "unsigned char" + * OUT_RAWDATA, in which case it points to an "uint8_t" * array. */ #define OUT_RAWDATA 0x00000000UL @@ -739,12 +748,12 @@ struct dfmt { * This is a short (one-liner) description of the type of * output generated by the driver. */ - const char *fullname; + const int8_t *fullname; /* * This is a single keyword used to select the driver. */ - const char *shortname; + const int8_t *shortname; /* * init - called initially to set up local pointer to object format, @@ -757,7 +766,7 @@ struct dfmt { * linenum - called any time there is output with a change of * line number or file. */ - void (*linenum) (const char *filename, long linenumber, long segto); + void (*linenum) (const int8_t *filename, int32_t linenumber, int32_t segto); /* * debug_deflabel - called whenever a label is defined. Parameters @@ -765,8 +774,8 @@ struct dfmt { * would be called before the output format version. */ - void (*debug_deflabel) (char *name, long segment, long offset, - int is_global, char *special); + void (*debug_deflabel) (int8_t *name, int32_t segment, int32_t offset, + int is_global, int8_t *special); /* * debug_directive - called whenever a DEBUG directive other than 'LINE' * is encountered. 'directive' contains the first parameter to the @@ -775,14 +784,14 @@ struct dfmt { * function with 'directive' equal to "VAR" and 'params' equal to * "_somevar:int". */ - void (*debug_directive) (const char *directive, const char *params); + void (*debug_directive) (const int8_t *directive, const int8_t *params); /* * typevalue - called whenever the assembler wishes to register a type * for the last defined label. This routine MUST detect if a type was * already registered and not re-register it. */ - void (*debug_typevalue) (long type); + void (*debug_typevalue) (int32_t type); /* * debug_output - called whenever output is required @@ -847,5 +856,7 @@ extern int tasm_compatible_mode; extern int pass0; /* this is globally known */ extern int optimizing; +extern int globalbits; /* this is globally known */ +extern int maxbits; /* this is globally known */ #endif @@ -10,11 +10,14 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" #include "insns.h" /* For MAX_KEYWORD */ +int globalbits = 0; /* defined in nasm.h, works better here for ASM+DISASM */ + static efunc nasm_malloc_error; #ifdef LOGALLOC @@ -32,7 +35,7 @@ void nasm_set_malloc_error(efunc error) } #ifdef LOGALLOC -void *nasm_malloc_log(char *file, int line, size_t size) +void *nasm_malloc_log(int8_t *file, int line, size_t size) #else void *nasm_malloc(size_t size) #endif @@ -43,13 +46,13 @@ void *nasm_malloc(size_t size) #ifdef LOGALLOC else fprintf(logfp, "%s %d malloc(%ld) returns %p\n", - file, line, (long)size, p); + file, line, (int32_t)size, p); #endif return p; } #ifdef LOGALLOC -void *nasm_realloc_log(char *file, int line, void *q, size_t size) +void *nasm_realloc_log(int8_t *file, int line, void *q, size_t size) #else void *nasm_realloc(void *q, size_t size) #endif @@ -60,16 +63,16 @@ void *nasm_realloc(void *q, size_t size) #ifdef LOGALLOC else if (q) fprintf(logfp, "%s %d realloc(%p,%ld) returns %p\n", - file, line, q, (long)size, p); + file, line, q, (int32_t)size, p); else fprintf(logfp, "%s %d malloc(%ld) returns %p\n", - file, line, (long)size, p); + file, line, (int32_t)size, p); #endif return p; } #ifdef LOGALLOC -void nasm_free_log(char *file, int line, void *q) +void nasm_free_log(int8_t *file, int line, void *q) #else void nasm_free(void *q) #endif @@ -83,12 +86,12 @@ void nasm_free(void *q) } #ifdef LOGALLOC -char *nasm_strdup_log(char *file, int line, const char *s) +int8_t *nasm_strdup_log(int8_t *file, int line, const int8_t *s) #else -char *nasm_strdup(const char *s) +int8_t *nasm_strdup(const int8_t *s) #endif { - char *p; + int8_t *p; int size = strlen(s) + 1; p = malloc(size); @@ -97,19 +100,19 @@ char *nasm_strdup(const char *s) #ifdef LOGALLOC else fprintf(logfp, "%s %d strdup(%ld) returns %p\n", - file, line, (long)size, p); + file, line, (int32_t)size, p); #endif strcpy(p, s); return p; } #ifdef LOGALLOC -char *nasm_strndup_log(char *file, int line, char *s, size_t len) +int8_t *nasm_strndup_log(int8_t *file, int line, int8_t *s, size_t len) #else -char *nasm_strndup(char *s, size_t len) +int8_t *nasm_strndup(int8_t *s, size_t len) #endif { - char *p; + int8_t *p; int size = len + 1; p = malloc(size); @@ -118,7 +121,7 @@ char *nasm_strndup(char *s, size_t len) #ifdef LOGALLOC else fprintf(logfp, "%s %d strndup(%ld) returns %p\n", - file, line, (long)size, p); + file, line, (int32_t)size, p); #endif strncpy(p, s, len); p[len] = '\0'; @@ -126,7 +129,7 @@ char *nasm_strndup(char *s, size_t len) } #if !defined(stricmp) && !defined(strcasecmp) -int nasm_stricmp(const char *s1, const char *s2) +int nasm_stricmp(const int8_t *s1, const int8_t *s2) { while (*s1 && tolower(*s1) == tolower(*s2)) s1++, s2++; @@ -140,7 +143,7 @@ int nasm_stricmp(const char *s1, const char *s2) #endif #if !defined(strnicmp) && !defined(strncasecmp) -int nasm_strnicmp(const char *s1, const char *s2, int n) +int nasm_strnicmp(const int8_t *s1, const int8_t *s2, int n) { while (n > 0 && *s1 && tolower(*s1) == tolower(*s2)) s1++, s2++, n--; @@ -156,11 +159,11 @@ int nasm_strnicmp(const char *s1, const char *s2, int n) #define lib_isnumchar(c) ( isalnum(c) || (c) == '$') #define numvalue(c) ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0') -long readnum(char *str, int *error) +int64_t readnum(int8_t *str, int *error) { - char *r = str, *q; - long radix; - unsigned long result, checklimit; + int8_t *r = str, *q; + int32_t radix; + uint64_t result, checklimit; int digit, last; int warn = FALSE; int sign = 1; @@ -212,18 +215,21 @@ long readnum(char *str, int *error) *error = TRUE; return 0; } - + /* - * `checklimit' must be 2**32 / radix. We can't do that in - * 32-bit arithmetic, which we're (probably) using, so we + * `checklimit' must be 2**(32|64) / radix. We can't do that in + * 32/64-bit arithmetic, which we're (probably) using, so we * cheat: since we know that all radices we use are even, we - * can divide 2**31 by radix/2 instead. + * can divide 2**(31|63) by radix/2 instead. */ - checklimit = 0x80000000UL / (radix >> 1); + if (globalbits == 64) + checklimit = 0x8000000000000000ULL / (radix >> 1); + else + checklimit = 0x80000000UL / (radix >> 1); /* - * Calculate the highest allowable value for the last digit - * of a 32 bit constant... in radix 10, it is 6, otherwise it is 0 + * Calculate the highest allowable value for the last digit of a + * 32-bit constant... in radix 10, it is 6, otherwise it is 0 */ last = (radix == 10 ? 6 : 0); @@ -250,42 +256,49 @@ long readnum(char *str, int *error) return result * sign; } -long readstrnum(char *str, int length, int *warn) +int64_t readstrnum(int8_t *str, int length, int *warn) { - long charconst = 0; + int64_t charconst = 0; int i; *warn = FALSE; str += length; - for (i = 0; i < length; i++) { - if (charconst & 0xff000000UL) { - *warn = TRUE; + if (globalbits == 64) { + for (i = 0; i < length; i++) { + if (charconst & 0xFF00000000000000ULL) + *warn = TRUE; + charconst = (charconst << 8) + (uint8_t)*--str; + } + } else { + for (i = 0; i < length; i++) { + if (charconst & 0xFF000000UL) + *warn = TRUE; + charconst = (charconst << 8) + (uint8_t)*--str; } - charconst = (charconst << 8) + (unsigned char)*--str; } return charconst; } -static long next_seg; +static int32_t next_seg; void seg_init(void) { next_seg = 0; } -long seg_alloc(void) +int32_t seg_alloc(void) { return (next_seg += 2) - 2; } -void fwriteshort(int data, FILE * fp) +void fwriteint16_t(int data, FILE * fp) { fputc((int)(data & 255), fp); fputc((int)((data >> 8) & 255), fp); } -void fwritelong(long data, FILE * fp) +void fwriteint32_t(int32_t data, FILE * fp) { fputc((int)(data & 255), fp); fputc((int)((data >> 8) & 255), fp); @@ -293,10 +306,10 @@ void fwritelong(long data, FILE * fp) fputc((int)((data >> 24) & 255), fp); } -void standard_extension(char *inname, char *outname, char *extension, +void standard_extension(int8_t *inname, int8_t *outname, int8_t *extension, efunc error) { - char *p, *q; + int8_t *p, *q; if (*outname) /* file name already exists, */ return; /* so do nothing */ @@ -367,7 +380,7 @@ void raa_free(struct RAA *r) } } -long raa_read(struct RAA *r, long posn) +int32_t raa_read(struct RAA *r, int32_t posn) { if (posn >= r->stepsize * LAYERSIZ(r)) return 0; /* Return 0 for undefined entries */ @@ -382,7 +395,7 @@ long raa_read(struct RAA *r, long posn) return r->u.l.data[posn]; } -struct RAA *raa_write(struct RAA *r, long posn, long value) +struct RAA *raa_write(struct RAA *r, int32_t posn, int32_t value) { struct RAA *result; @@ -425,7 +438,7 @@ struct RAA *raa_write(struct RAA *r, long posn, long value) #define SAA_MAXLEN 8192 -struct SAA *saa_init(long elem_len) +struct SAA *saa_init(int32_t elem_len) { struct SAA *s; @@ -475,12 +488,12 @@ void *saa_wstruct(struct SAA *s) return p; } -void saa_wbytes(struct SAA *s, const void *data, long len) +void saa_wbytes(struct SAA *s, const void *data, int32_t len) { - const char *d = data; + const int8_t *d = data; while (len > 0) { - long l = s->end->length - s->end->posn; + int32_t l = s->end->length - s->end->posn; if (l > len) l = len; if (l > 0) { @@ -529,7 +542,7 @@ void *saa_rstruct(struct SAA *s) return p; } -void *saa_rbytes(struct SAA *s, long *len) +void *saa_rbytes(struct SAA *s, int32_t *len) { void *p; @@ -543,12 +556,12 @@ void *saa_rbytes(struct SAA *s, long *len) return p; } -void saa_rnbytes(struct SAA *s, void *data, long len) +void saa_rnbytes(struct SAA *s, void *data, int32_t len) { - char *d = data; + int8_t *d = data; while (len > 0) { - long l; + int32_t l; if (!s->rptr) return; @@ -569,11 +582,11 @@ void saa_rnbytes(struct SAA *s, void *data, long len) } } -void saa_fread(struct SAA *s, long posn, void *data, long len) +void saa_fread(struct SAA *s, int32_t posn, void *data, int32_t len) { struct SAA *p; - long pos; - char *cdata = data; + int64_t pos; + int8_t *cdata = data; if (!s->rptr || posn < s->rptr->start) saa_rewind(s); @@ -586,7 +599,7 @@ void saa_fread(struct SAA *s, long posn, void *data, long len) pos = posn - p->start; while (len) { - long l = p->posn - pos; + int64_t l = p->posn - pos; if (l > len) l = len; memcpy(cdata, p->data + pos, l); @@ -595,16 +608,16 @@ void saa_fread(struct SAA *s, long posn, void *data, long len) p = p->next; if (!p) return; - pos = 0L; + pos = 0LL; } s->rptr = p; } -void saa_fwrite(struct SAA *s, long posn, void *data, long len) +void saa_fwrite(struct SAA *s, int32_t posn, void *data, int32_t len) { struct SAA *p; - long pos; - char *cdata = data; + int64_t pos; + int8_t *cdata = data; if (!s->rptr || posn < s->rptr->start) saa_rewind(s); @@ -617,7 +630,7 @@ void saa_fwrite(struct SAA *s, long posn, void *data, long len) pos = posn - p->start; while (len) { - long l = p->posn - pos; + int64_t l = p->posn - pos; if (l > len) l = len; memcpy(p->data + pos, cdata, l); @@ -626,15 +639,15 @@ void saa_fwrite(struct SAA *s, long posn, void *data, long len) p = p->next; if (!p) return; - pos = 0L; + pos = 0LL; } s->rptr = p; } void saa_fpwrite(struct SAA *s, FILE * fp) { - char *data; - long len; + int8_t *data; + int32_t len; saa_rewind(s); while ((data = saa_rbytes(s, &len))) @@ -646,11 +659,11 @@ void saa_fpwrite(struct SAA *s, FILE * fp) * by the scanner. */ #include "names.c" -static const char *special_names[] = { +static const int8_t *special_names[] = { "byte", "dword", "far", "long", "near", "nosplit", "qword", "short", "strict", "to", "tword", "word" }; -static const char *prefix_names[] = { +static const int8_t *prefix_names[] = { "a16", "a32", "lock", "o16", "o32", "rep", "repe", "repne", "repnz", "repz", "times" }; @@ -660,7 +673,7 @@ static const char *prefix_names[] = { * formats. It keeps a succession of temporary-storage strings in * stdscan_tempstorage, which can be cleared using stdscan_reset. */ -static char **stdscan_tempstorage = NULL; +static int8_t **stdscan_tempstorage = NULL; static int stdscan_tempsize = 0, stdscan_templen = 0; #define STDSCAN_TEMP_DELTA 256 @@ -685,9 +698,9 @@ void nasmlib_cleanup(void) nasm_free(stdscan_tempstorage); } -static char *stdscan_copy(char *p, int len) +static int8_t *stdscan_copy(int8_t *p, int len) { - char *text; + int8_t *text; text = nasm_malloc(len + 1); strncpy(text, p, len); @@ -697,17 +710,17 @@ static char *stdscan_copy(char *p, int len) stdscan_tempsize += STDSCAN_TEMP_DELTA; stdscan_tempstorage = nasm_realloc(stdscan_tempstorage, stdscan_tempsize * - sizeof(char *)); + sizeof(int8_t *)); } stdscan_tempstorage[stdscan_templen++] = text; return text; } -char *stdscan_bufptr = NULL; +int8_t *stdscan_bufptr = NULL; int stdscan(void *private_data, struct tokenval *tv) { - char ourcopy[MAX_KEYWORD + 1], *r, *s; + int8_t ourcopy[MAX_KEYWORD + 1], *r, *s; (void)private_data; /* Don't warn that this parameter is unused */ @@ -755,7 +768,7 @@ int stdscan(void *private_data, struct tokenval *tv) } for (i = 0; i < elements(icn); i++) if (!strncmp(ourcopy, icn[i], strlen(icn[i]))) { - char *p = ourcopy + strlen(icn[i]); + int8_t *p = ourcopy + strlen(icn[i]); tv->t_integer = ico[i]; if ((tv->t_inttwo = bsi(p, conditions, elements(conditions))) >= 0) @@ -816,7 +829,7 @@ int stdscan(void *private_data, struct tokenval *tv) tv->t_charptr = NULL; return tv->t_type = TOKEN_NUM; } else if (*stdscan_bufptr == '\'' || *stdscan_bufptr == '"') { /* a char constant */ - char quote = *stdscan_bufptr++, *r; + int8_t quote = *stdscan_bufptr++, *r; int rn_warn; r = tv->t_charptr = stdscan_bufptr; while (*stdscan_bufptr && *stdscan_bufptr != quote) @@ -867,7 +880,7 @@ int stdscan(void *private_data, struct tokenval *tv) stdscan_bufptr += 2; return tv->t_type = TOKEN_DBL_OR; } else /* just an ordinary char */ - return tv->t_type = (unsigned char)(*stdscan_bufptr++); + return tv->t_type = (uint8_t)(*stdscan_bufptr++); } /* @@ -971,7 +984,7 @@ int is_just_unknown(expr * vect) * Return the scalar part of a relocatable vector. (Including * simple scalar vectors - those qualify as relocatable.) */ -long reloc_value(expr * vect) +int64_t reloc_value(expr * vect) { while (vect->type && !vect->value) vect++; @@ -987,7 +1000,7 @@ long reloc_value(expr * vect) * Return the segment number of a relocatable vector, or NO_SEG for * simple scalars. */ -long reloc_seg(expr * vect) +int32_t reloc_seg(expr * vect) { while (vect->type && (vect->type == EXPR_WRT || !vect->value)) vect++; @@ -1006,7 +1019,7 @@ long reloc_seg(expr * vect) * Return the WRT segment number of a relocatable vector, or NO_SEG * if no WRT part is present. */ -long reloc_wrt(expr * vect) +int32_t reloc_wrt(expr * vect) { while (vect->type && vect->type < EXPR_WRT) vect++; @@ -1019,7 +1032,7 @@ long reloc_wrt(expr * vect) /* * Binary search. */ -int bsi(char *string, const char **array, int size) +int bsi(int8_t *string, const int8_t **array, int size) { int i = -1, j = size; /* always, i < index < j */ while (j - i >= 2) { @@ -1035,29 +1048,29 @@ int bsi(char *string, const char **array, int size) return -1; /* we haven't got it :( */ } -static char *file_name = NULL; -static long line_number = 0; +static int8_t *file_name = NULL; +static int32_t line_number = 0; -char *src_set_fname(char *newname) +int8_t *src_set_fname(int8_t *newname) { - char *oldname = file_name; + int8_t *oldname = file_name; file_name = newname; return oldname; } -long src_set_linnum(long newline) +int32_t src_set_linnum(int32_t newline) { - long oldline = line_number; + int32_t oldline = line_number; line_number = newline; return oldline; } -long src_get_linnum(void) +int32_t src_get_linnum(void) { return line_number; } -int src_get(long *xline, char **xname) +int src_get(int32_t *xline, int8_t **xname) { if (!file_name || !*xname || strcmp(*xname, file_name)) { nasm_free(*xname); @@ -1066,18 +1079,18 @@ int src_get(long *xline, char **xname) return -2; } if (*xline != line_number) { - long tmp = line_number - *xline; + int32_t tmp = line_number - *xline; *xline = line_number; return tmp; } return 0; } -void nasm_quote(char **str) +void nasm_quote(int8_t **str) { int ln = strlen(*str); - char q = (*str)[0]; - char *p; + int8_t q = (*str)[0]; + int8_t *p; if (ln > 1 && (*str)[ln - 1] == q && (q == '"' || q == '\'')) return; q = '"'; @@ -1091,9 +1104,9 @@ void nasm_quote(char **str) *str = p; } -char *nasm_strcat(char *one, char *two) +int8_t *nasm_strcat(int8_t *one, int8_t *two) { - char *rslt; + int8_t *rslt; int l1 = strlen(one); rslt = nasm_malloc(l1 + strlen(two) + 1); strcpy(rslt, one); @@ -1104,17 +1117,17 @@ char *nasm_strcat(char *one, char *two) void null_debug_init(struct ofmt *of, void *id, FILE * fp, efunc error) { } -void null_debug_linenum(const char *filename, long linenumber, long segto) +void null_debug_linenum(const int8_t *filename, int32_t linenumber, int32_t segto) { } -void null_debug_deflabel(char *name, long segment, long offset, - int is_global, char *special) +void null_debug_deflabel(int8_t *name, int32_t segment, int32_t offset, + int is_global, int8_t *special) { } -void null_debug_routine(const char *directive, const char *params) +void null_debug_routine(const int8_t *directive, const int8_t *params) { } -void null_debug_typevalue(long type) +void null_debug_typevalue(int32_t type) { } void null_debug_output(int type, void *param) @@ -31,14 +31,14 @@ void nasm_set_malloc_error(efunc); void *nasm_malloc(size_t); void *nasm_realloc(void *, size_t); void nasm_free(void *); -char *nasm_strdup(const char *); -char *nasm_strndup(char *, size_t); +int8_t *nasm_strdup(const int8_t *); +int8_t *nasm_strndup(int8_t *, size_t); #else -void *nasm_malloc_log(char *, int, size_t); -void *nasm_realloc_log(char *, int, void *, size_t); -void nasm_free_log(char *, int, void *); -char *nasm_strdup_log(char *, int, const char *); -char *nasm_strndup_log(char *, int, char *, size_t); +void *nasm_malloc_log(int8_t *, int, size_t); +void *nasm_realloc_log(int8_t *, int, void *, size_t); +void nasm_free_log(int8_t *, int, void *); +int8_t *nasm_strdup_log(int8_t *, int, const int8_t *); +int8_t *nasm_strndup_log(int8_t *, int, int8_t *, size_t); #define nasm_malloc(x) nasm_malloc_log(__FILE__,__LINE__,x) #define nasm_realloc(x,y) nasm_realloc_log(__FILE__,__LINE__,x,y) #define nasm_free(x) nasm_free_log(__FILE__,__LINE__,x) @@ -58,7 +58,7 @@ char *nasm_strndup_log(char *, int, char *, size_t); #define nasm_stricmp strcasecmp #endif #else -int nasm_stricmp(const char *, const char *); +int nasm_stricmp(const int8_t *, const int8_t *); #endif #if defined(strnicmp) || defined(strncasecmp) @@ -68,14 +68,14 @@ int nasm_stricmp(const char *, const char *); #define nasm_strnicmp strncasecmp #endif #else -int nasm_strnicmp(const char *, const char *, int); +int nasm_strnicmp(const int8_t *, const int8_t *, int); #endif /* * Convert a string into a number, using NASM number rules. Sets * `*error' to TRUE if an error occurs, and FALSE otherwise. */ -long readnum(char *str, int *error); +int64_t readnum(int8_t *str, int *error); /* * Convert a character constant into a number. Sets @@ -83,21 +83,21 @@ long readnum(char *str, int *error); * str points to and length covers the middle of the string, * without the quotes. */ -long readstrnum(char *str, int length, int *warn); +int64_t readstrnum(int8_t *str, int length, int *warn); /* * seg_init: Initialise the segment-number allocator. * seg_alloc: allocate a hitherto unused segment number. */ void seg_init(void); -long seg_alloc(void); +int32_t seg_alloc(void); /* * many output formats will be able to make use of this: a standard * function to add an extension to the name of the input file */ #ifdef NASM_NASM_H -void standard_extension(char *inname, char *outname, char *extension, +void standard_extension(int8_t *inname, int8_t *outname, int8_t *extension, efunc error); #endif @@ -125,15 +125,27 @@ void standard_extension(char *inname, char *outname, char *extension, WRITECHAR(p,(v) >> 16); \ WRITECHAR(p,(v) >> 24); \ } while (0) + +#define WRITEDLONG(p,v) \ + do { \ + WRITECHAR(p,v); \ + WRITECHAR(p,(v) >> 8); \ + WRITECHAR(p,(v) >> 16); \ + WRITECHAR(p,(v) >> 24); \ + WRITECHAR(p,(v) >> 32); \ + WRITECHAR(p,(v) >> 40); \ + WRITECHAR(p,(v) >> 48); \ + WRITECHAR(p,(v) >> 56); \ + } while (0) /* * and routines to do the same thing to a file */ -void fwriteshort(int data, FILE * fp); -void fwritelong(long data, FILE * fp); +void fwriteint16_t(int data, FILE * fp); +void fwriteint32_t(int32_t data, FILE * fp); /* - * Routines to manage a dynamic random access array of longs which + * Routines to manage a dynamic random access array of int32_ts which * may grow in size to be more than the largest single malloc'able * chunk. */ @@ -162,10 +174,10 @@ struct RAA { * RAA_BLKSIZE, and for a level 2 branch it's * RAA_LAYERSIZE*RAA_BLKSIZE. */ - long stepsize; + int32_t stepsize; union RAA_UNION { struct RAA_LEAF { - long data[RAA_BLKSIZE]; + int32_t data[RAA_BLKSIZE]; } l; struct RAA_BRANCH { struct RAA *data[RAA_LAYERSIZE]; @@ -175,14 +187,14 @@ struct RAA { struct RAA *raa_init(void); void raa_free(struct RAA *); -long raa_read(struct RAA *, long); -struct RAA *raa_write(struct RAA *r, long posn, long value); +int32_t raa_read(struct RAA *, int32_t); +struct RAA *raa_write(struct RAA *r, int32_t posn, int32_t value); /* * Routines to manage a dynamic sequential-access array, under the * same restriction on maximum mallocable block. This array may be * written to in two ways: a contiguous chunk can be reserved of a - * given size, and a pointer returned, or single-byte data may be + * given size with a pointer returned OR single-byte data may be * written. The array can also be read back in the same two ways: * as a series of big byte-data blocks or as a list of structures * of a given size. @@ -194,27 +206,27 @@ struct SAA { * list; `rptr' and `rpos' are used for reading */ struct SAA *next, *end, *rptr; - long elem_len, length, posn, start, rpos; - char *data; + int32_t elem_len, length, posn, start, rpos; + int8_t *data; }; -struct SAA *saa_init(long elem_len); /* 1 == byte */ +struct SAA *saa_init(int32_t elem_len); /* 1 == byte */ void saa_free(struct SAA *); void *saa_wstruct(struct SAA *); /* return a structure of elem_len */ -void saa_wbytes(struct SAA *, const void *, long); /* write arbitrary bytes */ +void saa_wbytes(struct SAA *, const void *, int32_t); /* write arbitrary bytes */ void saa_rewind(struct SAA *); /* for reading from beginning */ void *saa_rstruct(struct SAA *); /* return NULL on EOA */ -void *saa_rbytes(struct SAA *, long *); /* return 0 on EOA */ -void saa_rnbytes(struct SAA *, void *, long); /* read a given no. of bytes */ -void saa_fread(struct SAA *s, long posn, void *p, long len); /* fixup */ -void saa_fwrite(struct SAA *s, long posn, void *p, long len); /* fixup */ +void *saa_rbytes(struct SAA *, int32_t *); /* return 0 on EOA */ +void saa_rnbytes(struct SAA *, void *, int32_t); /* read a given no. of bytes */ +void saa_fread(struct SAA *s, int32_t posn, void *p, int32_t len); /* fixup */ +void saa_fwrite(struct SAA *s, int32_t posn, void *p, int32_t len); /* fixup */ void saa_fpwrite(struct SAA *, FILE *); #ifdef NASM_NASM_H /* * Standard scanner. */ -extern char *stdscan_bufptr; +extern int8_t *stdscan_bufptr; void stdscan_reset(void); int stdscan(void *private_data, struct tokenval *tv); #endif @@ -228,9 +240,9 @@ int is_simple(expr *); int is_really_simple(expr *); int is_unknown(expr *); int is_just_unknown(expr *); -long reloc_value(expr *); -long reloc_seg(expr *); -long reloc_wrt(expr *); +int64_t reloc_value(expr *); +int32_t reloc_seg(expr *); +int32_t reloc_wrt(expr *); #endif /* @@ -238,24 +250,25 @@ long reloc_wrt(expr *); * matching `string', or <0 if no match. `array' is taken to * contain `size' elements. */ -int bsi(char *string, const char **array, int size); +int bsi(int8_t *string, const int8_t **array, int size); -char *src_set_fname(char *newname); -long src_set_linnum(long newline); -long src_get_linnum(void); +int8_t *src_set_fname(int8_t *newname); +int32_t src_set_linnum(int32_t newline); +int32_t src_get_linnum(void); /* * src_get may be used if you simply want to know the source file and line. * It is also used if you maintain private status about the source location * It return 0 if the information was the same as the last time you * checked, -1 if the name changed and (new-old) if just the line changed. */ -int src_get(long *xline, char **xname); +int src_get(int32_t *xline, int8_t **xname); -void nasm_quote(char **str); -char *nasm_strcat(char *one, char *two); +void nasm_quote(int8_t **str); +int8_t *nasm_strcat(int8_t *one, int8_t *two); void nasmlib_cleanup(void); -void null_debug_routine(const char *directive, const char *params); +void null_debug_routine(const int8_t *directive, const int8_t *params); extern struct dfmt null_debug_form; extern struct dfmt *null_debug_arr[2]; + #endif @@ -11,6 +11,7 @@ #include <string.h> #include <ctype.h> #include <errno.h> +#include <inttypes.h> #include "insns.h" #include "nasm.h" @@ -20,7 +21,7 @@ #define BPL 8 /* bytes per line of hex dump */ -static const char *help = +static const int8_t *help = "usage: ndisasm [-a] [-i] [-h] [-r] [-u] [-b bits] [-o origin] [-s sync...]\n" " [-e bytes] [-k start,bytes] [-p vendor] file\n" " -a or -i activates auto (intelligent) sync\n" @@ -32,31 +33,31 @@ static const char *help = " -k avoids disassembling <bytes> bytes from position <start>\n" " -p selects the preferred vendor instruction set (intel, amd, cyrix, idt)\n"; -static void output_ins(unsigned long, unsigned char *, int, char *); -static void skip(unsigned long dist, FILE * fp); +static void output_ins(uint32_t, uint8_t *, int, int8_t *); +static void skip(uint32_t dist, FILE * fp); -int main(int argc, char **argv) +int main(int argc, int8_t **argv) { - unsigned char buffer[INSN_MAX * 2], *p, *q; - char outbuf[256]; - char *pname = *argv; - char *filename = NULL; - unsigned long nextsync, synclen, initskip = 0L; + uint8_t buffer[INSN_MAX * 2], *p, *q; + int8_t outbuf[256]; + int8_t *pname = *argv; + int8_t *filename = NULL; + uint32_t nextsync, synclen, initskip = 0L; int lenread; - long lendis; + int32_t lendis; int autosync = FALSE; int bits = 16; int eof = FALSE; - unsigned long prefer = 0; + uint32_t prefer = 0; int rn_error; - long offset; + int32_t offset; FILE *fp; offset = 0; init_sync(); while (--argc) { - char *v, *vv, *p = *++argv; + int8_t *v, *vv, *p = *++argv; if (*p == '-' && p[1]) { p++; while (*p) @@ -241,7 +242,7 @@ int main(int argc, char **argv) p = q = buffer; nextsync = next_sync(offset, &synclen); do { - unsigned long to_read = buffer + sizeof(buffer) - p; + uint32_t to_read = buffer + sizeof(buffer) - p; if (to_read > nextsync - offset - (p - q)) to_read = nextsync - offset - (p - q); if (to_read) { @@ -251,7 +252,7 @@ int main(int argc, char **argv) } else lenread = 0; p += lenread; - if ((unsigned long)offset == nextsync) { + if ((uint32_t)offset == nextsync) { if (synclen) { fprintf(stdout, "%08lX skipping 0x%lX bytes\n", offset, synclen); @@ -266,14 +267,14 @@ int main(int argc, char **argv) disasm(q, outbuf, sizeof(outbuf), bits, offset, autosync, prefer); if (!lendis || lendis > (p - q) - || (unsigned long)lendis > nextsync - offset) + || (uint32_t)lendis > nextsync - offset) lendis = eatbyte(q, outbuf, sizeof(outbuf)); output_ins(offset, q, lendis, outbuf); q += lendis; offset += lendis; } if (q >= buffer + INSN_MAX) { - unsigned char *r = buffer, *s = q; + uint8_t *r = buffer, *s = q; int count = p - q; while (count--) *r++ = *s++; @@ -288,8 +289,8 @@ int main(int argc, char **argv) return 0; } -static void output_ins(unsigned long offset, unsigned char *data, - int datalen, char *insn) +static void output_ins(uint32_t offset, uint8_t *data, + int datalen, int8_t *insn) { int bytes; fprintf(stdout, "%08lX ", offset); @@ -319,9 +320,9 @@ static void output_ins(unsigned long offset, unsigned char *data, * Skip a certain amount of data in a file, either by seeking if * possible, or if that fails then by reading and discarding. */ -static void skip(unsigned long dist, FILE * fp) +static void skip(uint32_t dist, FILE * fp) { - char buffer[256]; /* should fit on most stacks :-) */ + int8_t buffer[256]; /* should fit on most stacks :-) */ /* * Got to be careful with fseek: at least one fseek I've tried @@ -330,7 +331,7 @@ static void skip(unsigned long dist, FILE * fp) */ if (fseek(fp, dist + ftell(fp), SEEK_SET)) { while (dist > 0) { - unsigned long len = (dist < sizeof(buffer) ? + uint32_t len = (dist < sizeof(buffer) ? dist : sizeof(buffer)); if (fread(buffer, 1, len, fp) < len) { perror("fread"); @@ -11,13 +11,14 @@ #include <stdio.h> #include <string.h> +#include <inttypes.h> #define BUILD_DRIVERS_ARRAY #include "outform.h" static int ndrivers = 0; -struct ofmt *ofmt_find(char *name) +struct ofmt *ofmt_find(int8_t *name) { /* find driver */ int i; @@ -27,7 +28,7 @@ struct ofmt *ofmt_find(char *name) return NULL; } -struct dfmt *dfmt_find(struct ofmt *ofmt, char *name) +struct dfmt *dfmt_find(struct ofmt *ofmt, int8_t *name) { /* find driver */ struct dfmt **dfmt = ofmt->debug_formats; while (*dfmt) { @@ -89,6 +89,9 @@ #ifndef OF_WIN32 #define OF_WIN32 #endif +#ifndef OF_WIN64 +#define OF_WIN64 +#endif #ifndef OF_AS86 #define OF_AS86 #endif @@ -114,6 +117,9 @@ #ifndef OF_WIN32 #define OF_WIN32 #endif +#ifndef OF_WIN64 +#define OF_WIN64 +#endif #endif #ifdef OF_UNIX @@ -171,6 +177,9 @@ #ifdef OF_NO_WIN32 #undef OF_WIN32 #endif +#ifdef OF_NO_WIN64 +#undef OF_WIN64 +#endif #ifdef OF_NO_AS86 #undef OF_AS86 #endif @@ -201,6 +210,7 @@ extern struct ofmt of_elf; extern struct ofmt of_as86; extern struct ofmt of_obj; extern struct ofmt of_win32; +extern struct ofmt of_win64; extern struct ofmt of_rdf2; extern struct ofmt of_ieee; extern struct ofmt of_macho; @@ -231,6 +241,9 @@ struct ofmt *drivers[] = { #ifdef OF_WIN32 &of_win32, #endif +#ifdef OF_WIN64 + &of_win64, +#endif #ifdef OF_RDF2 &of_rdf2, #endif @@ -249,8 +262,8 @@ struct ofmt *drivers[] = { #endif /* BUILD_DRIVERS_ARRAY */ -struct ofmt *ofmt_find(char *); -struct dfmt *dfmt_find(struct ofmt *, char *); +struct ofmt *ofmt_find(int8_t *); +struct dfmt *dfmt_find(struct ofmt *, int8_t *); void ofmt_list(struct ofmt *, FILE *); void dfmt_list(struct ofmt *ofmt, FILE * fp); struct ofmt *ofmt_register(efunc error); diff --git a/output/outaout.c b/output/outaout.c index dabfe1f..e250767 100644 --- a/output/outaout.c +++ b/output/outaout.c @@ -11,6 +11,7 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" @@ -28,22 +29,22 @@ struct Reloc { struct Reloc *next; - long address; /* relative to _start_ of section */ - long symbol; /* symbol number or -ve section id */ + int32_t address; /* relative to _start_ of section */ + int32_t symbol; /* symbol number or -ve section id */ int bytes; /* 2 or 4 */ int reltype; /* see above */ }; struct Symbol { - long strpos; /* string table position of name */ + int32_t strpos; /* string table position of name */ int type; /* symbol type - see flags below */ - long value; /* address, or COMMON variable size */ - long size; /* size for data or function exports */ - long segment; /* back-reference used by gsym_reloc */ + int32_t value; /* address, or COMMON variable size */ + int32_t size; /* size for data or function exports */ + int32_t segment; /* back-reference used by gsym_reloc */ struct Symbol *next; /* list of globals in each section */ struct Symbol *nextfwd; /* list of unresolved-size symbols */ - char *name; /* for unresolved-size symbols */ - long symnum; /* index into symbol table */ + int8_t *name; /* for unresolved-size symbols */ + int32_t symnum; /* index into symbol table */ }; /* @@ -75,8 +76,8 @@ struct Symbol { struct Section { struct SAA *data; - unsigned long len, size, nrelocs; - long index; + uint32_t len, size, nrelocs; + int32_t index; struct Reloc *head, **tail; struct Symbol *gsyms, *asym; }; @@ -84,12 +85,12 @@ struct Section { static struct Section stext, sdata, sbss; static struct SAA *syms; -static unsigned long nsyms; +static uint32_t nsyms; static struct RAA *bsym; static struct SAA *strs; -static unsigned long strslen; +static uint32_t strslen; static struct Symbol *fwds; @@ -103,8 +104,8 @@ static int is_pic; static void aout_write(void); static void aout_write_relocs(struct Reloc *); static void aout_write_syms(void); -static void aout_sect_write(struct Section *, const unsigned char *, - unsigned long); +static void aout_sect_write(struct Section *, const uint8_t *, + uint32_t); static void aout_pad_sections(void); static void aout_fixup_relocs(struct Section *); @@ -113,9 +114,9 @@ static void aout_fixup_relocs(struct Section *); * symbols, which can be used with WRT to provide PIC relocation * types. */ -static long aout_gotpc_sect, aout_gotoff_sect; -static long aout_got_sect, aout_plt_sect; -static long aout_sym_sect; +static int32_t aout_gotpc_sect, aout_gotoff_sect; +static int32_t aout_got_sect, aout_plt_sect; +static int32_t aout_sym_sect; static void aoutg_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) @@ -137,7 +138,7 @@ static void aoutg_init(FILE * fp, efunc errfunc, ldfunc ldef, sdata.index = seg_alloc(); sbss.index = seg_alloc(); stext.asym = sdata.asym = sbss.asym = NULL; - syms = saa_init((long)sizeof(struct Symbol)); + syms = saa_init((int32_t)sizeof(struct Symbol)); nsyms = 0; bsym = raa_init(); strs = saa_init(1L); @@ -217,7 +218,7 @@ static void aout_cleanup(int debuginfo) saa_free(strs); } -static long aout_section_names(char *name, int pass, int *bits) +static int32_t aout_section_names(int8_t *name, int pass, int *bits) { /* * Default to 32 bits. @@ -238,8 +239,8 @@ static long aout_section_names(char *name, int pass, int *bits) return NO_SEG; } -static void aout_deflabel(char *name, long segment, long offset, - int is_global, char *special) +static void aout_deflabel(int8_t *name, int32_t segment, int32_t offset, + int is_global, int8_t *special) { int pos = strslen + 4; struct Symbol *sym; @@ -268,7 +269,7 @@ static void aout_deflabel(char *name, long segment, long offset, if (!strcmp((*s)->name, name)) { struct tokenval tokval; expr *e; - char *p = special; + int8_t *p = special; while (*p && !isspace(*p)) p++; @@ -296,7 +297,7 @@ static void aout_deflabel(char *name, long segment, long offset, return; /* it wasn't an important one */ } - saa_wbytes(strs, name, (long)(1 + strlen(name))); + saa_wbytes(strs, name, (int32_t)(1 + strlen(name))); strslen += 1 + strlen(name); sym = saa_wstruct(syms); @@ -355,7 +356,7 @@ static void aout_deflabel(char *name, long segment, long offset, struct tokenval tokval; expr *e; int fwd = FALSE; - char *saveme = stdscan_bufptr; /* bugfix? fbk 8/10/00 */ + int8_t *saveme = stdscan_bufptr; /* bugfix? fbk 8/10/00 */ if (!bsd) { error(ERR_NONFATAL, "Linux a.out does not support" @@ -408,7 +409,7 @@ static void aout_deflabel(char *name, long segment, long offset, error(ERR_NONFATAL, "no special symbol features supported here"); } -static void aout_add_reloc(struct Section *sect, long segment, +static void aout_add_reloc(struct Section *sect, int32_t segment, int reltype, int bytes) { struct Reloc *r; @@ -453,8 +454,8 @@ static void aout_add_reloc(struct Section *sect, long segment, * Inefficiency: we search, currently, using a linked list which * isn't even necessarily sorted. */ -static long aout_add_gsym_reloc(struct Section *sect, - long segment, long offset, +static int32_t aout_add_gsym_reloc(struct Section *sect, + int32_t segment, int32_t offset, int type, int bytes, int exact) { struct Symbol *sym, *sm, *shead; @@ -526,8 +527,8 @@ static long aout_add_gsym_reloc(struct Section *sect, * Return value is the adjusted value of `addr', having become an * offset from the `asym' symbol rather than the section. */ -static long aout_add_gotoff_reloc(struct Section *sect, long segment, - long offset, int bytes) +static int32_t aout_add_gotoff_reloc(struct Section *sect, int32_t segment, + int32_t offset, int bytes) { struct Reloc *r; struct Symbol *asym; @@ -561,13 +562,13 @@ static long aout_add_gotoff_reloc(struct Section *sect, long segment, return offset - asym->value; } -static void aout_out(long segto, const void *data, unsigned long type, - long segment, long wrt) +static void aout_out(int32_t segto, const void *data, uint32_t type, + int32_t segment, int32_t wrt) { struct Section *s; - long realbytes = type & OUT_SIZMASK; - long addr; - unsigned char mydata[4], *p; + int32_t realbytes = type & OUT_SIZMASK; + int32_t addr; + uint8_t mydata[4], *p; type &= OUT_TYPMASK; @@ -594,7 +595,7 @@ static void aout_out(long segto, const void *data, unsigned long type, } if (!s && type != OUT_RESERVE) { - error(ERR_WARNING, "attempt to initialise memory in the" + error(ERR_WARNING, "attempt to initialize memory in the" " BSS section: ignored"); if (type == OUT_REL2ADR) realbytes = 2; @@ -606,7 +607,7 @@ static void aout_out(long segto, const void *data, unsigned long type, if (type == OUT_RESERVE) { if (s) { - error(ERR_WARNING, "uninitialised space declared in" + error(ERR_WARNING, "uninitialized space declared in" " %s section: zeroing", (segto == stext.index ? "code" : "data")); aout_sect_write(s, NULL, realbytes); @@ -617,7 +618,7 @@ static void aout_out(long segto, const void *data, unsigned long type, error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG"); aout_sect_write(s, data, realbytes); } else if (type == OUT_ADDRESS) { - addr = *(long *)data; + addr = *(int32_t *)data; if (segment != NO_SEG) { if (segment % 2) { error(ERR_NONFATAL, "a.out format does not support" @@ -694,7 +695,7 @@ static void aout_out(long segto, const void *data, unsigned long type, } } p = mydata; - WRITESHORT(p, *(long *)data - (realbytes + s->len)); + WRITESHORT(p, *(int32_t *)data - (realbytes + s->len)); aout_sect_write(s, mydata, 2L); } else if (type == OUT_REL4ADR) { if (segment == segto) @@ -724,21 +725,21 @@ static void aout_out(long segto, const void *data, unsigned long type, } } p = mydata; - WRITELONG(p, *(long *)data - (realbytes + s->len)); + WRITELONG(p, *(int32_t *)data - (realbytes + s->len)); aout_sect_write(s, mydata, 4L); } } static void aout_pad_sections(void) { - static unsigned char pad[] = { 0x90, 0x90, 0x90, 0x90 }; + static uint8_t pad[] = { 0x90, 0x90, 0x90, 0x90 }; /* * Pad each of the text and data sections with NOPs until their * length is a multiple of four. (NOP == 0x90.) Also increase * the length of the BSS section similarly. */ - aout_sect_write(&stext, pad, (-(long)stext.len) & 3); - aout_sect_write(&sdata, pad, (-(long)sdata.len) & 3); + aout_sect_write(&stext, pad, (-(int32_t)stext.len) & 3); + aout_sect_write(&sdata, pad, (-(int32_t)sdata.len) & 3); sbss.len = (sbss.len + 3) & ~3; } @@ -757,17 +758,17 @@ static void aout_fixup_relocs(struct Section *sect) saa_rewind(sect->data); for (r = sect->head; r; r = r->next) { - unsigned char *p, *q, blk[4]; - long l; + uint8_t *p, *q, blk[4]; + int32_t l; - saa_fread(sect->data, r->address, blk, (long)r->bytes); + saa_fread(sect->data, r->address, blk, (int32_t)r->bytes); p = q = blk; l = *p++; if (r->bytes > 1) { - l += ((long)*p++) << 8; + l += ((int32_t)*p++) << 8; if (r->bytes == 4) { - l += ((long)*p++) << 16; - l += ((long)*p++) << 24; + l += ((int32_t)*p++) << 16; + l += ((int32_t)*p++) << 24; } } if (r->symbol == -SECT_DATA) @@ -780,7 +781,7 @@ static void aout_fixup_relocs(struct Section *sect) WRITESHORT(q, l); else *q++ = l & 0xFF; - saa_fwrite(sect->data, r->address, blk, (long)r->bytes); + saa_fwrite(sect->data, r->address, blk, (int32_t)r->bytes); } } @@ -790,14 +791,14 @@ static void aout_write(void) * Emit the a.out header. */ /* OMAGIC, M_386 or MID_I386, no flags */ - fwritelong(bsd ? 0x07018600 | is_pic : 0x640107L, aoutfp); - fwritelong(stext.len, aoutfp); - fwritelong(sdata.len, aoutfp); - fwritelong(sbss.len, aoutfp); - fwritelong(nsyms * 12, aoutfp); /* length of symbol table */ - fwritelong(0L, aoutfp); /* object files have no entry point */ - fwritelong(stext.nrelocs * 8, aoutfp); /* size of text relocs */ - fwritelong(sdata.nrelocs * 8, aoutfp); /* size of data relocs */ + fwriteint32_t(bsd ? 0x07018600 | is_pic : 0x640107L, aoutfp); + fwriteint32_t(stext.len, aoutfp); + fwriteint32_t(sdata.len, aoutfp); + fwriteint32_t(sbss.len, aoutfp); + fwriteint32_t(nsyms * 12, aoutfp); /* length of symbol table */ + fwriteint32_t(0L, aoutfp); /* object files have no entry point */ + fwriteint32_t(stext.nrelocs * 8, aoutfp); /* size of text relocs */ + fwriteint32_t(sdata.nrelocs * 8, aoutfp); /* size of data relocs */ /* * Write out the code section and the data section. @@ -819,16 +820,16 @@ static void aout_write(void) /* * And the string table. */ - fwritelong(strslen + 4, aoutfp); /* length includes length count */ + fwriteint32_t(strslen + 4, aoutfp); /* length includes length count */ saa_fpwrite(strs, aoutfp); } static void aout_write_relocs(struct Reloc *r) { while (r) { - unsigned long word2; + uint32_t word2; - fwritelong(r->address, aoutfp); + fwriteint32_t(r->address, aoutfp); if (r->symbol >= 0) word2 = r->symbol; @@ -837,7 +838,7 @@ static void aout_write_relocs(struct Reloc *r) word2 |= r->reltype << 24; word2 |= (r->bytes == 1 ? 0 : r->bytes == 2 ? 0x2000000L : 0x4000000L); - fwritelong(word2, aoutfp); + fwriteint32_t(word2, aoutfp); r = r->next; } @@ -845,13 +846,13 @@ static void aout_write_relocs(struct Reloc *r) static void aout_write_syms(void) { - unsigned long i; + uint32_t i; saa_rewind(syms); for (i = 0; i < nsyms; i++) { struct Symbol *sym = saa_rstruct(syms); - fwritelong(sym->strpos, aoutfp); - fwritelong((long)sym->type & ~SYM_WITH_SIZE, aoutfp); + fwriteint32_t(sym->strpos, aoutfp); + fwriteint32_t((int32_t)sym->type & ~SYM_WITH_SIZE, aoutfp); /* * Fix up the symbol value now we know the final section * sizes. @@ -860,49 +861,49 @@ static void aout_write_syms(void) sym->value += stext.len; if ((sym->type & SECT_MASK) == SECT_BSS) sym->value += stext.len + sdata.len; - fwritelong(sym->value, aoutfp); + fwriteint32_t(sym->value, aoutfp); /* * Output a size record if necessary. */ if (sym->type & SYM_WITH_SIZE) { - fwritelong(sym->strpos, aoutfp); - fwritelong(0x0DL, aoutfp); /* special value: means size */ - fwritelong(sym->size, aoutfp); + fwriteint32_t(sym->strpos, aoutfp); + fwriteint32_t(0x0DL, aoutfp); /* special value: means size */ + fwriteint32_t(sym->size, aoutfp); i++; /* use up another of `nsyms' */ } } } static void aout_sect_write(struct Section *sect, - const unsigned char *data, unsigned long len) + const uint8_t *data, uint32_t len) { saa_wbytes(sect->data, data, len); sect->len += len; } -static long aout_segbase(long segment) +static int32_t aout_segbase(int32_t segment) { return segment; } -static int aout_directive(char *directive, char *value, int pass) +static int aout_directive(int8_t *directive, int8_t *value, int pass) { return 0; } -static void aout_filename(char *inname, char *outname, efunc error) +static void aout_filename(int8_t *inname, int8_t *outname, efunc error) { standard_extension(inname, outname, ".o", error); } -static const char *aout_stdmac[] = { +static const int8_t *aout_stdmac[] = { "%define __SECT__ [section .text]", "%macro __NASM_CDecl__ 1", "%endmacro", NULL }; -static int aout_set_info(enum geninfo type, char **val) +static int aout_set_info(enum geninfo type, int8_t **val) { return 0; } diff --git a/output/outas86.c b/output/outas86.c index 9a3d366..b75fd5f 100644 --- a/output/outas86.c +++ b/output/outas86.c @@ -11,6 +11,7 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" @@ -21,17 +22,17 @@ struct Piece { struct Piece *next; int type; /* 0 = absolute, 1 = seg, 2 = sym */ - long offset; /* relative offset */ + int32_t offset; /* relative offset */ int number; /* symbol/segment number (4=bss) */ - long bytes; /* size of reloc or of absolute data */ + int32_t bytes; /* size of reloc or of absolute data */ int relative; /* TRUE or FALSE */ }; struct Symbol { - long strpos; /* string table position of name */ + int32_t strpos; /* string table position of name */ int flags; /* symbol flags */ int segment; /* 4=bss at this point */ - long value; /* address, or COMMON variable size */ + int32_t value; /* address, or COMMON variable size */ }; /* @@ -51,24 +52,24 @@ struct Symbol { struct Section { struct SAA *data; - unsigned long datalen, size, len; - long index; + uint32_t datalen, size, len; + int32_t index; struct Piece *head, *last, **tail; }; -static char as86_module[FILENAME_MAX]; +static int8_t as86_module[FILENAME_MAX]; static struct Section stext, sdata; -static unsigned long bsslen; -static long bssindex; +static uint32_t bsslen; +static int32_t bssindex; static struct SAA *syms; -static unsigned long nsyms; +static uint32_t nsyms; static struct RAA *bsym; static struct SAA *strs; -static unsigned long strslen; +static uint32_t strslen; static int as86_reloc_size; @@ -77,9 +78,9 @@ static efunc error; static void as86_write(void); static void as86_write_section(struct Section *, int); -static int as86_add_string(char *name); -static void as86_sect_write(struct Section *, const unsigned char *, - unsigned long); +static int as86_add_string(int8_t *name); +static void as86_sect_write(struct Section *, const uint8_t *, + uint32_t); static void as86_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) { @@ -100,7 +101,7 @@ static void as86_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) stext.index = seg_alloc(); sdata.index = seg_alloc(); bssindex = seg_alloc(); - syms = saa_init((long)sizeof(struct Symbol)); + syms = saa_init((int32_t)sizeof(struct Symbol)); nsyms = 0; bsym = raa_init(); strs = saa_init(1L); @@ -134,7 +135,7 @@ static void as86_cleanup(int debuginfo) saa_free(strs); } -static long as86_section_names(char *name, int pass, int *bits) +static int32_t as86_section_names(int8_t *name, int pass, int *bits) { /* * Default is 16 bits. @@ -155,19 +156,19 @@ static long as86_section_names(char *name, int pass, int *bits) return NO_SEG; } -static int as86_add_string(char *name) +static int as86_add_string(int8_t *name) { int pos = strslen; int length = strlen(name); - saa_wbytes(strs, name, (long)(length + 1)); + saa_wbytes(strs, name, (int32_t)(length + 1)); strslen += 1 + length; return pos; } -static void as86_deflabel(char *name, long segment, long offset, - int is_global, char *special) +static void as86_deflabel(int8_t *name, int32_t segment, int32_t offset, + int is_global, int8_t *special) { struct Symbol *sym; @@ -216,8 +217,8 @@ static void as86_deflabel(char *name, long segment, long offset, nsyms++; } -static void as86_add_piece(struct Section *sect, int type, long offset, - long segment, long bytes, int relative) +static void as86_add_piece(struct Section *sect, int type, int32_t offset, + int32_t segment, int32_t bytes, int relative) { struct Piece *p; @@ -247,13 +248,13 @@ static void as86_add_piece(struct Section *sect, int type, long offset, p->number = raa_read(bsym, segment), p->type = 2; } -static void as86_out(long segto, const void *data, unsigned long type, - long segment, long wrt) +static void as86_out(int32_t segto, const void *data, uint32_t type, + int32_t segment, int32_t wrt) { struct Section *s; - long realbytes = type & OUT_SIZMASK; - long offset; - unsigned char mydata[4], *p; + int32_t realbytes = type & OUT_SIZMASK; + int32_t offset; + uint8_t mydata[4], *p; if (wrt != NO_SEG) { wrt = NO_SEG; /* continue to do _something_ */ @@ -285,7 +286,7 @@ static void as86_out(long segto, const void *data, unsigned long type, } if (!s && type != OUT_RESERVE) { - error(ERR_WARNING, "attempt to initialise memory in the" + error(ERR_WARNING, "attempt to initialize memory in the" " BSS section: ignored"); if (type == OUT_REL2ADR) realbytes = 2; @@ -297,7 +298,7 @@ static void as86_out(long segto, const void *data, unsigned long type, if (type == OUT_RESERVE) { if (s) { - error(ERR_WARNING, "uninitialised space declared in" + error(ERR_WARNING, "uninitialized space declared in" " %s section: zeroing", (segto == stext.index ? "code" : "data")); as86_sect_write(s, NULL, realbytes); @@ -315,12 +316,12 @@ static void as86_out(long segto, const void *data, unsigned long type, error(ERR_NONFATAL, "as86 format does not support" " segment base references"); } else { - offset = *(long *)data; + offset = *(int32_t *)data; as86_add_piece(s, 1, offset, segment, realbytes, 0); } } else { p = mydata; - WRITELONG(p, *(long *)data); + WRITELONG(p, *(int32_t *)data); as86_sect_write(s, data, realbytes); as86_add_piece(s, 0, 0L, 0L, realbytes, 0); } @@ -332,7 +333,7 @@ static void as86_out(long segto, const void *data, unsigned long type, error(ERR_NONFATAL, "as86 format does not support" " segment base references"); } else { - offset = *(long *)data; + offset = *(int32_t *)data; as86_add_piece(s, 1, offset - realbytes + 2, segment, 2L, 1); } @@ -345,7 +346,7 @@ static void as86_out(long segto, const void *data, unsigned long type, error(ERR_NONFATAL, "as86 format does not support" " segment base references"); } else { - offset = *(long *)data; + offset = *(int32_t *)data; as86_add_piece(s, 1, offset - realbytes + 4, segment, 4L, 1); } @@ -355,8 +356,8 @@ static void as86_out(long segto, const void *data, unsigned long type, static void as86_write(void) { - unsigned long i; - long symlen, seglen, segsize; + uint32_t i; + int32_t symlen, seglen, segsize; /* * First, go through the symbol records working out how big @@ -385,11 +386,11 @@ static void as86_write(void) * descriptor word at the same time. */ seglen = segsize = 0; - if ((unsigned long)stext.len > 65535L) + if ((uint32_t)stext.len > 65535L) segsize |= 0x03000000L, seglen += 4; else segsize |= 0x02000000L, seglen += 2; - if ((unsigned long)sdata.len > 65535L) + if ((uint32_t)sdata.len > 65535L) segsize |= 0xC0000000L, seglen += 4; else segsize |= 0x80000000L, seglen += 2; @@ -397,23 +398,23 @@ static void as86_write(void) /* * Emit the as86 header. */ - fwritelong(0x000186A3L, as86fp); + fwriteint32_t(0x000186A3L, as86fp); fputc(0x2A, as86fp); - fwritelong(27 + symlen + seglen + strslen, as86fp); /* header length */ - fwritelong(stext.len + sdata.len + bsslen, as86fp); - fwriteshort(strslen, as86fp); - fwriteshort(0, as86fp); /* class = revision = 0 */ - fwritelong(0x55555555L, as86fp); /* segment max sizes: always this */ - fwritelong(segsize, as86fp); /* segment size descriptors */ + fwriteint32_t(27 + symlen + seglen + strslen, as86fp); /* header length */ + fwriteint32_t(stext.len + sdata.len + bsslen, as86fp); + fwriteint16_t(strslen, as86fp); + fwriteint16_t(0, as86fp); /* class = revision = 0 */ + fwriteint32_t(0x55555555L, as86fp); /* segment max sizes: always this */ + fwriteint32_t(segsize, as86fp); /* segment size descriptors */ if (segsize & 0x01000000L) - fwritelong(stext.len, as86fp); + fwriteint32_t(stext.len, as86fp); else - fwriteshort(stext.len, as86fp); + fwriteint16_t(stext.len, as86fp); if (segsize & 0x40000000L) - fwritelong(sdata.len + bsslen, as86fp); + fwriteint32_t(sdata.len + bsslen, as86fp); else - fwriteshort(sdata.len + bsslen, as86fp); - fwriteshort(nsyms, as86fp); + fwriteint16_t(sdata.len + bsslen, as86fp); + fwriteint16_t(nsyms, as86fp); /* * Write the symbol table. @@ -421,8 +422,8 @@ static void as86_write(void) saa_rewind(syms); for (i = 0; i < nsyms; i++) { struct Symbol *sym = saa_rstruct(syms); - fwriteshort(sym->strpos, as86fp); - fwriteshort(sym->flags, as86fp); + fwriteint16_t(sym->strpos, as86fp); + fwriteint16_t(sym->flags, as86fp); switch (sym->flags & (3 << 14)) { case 0 << 14: break; @@ -430,10 +431,10 @@ static void as86_write(void) fputc(sym->value, as86fp); break; case 2 << 14: - fwriteshort(sym->value, as86fp); + fwriteint16_t(sym->value, as86fp); break; case 3 << 14: - fwritelong(sym->value, as86fp); + fwriteint32_t(sym->value, as86fp); break; } } @@ -454,10 +455,10 @@ static void as86_write(void) */ if (bsslen > 65535L) { fputc(0x13, as86fp); - fwritelong(bsslen, as86fp); + fwriteint32_t(bsslen, as86fp); } else if (bsslen > 255) { fputc(0x12, as86fp); - fwriteshort(bsslen, as86fp); + fwriteint16_t(bsslen, as86fp); } else if (bsslen) { fputc(0x11, as86fp); fputc(bsslen, as86fp); @@ -488,8 +489,8 @@ static void as86_set_rsize(int size) static void as86_write_section(struct Section *sect, int index) { struct Piece *p; - unsigned long s; - long length; + uint32_t s; + int32_t length; fputc(0x20 + index, as86fp); /* select the right section */ @@ -504,8 +505,8 @@ static void as86_write_section(struct Section *sect, int index) */ length = p->bytes; do { - char buf[64]; - long tmplen = (length > 64 ? 64 : length); + int8_t buf[64]; + int32_t tmplen = (length > 64 ? 64 : length); fputc(0x40 | (tmplen & 0x3F), as86fp); saa_rnbytes(sect->data, buf, tmplen); fwrite(buf, 1, tmplen, as86fp); @@ -521,9 +522,9 @@ static void as86_write_section(struct Section *sect, int index) as86_set_rsize(p->bytes); fputc(0x80 | (p->relative ? 0x20 : 0) | p->number, as86fp); if (as86_reloc_size == 2) - fwriteshort(p->offset, as86fp); + fwriteint16_t(p->offset, as86fp); else - fwritelong(p->offset, as86fp); + fwriteint32_t(p->offset, as86fp); break; case 2: /* @@ -543,7 +544,7 @@ static void as86_write_section(struct Section *sect, int index) (p->relative ? 0x20 : 0) | (p->number > 255 ? 0x04 : 0) | s, as86fp); if (p->number > 255) - fwriteshort(p->number, as86fp); + fwriteint16_t(p->number, as86fp); else fputc(p->number, as86fp); switch ((int)s) { @@ -553,10 +554,10 @@ static void as86_write_section(struct Section *sect, int index) fputc(p->offset, as86fp); break; case 2: - fwriteshort(p->offset, as86fp); + fwriteint16_t(p->offset, as86fp); break; case 3: - fwritelong(p->offset, as86fp); + fwriteint32_t(p->offset, as86fp); break; } break; @@ -564,25 +565,25 @@ static void as86_write_section(struct Section *sect, int index) } static void as86_sect_write(struct Section *sect, - const unsigned char *data, unsigned long len) + const uint8_t *data, uint32_t len) { saa_wbytes(sect->data, data, len); sect->datalen += len; } -static long as86_segbase(long segment) +static int32_t as86_segbase(int32_t segment) { return segment; } -static int as86_directive(char *directive, char *value, int pass) +static int as86_directive(int8_t *directive, int8_t *value, int pass) { return 0; } -static void as86_filename(char *inname, char *outname, efunc error) +static void as86_filename(int8_t *inname, int8_t *outname, efunc error) { - char *p; + int8_t *p; if ((p = strrchr(inname, '.')) != NULL) { strncpy(as86_module, inname, p - inname); @@ -593,18 +594,18 @@ static void as86_filename(char *inname, char *outname, efunc error) standard_extension(inname, outname, ".o", error); } -static const char *as86_stdmac[] = { +static const int8_t *as86_stdmac[] = { "%define __SECT__ [section .text]", "%macro __NASM_CDecl__ 1", "%endmacro", NULL }; -static int as86_set_info(enum geninfo type, char **val) +static int as86_set_info(enum geninfo type, int8_t **val) { return 0; } -void as86_linenumber(char *name, long segment, long offset, int is_main, +void as86_linenumber(int8_t *name, int32_t segment, int32_t offset, int is_main, int lineno) { } diff --git a/output/outbin.c b/output/outbin.c index 5cadff0..cd46752 100644 --- a/output/outbin.c +++ b/output/outbin.c @@ -48,6 +48,7 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" @@ -75,25 +76,25 @@ static efunc error; /* This struct is used to keep track of symbols for map-file generation. */ static struct bin_label { - char *name; + int8_t *name; struct bin_label *next; } *no_seg_labels, **nsl_tail; static struct Section { - char *name; + int8_t *name; struct SAA *contents; - long length; /* section length in bytes */ + int32_t length; /* section length in bytes */ /* Section attributes */ int flags; /* see flag definitions above */ - unsigned long align; /* section alignment */ - unsigned long valign; /* notional section alignment */ - unsigned long start; /* section start address */ - unsigned long vstart; /* section virtual start address */ - char *follows; /* the section that this one will follow */ - char *vfollows; /* the section that this one will notionally follow */ - long start_index; /* NASM section id for non-relocated version */ - long vstart_index; /* the NASM section id */ + uint32_t align; /* section alignment */ + uint32_t valign; /* notional section alignment */ + uint32_t start; /* section start address */ + uint32_t vstart; /* section virtual start address */ + int8_t *follows; /* the section that this one will follow */ + int8_t *vfollows; /* the section that this one will notionally follow */ + int32_t start_index; /* NASM section id for non-relocated version */ + int32_t vstart_index; /* the NASM section id */ struct bin_label *labels; /* linked-list of label handles for map output. */ struct bin_label **labels_end; /* Holds address of end of labels list. */ @@ -112,19 +113,19 @@ static struct Section { static struct Reloc { struct Reloc *next; - long posn; - long bytes; - long secref; - long secrel; + int32_t posn; + int32_t bytes; + int32_t secref; + int32_t secrel; struct Section *target; } *relocs, **reloctail; -extern char *stdscan_bufptr; -extern int lookup_label(char *label, long *segment, long *offset); +extern int8_t *stdscan_bufptr; +extern int lookup_label(int8_t *label, int32_t *segment, int32_t *offset); -static unsigned char format_mode; /* 0 = original bin, 1 = extended bin */ -static long current_section; /* only really needed if format_mode = 0 */ -static unsigned long origin; +static uint8_t format_mode; /* 0 = original bin, 1 = extended bin */ +static int32_t current_section; /* only really needed if format_mode = 0 */ +static uint32_t origin; static int origin_defined; /* Stuff we need for map-file generation. */ @@ -133,9 +134,9 @@ static int origin_defined; #define MAP_SECTIONS 4 #define MAP_SYMBOLS 8 static int map_control = 0; -static char *infile, *outfile; +static int8_t *infile, *outfile; -static const char *bin_stdmac[] = { +static const int8_t *bin_stdmac[] = { "%define __SECT__ [section .text]", "%imacro org 1+.nolist", "[org %1]", @@ -145,8 +146,8 @@ static const char *bin_stdmac[] = { NULL }; -static void add_reloc(struct Section *s, long bytes, long secref, - long secrel) +static void add_reloc(struct Section *s, int32_t bytes, int32_t secref, + int32_t secrel) { struct Reloc *r; @@ -160,7 +161,7 @@ static void add_reloc(struct Section *s, long bytes, long secref, r->target = s; } -static struct Section *find_section_by_name(const char *name) +static struct Section *find_section_by_name(const int8_t *name) { struct Section *s; @@ -170,7 +171,7 @@ static struct Section *find_section_by_name(const char *name) return s; } -static struct Section *find_section_by_index(long index) +static struct Section *find_section_by_index(int32_t index) { struct Section *s; @@ -180,7 +181,7 @@ static struct Section *find_section_by_index(long index) return s; } -static struct Section *create_section(char *name) +static struct Section *create_section(int8_t *name) { /* Create a new section. */ last_section->next = nasm_malloc(sizeof(struct Section)); last_section->next->ifollows = last_section; @@ -211,7 +212,7 @@ static void bin_cleanup(int debuginfo) struct Section *last_progbits; struct bin_label *l; struct Reloc *r; - unsigned long pend; + uint32_t pend; int h; #ifdef DEBUG @@ -517,18 +518,24 @@ static void bin_cleanup(int debuginfo) saa_rewind(s->contents); /* Apply relocations. */ for (r = relocs; r; r = r->next) { - unsigned char *p, *q, mydata[4]; - long l; + uint8_t *p, *q, mydata[8]; + int64_t l; saa_fread(r->target->contents, r->posn, mydata, r->bytes); p = q = mydata; l = *p++; if (r->bytes > 1) { - l += ((long)*p++) << 8; - if (r->bytes == 4) { - l += ((long)*p++) << 16; - l += ((long)*p++) << 24; + l += ((int64_t)*p++) << 8; + if (r->bytes >= 4) { + l += ((int64_t)*p++) << 16; + l += ((int64_t)*p++) << 24; + } + if (r->bytes == 8) { + l += ((int64_t)*p++) << 32; + l += ((int64_t)*p++) << 40; + l += ((int64_t)*p++) << 48; + l += ((int64_t)*p++) << 56; } } @@ -546,13 +553,13 @@ static void bin_cleanup(int debuginfo) else l -= s->vstart; } - - if (r->bytes == 4) - WRITELONG(q, l); + + if (r->bytes >= 4) + WRITEDLONG(q, l); else if (r->bytes == 2) WRITESHORT(q, l); else - *q++ = (unsigned char)(l & 0xFF); + *q++ = (uint8_t)(l & 0xFF); saa_fwrite(r->target->contents, r->posn, mydata, r->bytes); } @@ -576,7 +583,7 @@ static void bin_cleanup(int debuginfo) /* Step 7: Generate the map file. */ if (map_control) { - const char *not_defined = { "not defined" }; + const int8_t *not_defined = { "not defined" }; /* Display input and output file names. */ fprintf(rf, "\n- NASM Map file "); @@ -651,7 +658,7 @@ static void bin_cleanup(int debuginfo) } /* Display symbols information. */ if (map_control & MAP_SYMBOLS) { - long segment, offset; + int32_t segment, offset; fprintf(rf, "-- Symbols "); for (h = 68; h; h--) @@ -725,13 +732,14 @@ static void bin_cleanup(int debuginfo) } } -static void bin_out(long segto, const void *data, unsigned long type, - long segment, long wrt) +static void bin_out(int32_t segto, const void *data, uint32_t type, + int32_t segment, int32_t wrt) { - unsigned char *p, mydata[4]; + uint8_t *p, mydata[8]; struct Section *s; - long realbytes; - + int32_t realbytes; + + if (wrt != NO_SEG) { wrt = NO_SEG; /* continue to do _something_ */ error(ERR_NONFATAL, "WRT not supported by binary output format"); @@ -749,7 +757,7 @@ static void bin_out(long segto, const void *data, unsigned long type, s = find_section_by_index(segto); if (!s) error(ERR_PANIC, "code directed to nonexistent segment?"); - + /* "Smart" section-type adaptation code. */ if (!(s->flags & TYPE_DEFINED)) { if ((type & OUT_TYPMASK) == OUT_RESERVE) @@ -759,7 +767,7 @@ static void bin_out(long segto, const void *data, unsigned long type, } if ((s->flags & TYPE_NOBITS) && ((type & OUT_TYPMASK) != OUT_RESERVE)) - error(ERR_WARNING, "attempt to initialise memory in a" + error(ERR_WARNING, "attempt to initialize memory in a" " nobits section: ignored"); if ((type & OUT_TYPMASK) == OUT_ADDRESS) { @@ -777,9 +785,11 @@ static void bin_out(long segto, const void *data, unsigned long type, add_reloc(s, type & OUT_SIZMASK, segment, -1L); p = mydata; if ((type & OUT_SIZMASK) == 4) - WRITELONG(p, *(long *)data); + WRITELONG(p, *(int32_t *)data); + else if ((type & OUT_SIZMASK) == 8) + WRITEDLONG(p, *(int64_t *)data); else - WRITESHORT(p, *(long *)data); + WRITESHORT(p, *(int32_t *)data); saa_wbytes(s->contents, mydata, type & OUT_SIZMASK); } s->length += type & OUT_SIZMASK; @@ -791,14 +801,18 @@ static void bin_out(long segto, const void *data, unsigned long type, } else if ((type & OUT_TYPMASK) == OUT_RESERVE) { type &= OUT_SIZMASK; if (s->flags & TYPE_PROGBITS) { - error(ERR_WARNING, "uninitialised space declared in" + error(ERR_WARNING, "uninitialized space declared in" " %s section: zeroing", s->name); saa_wbytes(s->contents, NULL, type); } s->length += type; } else if ((type & OUT_TYPMASK) == OUT_REL2ADR || (type & OUT_TYPMASK) == OUT_REL4ADR) { - realbytes = ((type & OUT_TYPMASK) == OUT_REL4ADR ? 4 : 2); + realbytes = (type & OUT_TYPMASK); + if (realbytes == OUT_REL2ADR) + realbytes = 2; + else + realbytes = 4; if (segment != NO_SEG && !find_section_by_index(segment)) { if (segment % 2) error(ERR_NONFATAL, "binary output format does not support" @@ -812,17 +826,17 @@ static void bin_out(long segto, const void *data, unsigned long type, add_reloc(s, realbytes, segment, segto); p = mydata; if (realbytes == 4) - WRITELONG(p, *(long *)data - realbytes - s->length); + WRITELONG(p, *(int32_t *)data - realbytes - s->length); else - WRITESHORT(p, *(long *)data - realbytes - s->length); + WRITESHORT(p, *(int32_t *)data - realbytes - s->length); saa_wbytes(s->contents, mydata, realbytes); } s->length += realbytes; } } -static void bin_deflabel(char *name, long segment, long offset, - int is_global, char *special) +static void bin_deflabel(int8_t *name, int32_t segment, int32_t offset, + int is_global, int8_t *special) { (void)segment; /* Don't warn that this parameter is unused */ (void)offset; /* Don't warn that this parameter is unused */ @@ -862,13 +876,13 @@ enum { ATTRIB_START, ATTRIB_ALIGN, ATTRIB_FOLLOWS, ATTRIB_NOBITS, ATTRIB_PROGBITS }; -static int bin_read_attribute(char **line, int *attribute, - unsigned long *value) +static int bin_read_attribute(int8_t **line, int *attribute, + uint32_t *value) { expr *e; int attrib_name_size; struct tokenval tokval; - char *exp; + int8_t *exp; /* Skip whitespace. */ while (**line && isspace(**line)) @@ -924,7 +938,7 @@ static int bin_read_attribute(char **line, int *attribute, (*line)++; } } else { - char c; + int8_t c; int pcount = 1; /* Full expression (delimited by parenthesis) */ @@ -986,15 +1000,15 @@ static int bin_read_attribute(char **line, int *attribute, " specified in `section' directive."); return -1; } - *value = (unsigned long)reloc_value(e); + *value = (uint32_t)reloc_value(e); return 1; } -static void bin_assign_attributes(struct Section *sec, char *astring) +static void bin_assign_attributes(struct Section *sec, int8_t *astring) { int attribute, check; - unsigned long value; - char *p; + uint32_t value; + int8_t *p; while (1) { /* Get the next attribute. */ check = bin_read_attribute(&astring, &attribute, &value); @@ -1182,7 +1196,7 @@ static void bin_define_section_labels() { static int labels_defined = 0; struct Section *sec; - char *label_name; + int8_t *label_name; size_t base_len; if (labels_defined) @@ -1208,9 +1222,9 @@ static void bin_define_section_labels() labels_defined = 1; } -static long bin_secname(char *name, int pass, int *bits) +static int32_t bin_secname(int8_t *name, int pass, int *bits) { - char *p; + int8_t *p; struct Section *sec; /* bin_secname is called with *name = NULL at the start of each @@ -1274,12 +1288,12 @@ static long bin_secname(char *name, int pass, int *bits) return current_section; } -static int bin_directive(char *directive, char *args, int pass) +static int bin_directive(int8_t *directive, int8_t *args, int pass) { /* Handle ORG directive */ if (!nasm_stricmp(directive, "org")) { struct tokenval tokval; - unsigned long value; + uint32_t value; expr *e; stdscan_reset(); @@ -1309,7 +1323,7 @@ static int bin_directive(char *directive, char *args, int pass) /* The 'map' directive allows the user to generate section * and symbol information to stdout, stderr, or to a file. */ else if (format_mode && !nasm_stricmp(directive, "map")) { - char *p; + int8_t *p; if (pass != 1) return 1; @@ -1356,19 +1370,19 @@ static int bin_directive(char *directive, char *args, int pass) return 0; } -static void bin_filename(char *inname, char *outname, efunc error) +static void bin_filename(int8_t *inname, int8_t *outname, efunc error) { standard_extension(inname, outname, "", error); infile = inname; outfile = outname; } -static long bin_segbase(long segment) +static int32_t bin_segbase(int32_t segment) { return segment; } -static int bin_set_info(enum geninfo type, char **val) +static int bin_set_info(enum geninfo type, int8_t **val) { return 0; } @@ -1381,6 +1395,7 @@ static void bin_init(FILE * afp, efunc errfunc, ldfunc ldef, evalfunc eval) (void)eval; /* Don't warn that this parameter is unused. */ (void)ldef; /* Placate optimizers. */ + maxbits = 64; /* Support 64-bit Segments */ relocs = NULL; reloctail = &relocs; origin_defined = 0; diff --git a/output/outcoff.c b/output/outcoff.c index 547f4db..bdcc4ce 100644 --- a/output/outcoff.c +++ b/output/outcoff.c @@ -12,12 +12,13 @@ #include <string.h> #include <ctype.h> #include <time.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" #include "outform.h" -#if defined(OF_COFF) || defined(OF_WIN32) +#if defined(OF_COFF) || defined(OF_WIN32) || defined(OF_WIN64) /* * Notes on COFF: @@ -60,87 +61,97 @@ */ /* Flag which version of COFF we are currently outputting. */ -static int win32; +static int win32, win64; struct Reloc { struct Reloc *next; - long address; /* relative to _start_ of section */ - long symbol; /* symbol number */ + int32_t address; /* relative to _start_ of section */ + int32_t symbol; /* symbol number */ enum { SECT_SYMBOLS, ABS_SYMBOL, REAL_SYMBOLS } symbase; /* relocation for symbol number :) */ int relative; /* TRUE or FALSE */ + int size64; /* TRUE or FALSE */ }; struct Symbol { - char name[9]; - long strpos; /* string table position of name */ + int8_t name[9]; + int32_t strpos; /* string table position of name */ int section; /* section number where it's defined * - in COFF codes, not NASM codes */ int is_global; /* is it a global symbol or not? */ - long value; /* address, or COMMON variable size */ + int32_t value; /* address, or COMMON variable size */ }; static FILE *coffp; static efunc error; -static char coff_infile[FILENAME_MAX]; +static int8_t coff_infile[FILENAME_MAX]; struct Section { struct SAA *data; - unsigned long len; + uint32_t len; int nrelocs; - long index; + int32_t index; struct Reloc *head, **tail; - unsigned long flags; /* section flags */ - char name[9]; - long pos, relpos; + uint32_t flags; /* section flags */ + int8_t name[9]; + int32_t pos, relpos; }; -#define TEXT_FLAGS (win32 ? 0x60500020L : 0x20L) -#define DATA_FLAGS (win32 ? 0xC0300040L : 0x40L) -#define BSS_FLAGS (win32 ? 0xC0300080L : 0x80L) +#define TEXT_FLAGS ((win32 | win64) ? 0x60500020L : 0x20L) +#define DATA_FLAGS ((win32 | win64) ? 0xC0300040L : 0x40L) +#define BSS_FLAGS ((win32 | win64) ? 0xC0300080L : 0x80L) #define INFO_FLAGS 0x00100A00L -#define RDATA_FLAGS (win32 ? 0x40400040L : 0x40L) +#define RDATA_FLAGS ((win32 | win64) ? 0x40400040L : 0x40L) #define SECT_DELTA 32 static struct Section **sects; static int nsects, sectlen; static struct SAA *syms; -static unsigned long nsyms; +static uint32_t nsyms; -static long def_seg; +static int32_t def_seg; static int initsym; static struct RAA *bsym, *symval; static struct SAA *strs; -static unsigned long strslen; +static uint32_t strslen; static void coff_gen_init(FILE *, efunc); -static void coff_sect_write(struct Section *, const unsigned char *, - unsigned long); +static void coff_sect_write(struct Section *, const uint8_t *, + uint32_t); static void coff_write(void); -static void coff_section_header(char *, long, long, long, long, int, long); +static void coff_section_header(int8_t *, int32_t, int32_t, int32_t, int32_t, int, int32_t); static void coff_write_relocs(struct Section *); static void coff_write_symbols(void); static void coff_win32_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) { - win32 = TRUE; - (void)ldef; /* placate optimisers */ + win32 = TRUE; win64 = FALSE; + (void)ldef; /* placate optimizers */ + coff_gen_init(fp, errfunc); +} + +static void coff_win64_init(FILE * fp, efunc errfunc, + ldfunc ldef, evalfunc eval) +{ + maxbits = 64; + win32 = FALSE; win64 = TRUE; + (void)ldef; /* placate optimizers */ coff_gen_init(fp, errfunc); } static void coff_std_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) { - win32 = FALSE; - (void)ldef; /* placate optimisers */ + win32 = win64 = FALSE; + (void)ldef; /* placate optimizers */ coff_gen_init(fp, errfunc); } @@ -151,7 +162,7 @@ static void coff_gen_init(FILE * fp, efunc errfunc) error = errfunc; sects = NULL; nsects = sectlen = 0; - syms = saa_init((long)sizeof(struct Symbol)); + syms = saa_init((int32_t)sizeof(struct Symbol)); nsyms = 0; bsym = raa_init(); symval = raa_init(); @@ -186,7 +197,7 @@ static void coff_cleanup(int debuginfo) saa_free(strs); } -static int coff_make_section(char *name, unsigned long flags) +static int coff_make_section(int8_t *name, uint32_t flags) { struct Section *s; @@ -216,17 +227,21 @@ static int coff_make_section(char *name, unsigned long flags) return nsects - 1; } -static long coff_section_names(char *name, int pass, int *bits) +static int32_t coff_section_names(int8_t *name, int pass, int *bits) { - char *p; - unsigned long flags, align_and = ~0L, align_or = 0L; + int8_t *p; + uint32_t flags, align_and = ~0L, align_or = 0L; int i; /* - * Default is 32 bits. + * Set default bits. */ - if (!name) - *bits = 32; + if (!name) { + if(win64) + *bits = 64; + else + *bits = 32; + } if (!name) return def_seg; @@ -246,7 +261,7 @@ static long coff_section_names(char *name, int pass, int *bits) while (*p && isspace(*p)) p++; while (*p) { - char *q = p; + int8_t *q = p; while (*p && !isspace(*p)) p++; if (*p) @@ -259,7 +274,7 @@ static long coff_section_names(char *name, int pass, int *bits) } else if (!nasm_stricmp(q, "data")) { flags = DATA_FLAGS; } else if (!nasm_stricmp(q, "rdata")) { - if (win32) + if (win32 | win64) flags = RDATA_FLAGS; else { flags = DATA_FLAGS; /* gotta do something */ @@ -269,7 +284,7 @@ static long coff_section_names(char *name, int pass, int *bits) } else if (!nasm_stricmp(q, "bss")) { flags = BSS_FLAGS; } else if (!nasm_stricmp(q, "info")) { - if (win32) + if (win32 | win64) flags = INFO_FLAGS; else { flags = DATA_FLAGS; /* gotta do something */ @@ -277,7 +292,7 @@ static long coff_section_names(char *name, int pass, int *bits) " informational sections"); } } else if (!nasm_strnicmp(q, "align=", 6)) { - if (!win32) + if (!(win32 | win64)) error(ERR_NONFATAL, "standard COFF does not support" " section alignment specification"); else { @@ -335,8 +350,8 @@ static long coff_section_names(char *name, int pass, int *bits) return sects[i]->index; } -static void coff_deflabel(char *name, long segment, long offset, - int is_global, char *special) +static void coff_deflabel(int8_t *name, int32_t segment, int32_t offset, + int is_global, int8_t *special) { int pos = strslen + 4; struct Symbol *sym; @@ -346,12 +361,12 @@ static void coff_deflabel(char *name, long segment, long offset, " special symbol types"); if (name[0] == '.' && name[1] == '.' && name[2] != '@') { - error(ERR_NONFATAL, "unrecognised special symbol `%s'", name); + error(ERR_NONFATAL, "unrecognized special symbol `%s'", name); return; } if (strlen(name) > 8) { - saa_wbytes(strs, name, (long)(1 + strlen(name))); + saa_wbytes(strs, name, (int32_t)(1 + strlen(name))); strslen += 1 + strlen(name); } else pos = -1; @@ -384,8 +399,9 @@ static void coff_deflabel(char *name, long segment, long offset, * define the references from external-symbol segment numbers * to these symbol records. */ - if (sym->section == 0) + if (sym->section == 0) { bsym = raa_write(bsym, segment, nsyms); + } if (segment != NO_SEG) symval = raa_write(symval, segment, sym->section ? 0 : sym->value); @@ -393,8 +409,8 @@ static void coff_deflabel(char *name, long segment, long offset, nsyms++; } -static long coff_add_reloc(struct Section *sect, long segment, - int relative) +static int32_t coff_add_reloc(struct Section *sect, int32_t segment, + int relative, int size64) { struct Reloc *r; @@ -424,18 +440,18 @@ static long coff_add_reloc(struct Section *sect, long segment, /* * Return the fixup for standard COFF common variables. */ - if (r->symbase == REAL_SYMBOLS && !win32) + if (r->symbase == REAL_SYMBOLS && !(win32 | win64)) return raa_read(symval, segment); else return 0; } -static void coff_out(long segto, const void *data, unsigned long type, - long segment, long wrt) +static void coff_out(int32_t segto, const void *data, uint32_t type, + int32_t segment, int32_t wrt) { struct Section *s; - long realbytes = type & OUT_SIZMASK; - unsigned char mydata[4], *p; + int32_t realbytes = type & OUT_SIZMASK; + uint8_t mydata[8], *p; int i; if (wrt != NO_SEG) { @@ -470,7 +486,7 @@ static void coff_out(long segto, const void *data, unsigned long type, } if (!s->data && type != OUT_RESERVE) { - error(ERR_WARNING, "attempt to initialise memory in" + error(ERR_WARNING, "attempt to initialize memory in" " BSS section `%s': ignored", s->name); if (type == OUT_REL2ADR) realbytes = 2; @@ -492,12 +508,31 @@ static void coff_out(long segto, const void *data, unsigned long type, error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG"); coff_sect_write(s, data, realbytes); } else if (type == OUT_ADDRESS) { - if (realbytes != 4 && (segment != NO_SEG || wrt != NO_SEG)) - error(ERR_NONFATAL, "COFF format does not support non-32-bit" - " relocations"); - else { - long fix = 0; - if (segment != NO_SEG || wrt != NO_SEG) { + if (!(win64)) { + if (realbytes != 4 && (segment != NO_SEG || wrt != NO_SEG)) + error(ERR_NONFATAL, "COFF format does not support non-32-bit" + " relocations"); + else { + int32_t fix = 0; + if (segment != NO_SEG || wrt != NO_SEG) { + if (wrt != NO_SEG) { + error(ERR_NONFATAL, "COFF format does not support" + " WRT types"); + } else if (segment % 2) { + error(ERR_NONFATAL, "COFF format does not support" + " segment base references"); + } else + fix = coff_add_reloc(s, segment, FALSE, FALSE); + } + p = mydata; + WRITELONG(p, *(int32_t *)data + fix); + coff_sect_write(s, mydata, realbytes); + } + } else { + int32_t fix = 0; + p = mydata; + if (realbytes == 8) { +/* if (segment != NO_SEG || wrt != NO_SEG) { if (wrt != NO_SEG) { error(ERR_NONFATAL, "COFF format does not support" " WRT types"); @@ -506,40 +541,46 @@ static void coff_out(long segto, const void *data, unsigned long type, " segment base references"); } else fix = coff_add_reloc(s, segment, FALSE); + } */ + fix = coff_add_reloc(s, segment, FALSE, TRUE); + WRITEDLONG(p, *(int64_t *)data + fix); + coff_sect_write(s, mydata, realbytes); + } else { + fix = coff_add_reloc(s, segment, FALSE, FALSE); + WRITELONG(p, *(int32_t *)data + fix); + coff_sect_write(s, mydata, realbytes); } - p = mydata; - WRITELONG(p, *(long *)data + fix); - coff_sect_write(s, mydata, realbytes); } } else if (type == OUT_REL2ADR) { error(ERR_NONFATAL, "COFF format does not support 16-bit" " relocations"); } else if (type == OUT_REL4ADR) { - if (segment == segto) + if (segment == segto && !(win64)) /* Acceptable for RIP-relative */ error(ERR_PANIC, "intra-segment OUT_REL4ADR"); else if (segment == NO_SEG && win32) error(ERR_NONFATAL, "Win32 COFF does not correctly support" " relative references to absolute addresses"); else { - long fix = 0; + int32_t fix = 0; if (segment != NO_SEG && segment % 2) { error(ERR_NONFATAL, "COFF format does not support" " segment base references"); } else - fix = coff_add_reloc(s, segment, TRUE); + fix = coff_add_reloc(s, segment, TRUE, FALSE); p = mydata; - if (win32) { - WRITELONG(p, *(long *)data + 4 - realbytes + fix); + if (win32 | win64) { + WRITELONG(p, *(int32_t *)data + 4 - realbytes + fix); } else { - WRITELONG(p, *(long *)data - (realbytes + s->len) + fix); + WRITELONG(p, *(int32_t *)data - (realbytes + s->len) + fix); } coff_sect_write(s, mydata, 4L); } + } } static void coff_sect_write(struct Section *sect, - const unsigned char *data, unsigned long len) + const uint8_t *data, uint32_t len) { saa_wbytes(sect->data, data, len); sect->len += len; @@ -548,7 +589,7 @@ static void coff_sect_write(struct Section *sect, typedef struct tagString { struct tagString *Next; int len; - char *String; + int8_t *String; } STRING; #define EXPORT_SECTION_NAME ".drectve" @@ -560,14 +601,14 @@ typedef struct tagString { static STRING *Exports = NULL; static struct Section *directive_sec; -void AddExport(char *name) +void AddExport(int8_t *name) { STRING *rvp = Exports, *newS; newS = (STRING *) nasm_malloc(sizeof(STRING)); newS->len = strlen(name); newS->Next = NULL; - newS->String = (char *)nasm_malloc(newS->len + 1); + newS->String = (int8_t *)nasm_malloc(newS->len + 1); strcpy(newS->String, name); if (rvp == NULL) { int i; @@ -595,12 +636,12 @@ void AddExport(char *name) void BuildExportTable(void) { STRING *rvp = Exports, *next; - unsigned char buf[256]; + uint8_t buf[256]; int len; if (rvp == NULL) return; while (rvp) { - len = sprintf((char *)buf, "-export:%s ", rvp->String); + len = sprintf((int8_t *)buf, "-export:%s ", rvp->String); coff_sect_write(directive_sec, buf, len); rvp = rvp->Next; } @@ -614,10 +655,10 @@ void BuildExportTable(void) Exports = NULL; } -static int coff_directives(char *directive, char *value, int pass) +static int coff_directives(int8_t *directive, int8_t *value, int pass) { if (!strcmp(directive, "export")) { - char *q, *name; + int8_t *q, *name; if (pass == 2) return 1; /* ignore in pass two */ @@ -635,7 +676,7 @@ static int coff_directives(char *directive, char *value, int pass) return 1; } if (*q) { - error(ERR_NONFATAL, "unrecognised export qualifier `%s'", q); + error(ERR_NONFATAL, "unrecognized export qualifier `%s'", q); return 1; } AddExport(name); @@ -646,7 +687,7 @@ static int coff_directives(char *directive, char *value, int pass) static void coff_write(void) { - long pos, sympos, vsize; + int32_t pos, sympos, vsize; int i; BuildExportTable(); /* fill in the .drectve section with -export's */ @@ -671,14 +712,17 @@ static void coff_write(void) /* * Output the COFF header. */ - fwriteshort(0x14C, coffp); /* MACHINE_i386 */ - fwriteshort(nsects, coffp); /* number of sections */ - fwritelong(time(NULL), coffp); /* time stamp */ - fwritelong(sympos, coffp); - fwritelong(nsyms + initsym, coffp); - fwriteshort(0, coffp); /* no optional header */ + if (win64) + fwriteint16_t(0x8664, coffp); /* MACHINE_x86-64 */ + else + fwriteint16_t(0x014C, coffp); /* MACHINE_i386 */ + fwriteint16_t(nsects, coffp); /* number of sections */ + fwriteint32_t(time(NULL), coffp); /* time stamp */ + fwriteint32_t(sympos, coffp); + fwriteint32_t(nsyms + initsym, coffp); + fwriteint16_t(0, coffp); /* no optional header */ /* Flags: 32-bit, no line numbers. Win32 doesn't even bother with them. */ - fwriteshort(win32 ? 0 : 0x104, coffp); + fwriteint16_t((win32 | win64) ? 0 : 0x104, coffp); /* * Output the section headers. @@ -704,28 +748,28 @@ static void coff_write(void) * Output the symbol and string tables. */ coff_write_symbols(); - fwritelong(strslen + 4, coffp); /* length includes length count */ + fwriteint32_t(strslen + 4, coffp); /* length includes length count */ saa_fpwrite(strs, coffp); } -static void coff_section_header(char *name, long vsize, - long datalen, long datapos, - long relpos, int nrelocs, long flags) +static void coff_section_header(int8_t *name, int32_t vsize, + int32_t datalen, int32_t datapos, + int32_t relpos, int nrelocs, int32_t flags) { - char padname[8]; + int8_t padname[8]; memset(padname, 0, 8); strncpy(padname, name, 8); fwrite(padname, 8, 1, coffp); - fwritelong(vsize, coffp); - fwritelong(0L, coffp); /* RVA/offset - we ignore */ - fwritelong(datalen, coffp); - fwritelong(datapos, coffp); - fwritelong(relpos, coffp); - fwritelong(0L, coffp); /* no line numbers - we don't do 'em */ - fwriteshort(nrelocs, coffp); - fwriteshort(0, coffp); /* again, no line numbers */ - fwritelong(flags, coffp); + fwriteint32_t(vsize, coffp); + fwriteint32_t(0L, coffp); /* RVA/offset - we ignore */ + fwriteint32_t(datalen, coffp); + fwriteint32_t(datapos, coffp); + fwriteint32_t(relpos, coffp); + fwriteint32_t(0L, coffp); /* no line numbers - we don't do 'em */ + fwriteint16_t(nrelocs, coffp); + fwriteint16_t(0, coffp); /* again, no line numbers */ + fwriteint32_t(flags, coffp); } static void coff_write_relocs(struct Section *s) @@ -733,8 +777,8 @@ static void coff_write_relocs(struct Section *s) struct Reloc *r; for (r = s->head; r; r = r->next) { - fwritelong(r->address, coffp); - fwritelong(r->symbol + (r->symbase == REAL_SYMBOLS ? initsym : + fwriteint32_t(r->address, coffp); + fwriteint32_t(r->symbol + (r->symbase == REAL_SYMBOLS ? initsym : r->symbase == ABS_SYMBOL ? initsym - 1 : r->symbase == SECT_SYMBOLS ? 2 : 0), coffp); @@ -742,36 +786,39 @@ static void coff_write_relocs(struct Section *s) * Strange: Microsoft's COFF documentation says 0x03 for an * absolute relocation, but both Visual C++ and DJGPP agree * that in fact it's 0x06. I'll use 0x06 until someone - * argues. + * argues. ***** UPDATE: PE/COFF Ver.8 docs confirm this -kkanios ***** */ - fwriteshort(r->relative ? 0x14 : 0x06, coffp); + if (win64) + fwriteint16_t(r->relative ? 0x04 : r->size64 ? 0x01 : 0x02, coffp); + else + fwriteint16_t(r->relative ? 0x14 : 0x06, coffp); } } -static void coff_symbol(char *name, long strpos, long value, +static void coff_symbol(int8_t *name, int32_t strpos, int32_t value, int section, int type, int aux) { - char padname[8]; + int8_t padname[8]; if (name) { memset(padname, 0, 8); strncpy(padname, name, 8); fwrite(padname, 8, 1, coffp); } else { - fwritelong(0L, coffp); - fwritelong(strpos, coffp); + fwriteint32_t(0L, coffp); + fwriteint32_t(strpos, coffp); } - fwritelong(value, coffp); - fwriteshort(section, coffp); - fwriteshort(0, coffp); + fwriteint32_t(value, coffp); + fwriteint16_t(section, coffp); + fwriteint16_t(0, coffp); fputc(type, coffp); fputc(aux, coffp); } static void coff_write_symbols(void) { - char filename[18]; - unsigned long i; + int8_t filename[18]; + uint32_t i; /* * The `.file' record, and the file name auxiliary record. @@ -788,8 +835,8 @@ static void coff_write_symbols(void) for (i = 0; i < nsects; i++) { coff_symbol(sects[i]->name, 0L, 0L, i + 1, 3, 1); - fwritelong(sects[i]->len, coffp); - fwriteshort(sects[i]->nrelocs, coffp); + fwriteint32_t(sects[i]->len, coffp); + fwriteint16_t(sects[i]->nrelocs, coffp); fwrite(filename, 12, 1, coffp); } @@ -810,24 +857,24 @@ static void coff_write_symbols(void) } } -static long coff_segbase(long segment) +static int32_t coff_segbase(int32_t segment) { return segment; } -static void coff_std_filename(char *inname, char *outname, efunc error) +static void coff_std_filename(int8_t *inname, int8_t *outname, efunc error) { strcpy(coff_infile, inname); standard_extension(inname, outname, ".o", error); } -static void coff_win32_filename(char *inname, char *outname, efunc error) +static void coff_win32_filename(int8_t *inname, int8_t *outname, efunc error) { strcpy(coff_infile, inname); standard_extension(inname, outname, ".obj", error); } -static const char *coff_stdmac[] = { +static const int8_t *coff_stdmac[] = { "%define __SECT__ [section .text]", "%macro __NASM_CDecl__ 1", "%endmacro", @@ -837,7 +884,7 @@ static const char *coff_stdmac[] = { NULL }; -static int coff_set_info(enum geninfo type, char **val) +static int coff_set_info(enum geninfo type, int8_t **val) { return 0; } @@ -886,3 +933,25 @@ struct ofmt of_win32 = { }; #endif + +#ifdef OF_WIN64 + +struct ofmt of_win64 = { + "Microsoft Win64 (x86-64) object files", + "win64", + NULL, + null_debug_arr, + &null_debug_form, + coff_stdmac, + coff_win64_init, + coff_set_info, + coff_out, + coff_deflabel, + coff_section_names, + coff_segbase, + coff_directives, + coff_win32_filename, + coff_cleanup +}; + +#endif diff --git a/output/outdbg.c b/output/outdbg.c index 5000407..d7bcb48 100644 --- a/output/outdbg.c +++ b/output/outdbg.c @@ -11,6 +11,7 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" @@ -20,8 +21,8 @@ struct Section { struct Section *next; - long number; - char *name; + int32_t number; + int8_t *name; } *dbgsect; FILE *dbgf; @@ -54,7 +55,7 @@ static void dbg_cleanup(int debuginfo) fclose(dbgf); } -static long dbg_section_names(char *name, int pass, int *bits) +static int32_t dbg_section_names(int8_t *name, int pass, int *bits) { int seg; @@ -69,7 +70,7 @@ static long dbg_section_names(char *name, int pass, int *bits) seg = seg_alloc()); else { int n = strcspn(name, " \t"); - char *sname = nasm_strndup(name, n); + int8_t *sname = nasm_strndup(name, n); struct Section *s; seg = NO_SEG; @@ -90,8 +91,8 @@ static long dbg_section_names(char *name, int pass, int *bits) return seg; } -static void dbg_deflabel(char *name, long segment, long offset, - int is_global, char *special) +static void dbg_deflabel(int8_t *name, int32_t segment, int32_t offset, + int is_global, int8_t *special) { fprintf(dbgf, "deflabel %s := %08lx:%08lx %s (%d)%s%s\n", name, segment, offset, @@ -99,11 +100,11 @@ static void dbg_deflabel(char *name, long segment, long offset, is_global, special ? ": " : "", special); } -static void dbg_out(long segto, void *data, unsigned long type, - long segment, long wrt) +static void dbg_out(int32_t segto, void *data, uint32_t type, + int32_t segment, int32_t wrt) { - long realbytes = type & OUT_SIZMASK; - long ldata; + int32_t realbytes = type & OUT_SIZMASK; + int32_t ldata; int id; type &= OUT_TYPMASK; @@ -117,8 +118,8 @@ static void dbg_out(long segto, void *data, unsigned long type, case OUT_RAWDATA: fprintf(dbgf, "raw data = "); while (realbytes--) { - id = *(unsigned char *)data; - data = (char *)data + 1; + id = *(uint8_t *)data; + data = (int8_t *)data + 1; fprintf(dbgf, "%02x ", id); } fprintf(dbgf, "\n"); @@ -126,20 +127,20 @@ static void dbg_out(long segto, void *data, unsigned long type, case OUT_ADDRESS: ldata = 0; /* placate gcc */ if (realbytes == 1) - ldata = *((char *)data); + ldata = *((int8_t *)data); else if (realbytes == 2) - ldata = *((short *)data); + ldata = *((int16_t *)data); else if (realbytes == 4) - ldata = *((long *)data); + ldata = *((int32_t *)data); fprintf(dbgf, "addr %08lx (seg %08lx, wrt %08lx)\n", ldata, segment, wrt); break; case OUT_REL2ADR: - fprintf(dbgf, "rel2adr %04x (seg %08lx)\n", (int)*(short *)data, + fprintf(dbgf, "rel2adr %04x (seg %08lx)\n", (int)*(int16_t *)data, segment); break; case OUT_REL4ADR: - fprintf(dbgf, "rel4adr %08lx (seg %08lx)\n", *(long *)data, + fprintf(dbgf, "rel4adr %08lx (seg %08lx)\n", *(int32_t *)data, segment); break; default: @@ -148,31 +149,31 @@ static void dbg_out(long segto, void *data, unsigned long type, } } -static long dbg_segbase(long segment) +static int32_t dbg_segbase(int32_t segment) { return segment; } -static int dbg_directive(char *directive, char *value, int pass) +static int dbg_directive(int8_t *directive, int8_t *value, int pass) { fprintf(dbgf, "directive [%s] value [%s] (pass %d)\n", directive, value, pass); return 1; } -static void dbg_filename(char *inname, char *outname, efunc error) +static void dbg_filename(int8_t *inname, int8_t *outname, efunc error) { standard_extension(inname, outname, ".dbg", error); } -static int dbg_set_info(enum geninfo type, char **val) +static int dbg_set_info(enum geninfo type, int8_t **val) { (void)type; (void)val; return 0; } -char *types[] = { +int8_t *types[] = { "unknown", "label", "byte", "word", "dword", "float", "qword", "tbyte" }; void dbgdbg_init(struct ofmt *of, void *id, FILE * fp, efunc error) @@ -187,12 +188,12 @@ static void dbgdbg_cleanup(void) { } -static void dbgdbg_linnum(const char *lnfname, long lineno, long segto) +static void dbgdbg_linnum(const int8_t *lnfname, int32_t lineno, int32_t segto) { fprintf(dbgf, "dbglinenum %s(%ld) := %08lx\n", lnfname, lineno, segto); } -static void dbgdbg_deflabel(char *name, long segment, - long offset, int is_global, char *special) +static void dbgdbg_deflabel(int8_t *name, int32_t segment, + int32_t offset, int is_global, int8_t *special) { fprintf(dbgf, "dbglabel %s := %08lx:%08lx %s (%d)%s%s\n", name, @@ -200,7 +201,7 @@ static void dbgdbg_deflabel(char *name, long segment, is_global == 2 ? "common" : is_global ? "global" : "local", is_global, special ? ": " : "", special); } -static void dbgdbg_define(const char *type, const char *params) +static void dbgdbg_define(const int8_t *type, const int8_t *params) { fprintf(dbgf, "dbgdirective [%s] value [%s]\n", type, params); } @@ -209,7 +210,7 @@ static void dbgdbg_output(int output_type, void *param) (void)output_type; (void)param; } -static void dbgdbg_typevalue(long type) +static void dbgdbg_typevalue(int32_t type) { fprintf(dbgf, "new type: %s(%lX)\n", types[TYM_TYPE(type) >> 3], TYM_ELEMENTS(type)); diff --git a/output/outelf.c b/output/outelf.c index 35d0e34..e185c7e 100644 --- a/output/outelf.c +++ b/output/outelf.c @@ -11,6 +11,7 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" @@ -41,21 +42,21 @@ enum reloc_type { struct Reloc { struct Reloc *next; - long address; /* relative to _start_ of section */ - long symbol; /* ELF symbol info thingy */ + int32_t address; /* relative to _start_ of section */ + int32_t symbol; /* ELF symbol info thingy */ int type; /* type of relocation */ }; struct Symbol { - long strpos; /* string table position of name */ - long section; /* section ID of the symbol */ + int32_t strpos; /* string table position of name */ + int32_t section; /* section ID of the symbol */ int type; /* symbol type */ - long value; /* address, or COMMON variable align */ - long size; /* size of symbol */ - long globnum; /* symbol table offset if global */ + int32_t value; /* address, or COMMON variable align */ + int32_t size; /* size of symbol */ + int32_t globnum; /* symbol table offset if global */ struct Symbol *next; /* list of globals in each section */ struct Symbol *nextfwd; /* list of unresolved-size symbols */ - char *name; /* used temporarily if in above list */ + int8_t *name; /* used temporarily if in above list */ }; #define SHT_PROGBITS 1 @@ -67,14 +68,14 @@ struct Symbol { struct Section { struct SAA *data; - unsigned long len, size, nrelocs; - long index; + uint32_t len, size, nrelocs; + int32_t index; int type; /* SHT_PROGBITS or SHT_NOBITS */ int align; /* alignment: power of two */ - unsigned long flags; /* section flags */ - char *name; + uint32_t flags; /* section flags */ + int8_t *name; struct SAA *rel; - long rellen; + int32_t rellen; struct Reloc *head, **tail; struct Symbol *gsyms; /* global symbols in section */ }; @@ -84,18 +85,18 @@ static struct Section **sects; static int nsects, sectlen; #define SHSTR_DELTA 256 -static char *shstrtab; +static int8_t *shstrtab; static int shstrtablen, shstrtabsize; static struct SAA *syms; -static unsigned long nlocals, nglobs; +static uint32_t nlocals, nglobs; -static long def_seg; +static int32_t def_seg; static struct RAA *bsym; static struct SAA *strs; -static unsigned long strslen; +static uint32_t strslen; static FILE *elffp; static efunc error; @@ -103,7 +104,7 @@ static evalfunc evaluate; static struct Symbol *fwds; -static char elf_module[FILENAME_MAX]; +static int8_t elf_module[FILENAME_MAX]; extern struct ofmt of_elf; @@ -121,26 +122,26 @@ extern struct ofmt of_elf; #define SEG_ALIGN 16 /* alignment of sections in file */ #define SEG_ALIGN_1 (SEG_ALIGN-1) -static const char align_str[SEG_ALIGN] = ""; /* ANSI will pad this with 0s */ +static const int8_t align_str[SEG_ALIGN] = ""; /* ANSI will pad this with 0s */ #define ELF_MAX_SECTIONS 16 /* really 10, but let's play safe */ static struct ELF_SECTDATA { void *data; - long len; + int32_t len; int is_saa; } *elf_sects; static int elf_nsect; -static long elf_foffs; +static int32_t elf_foffs; static void elf_write(void); -static void elf_sect_write(struct Section *, const unsigned char *, - unsigned long); -static void elf_section_header(int, int, int, void *, int, long, int, int, +static void elf_sect_write(struct Section *, const uint8_t *, + uint32_t); +static void elf_section_header(int, int, int, void *, int, int32_t, int, int, int, int); static void elf_write_sections(void); -static struct SAA *elf_build_symtab(long *, long *); -static struct SAA *elf_build_reltab(long *, struct Reloc *); -static void add_sectname(char *, char *); +static struct SAA *elf_build_symtab(int32_t *, int32_t *); +static struct SAA *elf_build_reltab(int32_t *, struct Reloc *); +static void add_sectname(int8_t *, int8_t *); /* this stuff is needed for the stabs debugging format */ #define N_SO 0x64 /* ID for main source file */ @@ -151,11 +152,11 @@ static void add_sectname(char *, char *); #define TY_STABSSYMLIN 0x40 /* ouch */ struct stabentry { - unsigned long n_strx; - unsigned char n_type; - unsigned char n_other; - unsigned short n_desc; - unsigned long n_value; + uint32_t n_strx; + uint8_t n_type; + uint8_t n_other; + uint16_t n_desc; + uint32_t n_value; }; struct erel { @@ -165,13 +166,13 @@ struct erel { struct symlininfo { int offset; int section; /* section index */ - char *name; /* shallow-copied pointer of section name */ + int8_t *name; /* shallow-copied pointer of section name */ }; struct linelist { struct symlininfo info; int line; - char *filename; + int8_t *filename; struct linelist *next; struct linelist *last; }; @@ -180,18 +181,18 @@ static struct linelist *stabslines = 0; static int stabs_immcall = 0; static int currentline = 0; static int numlinestabs = 0; -static char *stabs_filename = 0; +static int8_t *stabs_filename = 0; static int symtabsection; -static unsigned char *stabbuf = 0, *stabstrbuf = 0, *stabrelbuf = 0; +static uint8_t *stabbuf = 0, *stabstrbuf = 0, *stabrelbuf = 0; static int stablen, stabstrlen, stabrellen; static struct dfmt df_stabs; void stabs_init(struct ofmt *, void *, FILE *, efunc); -void stabs_linenum(const char *filename, long linenumber, long); -void stabs_deflabel(char *, long, long, int, char *); -void stabs_directive(const char *, const char *); -void stabs_typevalue(long); +void stabs_linenum(const int8_t *filename, int32_t linenumber, int32_t); +void stabs_deflabel(int8_t *, int32_t, int32_t, int, int8_t *); +void stabs_directive(const int8_t *, const int8_t *); +void stabs_typevalue(int32_t); void stabs_output(int, void *); void stabs_generate(); void stabs_cleanup(); @@ -203,9 +204,9 @@ void stabs_cleanup(); * symbols, which can be used with WRT to provide PIC relocation * types. */ -static long elf_gotpc_sect, elf_gotoff_sect; -static long elf_got_sect, elf_plt_sect; -static long elf_sym_sect; +static int32_t elf_gotpc_sect, elf_gotoff_sect; +static int32_t elf_got_sect, elf_plt_sect; +static int32_t elf_sym_sect; static void elf_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) { @@ -215,12 +216,12 @@ static void elf_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) (void)ldef; /* placate optimisers */ sects = NULL; nsects = sectlen = 0; - syms = saa_init((long)sizeof(struct Symbol)); + syms = saa_init((int32_t)sizeof(struct Symbol)); nlocals = nglobs = 0; bsym = raa_init(); strs = saa_init(1L); saa_wbytes(strs, "\0", 1L); - saa_wbytes(strs, elf_module, (long)(strlen(elf_module) + 1)); + saa_wbytes(strs, elf_module, (int32_t)(strlen(elf_module) + 1)); strslen = 2 + strlen(elf_module); shstrtab = NULL; shstrtablen = shstrtabsize = 0;; @@ -276,7 +277,7 @@ static void elf_cleanup(int debuginfo) } } -static void add_sectname(char *firsthalf, char *secondhalf) +static void add_sectname(int8_t *firsthalf, int8_t *secondhalf) { int len = strlen(firsthalf) + strlen(secondhalf); while (shstrtablen + len + 1 > shstrtabsize) @@ -286,7 +287,7 @@ static void add_sectname(char *firsthalf, char *secondhalf) shstrtablen += len + 1; } -static int elf_make_section(char *name, int type, int flags, int align) +static int elf_make_section(int8_t *name, int type, int flags, int align) { struct Section *s; @@ -318,9 +319,9 @@ static int elf_make_section(char *name, int type, int flags, int align) return nsects - 1; } -static long elf_section_names(char *name, int pass, int *bits) +static int32_t elf_section_names(int8_t *name, int pass, int *bits) { - char *p; + int8_t *p; int flags_and, flags_or, type, align, i; /* @@ -341,7 +342,7 @@ static long elf_section_names(char *name, int pass, int *bits) while (*p && isspace(*p)) p++; while (*p) { - char *q = p; + int8_t *q = p; while (*p && !isspace(*p)) p++; if (*p) @@ -423,8 +424,8 @@ static long elf_section_names(char *name, int pass, int *bits) return sects[i]->index; } -static void elf_deflabel(char *name, long segment, long offset, - int is_global, char *special) +static void elf_deflabel(int8_t *name, int32_t segment, int32_t offset, + int is_global, int8_t *special) { int pos = strslen; struct Symbol *sym; @@ -458,7 +459,7 @@ static void elf_deflabel(char *name, long segment, long offset, if (!strcmp((*s)->name, name)) { struct tokenval tokval; expr *e; - char *p = special; + int8_t *p = special; while (*p && !isspace(*p)) p++; @@ -486,7 +487,7 @@ static void elf_deflabel(char *name, long segment, long offset, return; /* it wasn't an important one */ } - saa_wbytes(strs, name, (long)(1 + strlen(name))); + saa_wbytes(strs, name, (int32_t)(1 + strlen(name))); strslen += 1 + strlen(name); sym = saa_wstruct(syms); @@ -585,7 +586,7 @@ static void elf_deflabel(char *name, long segment, long offset, struct tokenval tokval; expr *e; int fwd = FALSE; - char *saveme = stdscan_bufptr; /* bugfix? fbk 8/10/00 */ + int8_t *saveme = stdscan_bufptr; /* bugfix? fbk 8/10/00 */ while (special[n] && isspace(special[n])) n++; @@ -623,7 +624,7 @@ static void elf_deflabel(char *name, long segment, long offset, error(ERR_NONFATAL, "no special symbol features supported here"); } -static void elf_add_reloc(struct Section *sect, long segment, int type) +static void elf_add_reloc(struct Section *sect, int32_t segment, int type) { struct Reloc *r; @@ -670,8 +671,8 @@ static void elf_add_reloc(struct Section *sect, long segment, int type) * Inefficiency: we search, currently, using a linked list which * isn't even necessarily sorted. */ -static long elf_add_gsym_reloc(struct Section *sect, - long segment, long offset, +static int32_t elf_add_gsym_reloc(struct Section *sect, + int32_t segment, int32_t offset, int type, int exact) { struct Reloc *r; @@ -736,13 +737,13 @@ static long elf_add_gsym_reloc(struct Section *sect, return offset - sym->value; } -static void elf_out(long segto, const void *data, unsigned long type, - long segment, long wrt) +static void elf_out(int32_t segto, const void *data, uint32_t type, + int32_t segment, int32_t wrt) { struct Section *s; - long realbytes = type & OUT_SIZMASK; - long addr; - unsigned char mydata[4], *p; + int32_t realbytes = type & OUT_SIZMASK; + int32_t addr; + uint8_t mydata[4], *p; int i; static struct symlininfo sinfo; @@ -784,7 +785,7 @@ static void elf_out(long segto, const void *data, unsigned long type, /* end of debugging stuff */ if (s->type == SHT_NOBITS && type != OUT_RESERVE) { - error(ERR_WARNING, "attempt to initialise memory in" + error(ERR_WARNING, "attempt to initialize memory in" " BSS section `%s': ignored", s->name); if (type == OUT_REL2ADR) realbytes = 2; @@ -796,7 +797,7 @@ static void elf_out(long segto, const void *data, unsigned long type, if (type == OUT_RESERVE) { if (s->type == SHT_PROGBITS) { - error(ERR_WARNING, "uninitialised space declared in" + error(ERR_WARNING, "uninitialized space declared in" " non-BSS section `%s': zeroing", s->name); elf_sect_write(s, NULL, realbytes); } else @@ -807,7 +808,7 @@ static void elf_out(long segto, const void *data, unsigned long type, elf_sect_write(s, data, realbytes); } else if (type == OUT_ADDRESS) { int gnu16 = 0; - addr = *(long *)data; + addr = *(int32_t *)data; if (segment != NO_SEG) { if (segment % 2) { error(ERR_NONFATAL, "ELF format does not support" @@ -882,7 +883,7 @@ static void elf_out(long segto, const void *data, unsigned long type, } } p = mydata; - WRITESHORT(p, *(long *)data - realbytes); + WRITESHORT(p, *(int32_t *)data - realbytes); elf_sect_write(s, mydata, 2L); } else if (type == OUT_REL4ADR) { if (segment == segto) @@ -907,7 +908,7 @@ static void elf_out(long segto, const void *data, unsigned long type, } } p = mydata; - WRITELONG(p, *(long *)data - realbytes); + WRITELONG(p, *(int32_t *)data - realbytes); elf_sect_write(s, mydata, 4L); } } @@ -916,13 +917,13 @@ static void elf_write(void) { int nsections, align; int scount; - char *p; + int8_t *p; int commlen; - char comment[64]; + int8_t comment[64]; int i; struct SAA *symtab; - long symtablen, symtablocal; + int32_t symtablen, symtablocal; /* * Work out how many sections we will have. We have SHN_UNDEF, @@ -965,24 +966,24 @@ static void elf_write(void) * Output the ELF header. */ fwrite("\177ELF\1\1\1\0\0\0\0\0\0\0\0\0", 16, 1, elffp); - fwriteshort(1, elffp); /* ET_REL relocatable file */ - fwriteshort(3, elffp); /* EM_386 processor ID */ - fwritelong(1L, elffp); /* EV_CURRENT file format version */ - fwritelong(0L, elffp); /* no entry point */ - fwritelong(0L, elffp); /* no program header table */ - fwritelong(0x40L, elffp); /* section headers straight after + fwriteint16_t(1, elffp); /* ET_REL relocatable file */ + fwriteint16_t(3, elffp); /* EM_386 processor ID */ + fwriteint32_t(1L, elffp); /* EV_CURRENT file format version */ + fwriteint32_t(0L, elffp); /* no entry point */ + fwriteint32_t(0L, elffp); /* no program header table */ + fwriteint32_t(0x40L, elffp); /* section headers straight after * ELF header plus alignment */ - fwritelong(0L, elffp); /* 386 defines no special flags */ - fwriteshort(0x34, elffp); /* size of ELF header */ - fwriteshort(0, elffp); /* no program header table, again */ - fwriteshort(0, elffp); /* still no program header table */ - fwriteshort(0x28, elffp); /* size of section header */ - fwriteshort(nsections, elffp); /* number of sections */ - fwriteshort(nsects + 2, elffp); /* string table section index for + fwriteint32_t(0L, elffp); /* 386 defines no special flags */ + fwriteint16_t(0x34, elffp); /* size of ELF header */ + fwriteint16_t(0, elffp); /* no program header table, again */ + fwriteint16_t(0, elffp); /* still no program header table */ + fwriteint16_t(0x28, elffp); /* size of section header */ + fwriteint16_t(nsections, elffp); /* number of sections */ + fwriteint16_t(nsects + 2, elffp); /* string table section index for * section header table */ - fwritelong(0L, elffp); /* align to 0x40 bytes */ - fwritelong(0L, elffp); - fwritelong(0L, elffp); + fwriteint32_t(0L, elffp); /* align to 0x40 bytes */ + fwriteint32_t(0L, elffp); + fwriteint32_t(0L, elffp); /* * Build the symbol table and relocation tables. @@ -1014,10 +1015,10 @@ static void elf_write(void) p += strlen(p) + 1; scount++; /* dito */ } - elf_section_header(p - shstrtab, 1, 0, comment, FALSE, (long)commlen, 0, 0, 1, 0); /* .comment */ + elf_section_header(p - shstrtab, 1, 0, comment, FALSE, (int32_t)commlen, 0, 0, 1, 0); /* .comment */ scount++; /* dito */ p += strlen(p) + 1; - elf_section_header(p - shstrtab, 3, 0, shstrtab, FALSE, (long)shstrtablen, 0, 0, 1, 0); /* .shstrtab */ + elf_section_header(p - shstrtab, 3, 0, shstrtab, FALSE, (int32_t)shstrtablen, 0, 0, 1, 0); /* .shstrtab */ scount++; /* dito */ p += strlen(p) + 1; elf_section_header(p - shstrtab, 2, 0, symtab, TRUE, symtablen, nsects + 4, symtablocal, 4, 16); /* .symtab */ @@ -1064,11 +1065,11 @@ static void elf_write(void) saa_free(symtab); } -static struct SAA *elf_build_symtab(long *len, long *local) +static struct SAA *elf_build_symtab(int32_t *len, int32_t *local) { struct SAA *s = saa_init(1L); struct Symbol *sym; - unsigned char entry[16], *p; + uint8_t entry[16], *p; int i; *len = *local = 0; @@ -1147,10 +1148,10 @@ static struct SAA *elf_build_symtab(long *len, long *local) return s; } -static struct SAA *elf_build_reltab(long *len, struct Reloc *r) +static struct SAA *elf_build_reltab(int32_t *len, struct Reloc *r) { struct SAA *s; - unsigned char *p, entry[8]; + uint8_t *p, entry[8]; if (!r) return NULL; @@ -1159,7 +1160,7 @@ static struct SAA *elf_build_reltab(long *len, struct Reloc *r) *len = 0; while (r) { - long sym = r->symbol; + int32_t sym = r->symbol; if (sym >= GLOBAL_TEMP_BASE) sym += -GLOBAL_TEMP_BASE + (nsects + 3) + nlocals; @@ -1177,7 +1178,7 @@ static struct SAA *elf_build_reltab(long *len, struct Reloc *r) } static void elf_section_header(int name, int type, int flags, - void *data, int is_saa, long datalen, + void *data, int is_saa, int32_t datalen, int link, int info, int align, int eltsize) { elf_sects[elf_nsect].data = data; @@ -1185,18 +1186,18 @@ static void elf_section_header(int name, int type, int flags, elf_sects[elf_nsect].is_saa = is_saa; elf_nsect++; - fwritelong((long)name, elffp); - fwritelong((long)type, elffp); - fwritelong((long)flags, elffp); - fwritelong(0L, elffp); /* no address, ever, in object files */ - fwritelong(type == 0 ? 0L : elf_foffs, elffp); - fwritelong(datalen, elffp); + fwriteint32_t((int32_t)name, elffp); + fwriteint32_t((int32_t)type, elffp); + fwriteint32_t((int32_t)flags, elffp); + fwriteint32_t(0L, elffp); /* no address, ever, in object files */ + fwriteint32_t(type == 0 ? 0L : elf_foffs, elffp); + fwriteint32_t(datalen, elffp); if (data) elf_foffs += (datalen + SEG_ALIGN_1) & ~SEG_ALIGN_1; - fwritelong((long)link, elffp); - fwritelong((long)info, elffp); - fwritelong((long)align, elffp); - fwritelong((long)eltsize, elffp); + fwriteint32_t((int32_t)link, elffp); + fwriteint32_t((int32_t)info, elffp); + fwriteint32_t((int32_t)align, elffp); + fwriteint32_t((int32_t)eltsize, elffp); } static void elf_write_sections(void) @@ -1204,9 +1205,9 @@ static void elf_write_sections(void) int i; for (i = 0; i < elf_nsect; i++) if (elf_sects[i].data) { - long len = elf_sects[i].len; - long reallen = (len + SEG_ALIGN_1) & ~SEG_ALIGN_1; - long align = reallen - len; + int32_t len = elf_sects[i].len; + int32_t reallen = (len + SEG_ALIGN_1) & ~SEG_ALIGN_1; + int32_t align = reallen - len; if (elf_sects[i].is_saa) saa_fpwrite(elf_sects[i].data, elffp); else @@ -1216,36 +1217,36 @@ static void elf_write_sections(void) } static void elf_sect_write(struct Section *sect, - const unsigned char *data, unsigned long len) + const uint8_t *data, uint32_t len) { saa_wbytes(sect->data, data, len); sect->len += len; } -static long elf_segbase(long segment) +static int32_t elf_segbase(int32_t segment) { return segment; } -static int elf_directive(char *directive, char *value, int pass) +static int elf_directive(int8_t *directive, int8_t *value, int pass) { return 0; } -static void elf_filename(char *inname, char *outname, efunc error) +static void elf_filename(int8_t *inname, int8_t *outname, efunc error) { strcpy(elf_module, inname); standard_extension(inname, outname, ".o", error); } -static const char *elf_stdmac[] = { +static const int8_t *elf_stdmac[] = { "%define __SECT__ [section .text]", "%macro __NASM_CDecl__ 1", "%define $_%1 $%1", "%endmacro", NULL }; -static int elf_set_info(enum geninfo type, char **val) +static int elf_set_info(enum geninfo type, int8_t **val) { return 0; } @@ -1288,10 +1289,10 @@ void stabs_init(struct ofmt *of, void *id, FILE * fp, efunc error) { } -void stabs_linenum(const char *filename, long linenumber, long segto) +void stabs_linenum(const int8_t *filename, int32_t linenumber, int32_t segto) { if (!stabs_filename) { - stabs_filename = (char *)nasm_malloc(strlen(filename) + 1); + stabs_filename = (int8_t *)nasm_malloc(strlen(filename) + 1); strcpy(stabs_filename, filename); } else { if (strcmp(stabs_filename, filename)) { @@ -1301,7 +1302,7 @@ void stabs_linenum(const char *filename, long linenumber, long segto) /* why not nasm_free(stabs_filename); we're done with the old one */ - stabs_filename = (char *)nasm_malloc(strlen(filename) + 1); + stabs_filename = (int8_t *)nasm_malloc(strlen(filename) + 1); strcpy(stabs_filename, filename); } } @@ -1309,16 +1310,16 @@ void stabs_linenum(const char *filename, long linenumber, long segto) currentline = linenumber; } -void stabs_deflabel(char *name, long segment, long offset, int is_global, - char *special) +void stabs_deflabel(int8_t *name, int32_t segment, int32_t offset, int is_global, + int8_t *special) { } -void stabs_directive(const char *directive, const char *params) +void stabs_directive(const int8_t *directive, const int8_t *params) { } -void stabs_typevalue(long type) +void stabs_typevalue(int32_t type) { } @@ -1365,15 +1366,15 @@ void stabs_output(int type, void *param) void stabs_generate(void) { int i, numfiles, strsize, numstabs = 0, currfile, mainfileindex; - unsigned char *sbuf, *ssbuf, *rbuf, *sptr, *rptr; - char **allfiles; + uint8_t *sbuf, *ssbuf, *rbuf, *sptr, *rptr; + int8_t **allfiles; int *fileidx; struct linelist *ptr; ptr = stabslines; - allfiles = (char **)nasm_malloc(numlinestabs * sizeof(char *)); + allfiles = (int8_t **)nasm_malloc(numlinestabs * sizeof(int8_t *)); for (i = 0; i < numlinestabs; i++) allfiles[i] = 0; numfiles = 0; @@ -1411,16 +1412,16 @@ void stabs_generate(void) the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line */ sbuf = - (unsigned char *)nasm_malloc((numlinestabs * 2 + 3) * + (uint8_t *)nasm_malloc((numlinestabs * 2 + 3) * sizeof(struct stabentry)); - ssbuf = (unsigned char *)nasm_malloc(strsize); + ssbuf = (uint8_t *)nasm_malloc(strsize); - rbuf = (unsigned char *)nasm_malloc(numlinestabs * 8 * (2 + 3)); + rbuf = (uint8_t *)nasm_malloc(numlinestabs * 8 * (2 + 3)); rptr = rbuf; for (i = 0; i < numfiles; i++) { - strcpy((char *)ssbuf + fileidx[i], allfiles[i]); + strcpy((int8_t *)ssbuf + fileidx[i], allfiles[i]); } ssbuf[0] = 0; diff --git a/output/outieee.c b/output/outieee.c index 6c319cd..7cea69f 100644 --- a/output/outieee.c +++ b/output/outieee.c @@ -42,6 +42,7 @@ #include <time.h> #include <stdarg.h> /* Note: we need the ANSI version of stdarg.h */ #include <ctype.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" @@ -51,7 +52,7 @@ #define ARRAY_BOT 0x1 -static char ieee_infile[FILENAME_MAX]; +static int8_t ieee_infile[FILENAME_MAX]; static int ieee_uppercase; static efunc error; @@ -69,14 +70,14 @@ struct ieeeSection; struct LineNumber { struct LineNumber *next; struct ieeeSection *segment; - long offset; - long lineno; + int32_t offset; + int32_t lineno; }; static struct FileName { struct FileName *next; - char *name; - long index; + int8_t *name; + int32_t index; } *fnhead, **fntail; static struct Array { @@ -87,17 +88,17 @@ static struct Array { static struct ieeePublic { struct ieeePublic *next; - char *name; - long offset; - long segment; /* only if it's far-absolute */ - long index; + int8_t *name; + int32_t offset; + int32_t segment; /* only if it's far-absolute */ + int32_t index; int type; /* for debug purposes */ } *fpubhead, **fpubtail, *last_defined; static struct ieeeExternal { struct ieeeExternal *next; - char *name; - long commonsize; + int8_t *name; + int32_t commonsize; } *exthead, **exttail; static int externals; @@ -112,24 +113,24 @@ static struct ieeeSection { struct ieeeObjData *data, *datacurr; struct ieeeSection *next; struct ieeeFixupp *fptr, *flptr; - long index; /* the NASM segment id */ - long ieee_index; /* the OBJ-file segment index */ - long currentpos; - long align; /* can be SEG_ABS + absolute addr */ - long startpos; + int32_t index; /* the NASM segment id */ + int32_t ieee_index; /* the OBJ-file segment index */ + int32_t currentpos; + int32_t align; /* can be SEG_ABS + absolute addr */ + int32_t startpos; enum { CMB_PRIVATE = 0, CMB_PUBLIC = 2, CMB_COMMON = 6 } combine; - long use32; /* is this segment 32-bit? */ + int32_t use32; /* is this segment 32-bit? */ struct ieeePublic *pubhead, **pubtail, *lochead, **loctail; - char *name; + int8_t *name; } *seghead, **segtail, *ieee_seg_needs_update; struct ieeeObjData { struct ieeeObjData *next; - unsigned char data[HUNKSIZE]; + uint8_t data[HUNKSIZE]; }; struct ieeeFixupp { @@ -144,32 +145,32 @@ struct ieeeFixupp { FT_EXTWRT = 6, FT_EXTSEG = 7 } ftype; - short size; - long id1; - long id2; - long offset; - long addend; + int16_t size; + int32_t id1; + int32_t id2; + int32_t offset; + int32_t addend; }; -static long ieee_entry_seg, ieee_entry_ofs; +static int32_t ieee_entry_seg, ieee_entry_ofs; static int checksum; extern struct ofmt of_ieee; static void ieee_data_new(struct ieeeSection *); -static void ieee_write_fixup(long, long, struct ieeeSection *, - int, unsigned long, long); +static void ieee_write_fixup(int32_t, int32_t, struct ieeeSection *, + int, uint32_t, int32_t); static void ieee_install_fixup(struct ieeeSection *, struct ieeeFixupp *); -static long ieee_segment(char *, int, int *); +static int32_t ieee_segment(int8_t *, int, int *); static void ieee_write_file(int debuginfo); static void ieee_write_byte(struct ieeeSection *, int); static void ieee_write_word(struct ieeeSection *, int); -static void ieee_write_dword(struct ieeeSection *, long); -static void ieee_putascii(char *, ...); +static void ieee_write_dword(struct ieeeSection *, int32_t); +static void ieee_putascii(int8_t *, ...); static void ieee_putcs(int); -static long ieee_putld(long, long, unsigned char *); -static long ieee_putlr(struct ieeeFixupp *); -static void ieee_unqualified_name(char *, char *); +static int32_t ieee_putld(int32_t, int32_t, uint8_t *); +static int32_t ieee_putlr(struct ieeeFixupp *); +static void ieee_unqualified_name(int8_t *, int8_t *); /* * pup init @@ -195,7 +196,7 @@ static void ieee_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) checksum = 0; of_ieee.current_dfmt->init(&of_ieee, NULL, fp, errfunc); } -static int ieee_set_info(enum geninfo type, char **val) +static int ieee_set_info(enum geninfo type, int8_t **val) { (void)type; (void)val; @@ -251,8 +252,8 @@ static void ieee_cleanup(int debuginfo) /* * callback for labels */ -static void ieee_deflabel(char *name, long segment, - long offset, int is_global, char *special) +static void ieee_deflabel(int8_t *name, int32_t segment, + int32_t offset, int is_global, int8_t *special) { /* * We have three cases: @@ -369,12 +370,12 @@ static void ieee_deflabel(char *name, long segment, /* * Put data out */ -static void ieee_out(long segto, const void *data, unsigned long type, - long segment, long wrt) +static void ieee_out(int32_t segto, const void *data, uint32_t type, + int32_t segment, int32_t wrt) { - unsigned long size, realtype; - const unsigned char *ucdata; - long ldata; + uint32_t size, realtype; + const uint8_t *ucdata; + int32_t ldata; struct ieeeSection *seg; /* @@ -417,7 +418,7 @@ static void ieee_out(long segto, const void *data, unsigned long type, if (segment == NO_SEG && realtype != OUT_ADDRESS) error(ERR_NONFATAL, "relative call to absolute address not" " supported by IEEE format"); - ldata = *(long *)data; + ldata = *(int32_t *)data; if (realtype == OUT_REL2ADR) ldata += (size - 2); if (realtype == OUT_REL4ADR) @@ -450,9 +451,9 @@ static void ieee_data_new(struct ieeeSection *segto) * but I might as well see what it is like on a harmless program. * If anyone wants to optimize this is a good canditate! */ -static void ieee_write_fixup(long segment, long wrt, +static void ieee_write_fixup(int32_t segment, int32_t wrt, struct ieeeSection *segto, int size, - unsigned long realtype, long offset) + uint32_t realtype, int32_t offset) { struct ieeeSection *target; struct ieeeFixupp s; @@ -489,7 +490,7 @@ static void ieee_write_fixup(long segment, long wrt, * Now we assume the segment field is being used * to hold an extern index */ - long i = segment / 2; + int32_t i = segment / 2; struct ExtBack *eb = ebhead; while (i > EXT_BLKSIZ) { if (eb) @@ -539,7 +540,7 @@ static void ieee_write_fixup(long segment, long wrt, * Now we assume the segment field is being used * to hold an extern index */ - long i = segment / 2; + int32_t i = segment / 2; struct ExtBack *eb = ebhead; while (i > EXT_BLKSIZ) { if (eb) @@ -593,7 +594,7 @@ static void ieee_write_fixup(long segment, long wrt, * Now we assume the segment field is being used * to hold an extern index */ - long i = segment / 2; + int32_t i = segment / 2; struct ExtBack *eb = ebhead; while (i > EXT_BLKSIZ) { if (eb) @@ -650,7 +651,7 @@ static void ieee_install_fixup(struct ieeeSection *seg, /* * segment registry */ -static long ieee_segment(char *name, int pass, int *bits) +static int32_t ieee_segment(int8_t *name, int pass, int *bits) { /* * We call the label manager here to define a name for the new @@ -667,7 +668,7 @@ static long ieee_segment(char *name, int pass, int *bits) } else { struct ieeeSection *seg; int ieee_idx, attrs, rn_error; - char *p; + int8_t *p; /* * Look for segment attributes. @@ -804,7 +805,7 @@ static long ieee_segment(char *name, int pass, int *bits) /* * directives supported */ -static int ieee_directive(char *directive, char *value, int pass) +static int ieee_directive(int8_t *directive, int8_t *value, int pass) { (void)value; @@ -819,7 +820,7 @@ static int ieee_directive(char *directive, char *value, int pass) /* * Return segment data */ -static long ieee_segbase(long segment) +static int32_t ieee_segbase(int32_t segment) { struct ieeeSection *seg; @@ -842,7 +843,7 @@ static long ieee_segbase(long segment) /* * filename */ -static void ieee_filename(char *inname, char *outname, efunc error) +static void ieee_filename(int8_t *inname, int8_t *outname, efunc error) { strcpy(ieee_infile, inname); standard_extension(inname, outname, ".o", error); @@ -859,7 +860,7 @@ static void ieee_write_file(int debuginfo) struct ieeeObjData *data; struct ieeeFixupp *fix; struct Array *arr; - static char boast[] = "The Netwide Assembler " NASM_VER; + static int8_t boast[] = "The Netwide Assembler " NASM_VER; int i; /* @@ -907,8 +908,8 @@ static void ieee_write_file(int debuginfo) if (!debuginfo && !strcmp(seg->name, "??LINE")) seg = seg->next; while (seg) { - char buf[256]; - char attrib; + int8_t buf[256]; + int8_t attrib; switch (seg->combine) { case CMB_PUBLIC: default: @@ -957,7 +958,7 @@ static void ieee_write_file(int debuginfo) i = 1; for (seg = seghead; seg; seg = seg->next) { for (pub = seg->pubhead; pub; pub = pub->next) { - char buf[256]; + int8_t buf[256]; ieee_unqualified_name(buf, pub->name); ieee_putascii("NI%X,%02X%s.\r\n", i, strlen(buf), buf); if (pub->segment == -1) @@ -978,7 +979,7 @@ static void ieee_write_file(int debuginfo) pub = fpubhead; i = 1; while (pub) { - char buf[256]; + int8_t buf[256]; ieee_unqualified_name(buf, pub->name); ieee_putascii("NI%X,%02X%s.\r\n", i, strlen(buf), buf); if (pub->segment == -1) @@ -1002,7 +1003,7 @@ static void ieee_write_file(int debuginfo) ext = exthead; i = 1; while (ext) { - char buf[256]; + int8_t buf[256]; ieee_unqualified_name(buf, ext->name); ieee_putascii("NX%X,%02X%s.\r\n", i++, strlen(buf), buf); ext = ext->next; @@ -1029,7 +1030,7 @@ static void ieee_write_file(int debuginfo) i = 1; for (seg = seghead; seg && debuginfo; seg = seg->next) { for (loc = seg->lochead; loc; loc = loc->next) { - char buf[256]; + int8_t buf[256]; ieee_unqualified_name(buf, loc->name); ieee_putascii("NN%X,%02X%s.\r\n", i, strlen(buf), buf); if (loc->segment == -1) @@ -1056,7 +1057,7 @@ static void ieee_write_file(int debuginfo) seg = seg->next; while (seg) { if (seg->currentpos) { - long size, org = 0; + int32_t size, org = 0; data = seg->data; ieee_putascii("SB%X.\r\n", seg->ieee_index); fix = seg->fptr; @@ -1106,16 +1107,16 @@ static void ieee_write_word(struct ieeeSection *seg, int data) ieee_write_byte(seg, (data >> 8) & 0xFF); } -static void ieee_write_dword(struct ieeeSection *seg, long data) +static void ieee_write_dword(struct ieeeSection *seg, int32_t data) { ieee_write_byte(seg, data & 0xFF); ieee_write_byte(seg, (data >> 8) & 0xFF); ieee_write_byte(seg, (data >> 16) & 0xFF); ieee_write_byte(seg, (data >> 24) & 0xFF); } -static void ieee_putascii(char *format, ...) +static void ieee_putascii(int8_t *format, ...) { - char buffer[256]; + int8_t buffer[256]; int i, l; va_list ap; @@ -1143,9 +1144,9 @@ static void ieee_putcs(int toclear) checksum = 0; } -static long ieee_putld(long start, long end, unsigned char *buf) +static int32_t ieee_putld(int32_t start, int32_t end, uint8_t *buf) { - long val; + int32_t val; if (start == end) return (start); val = start % HUNKSIZE; @@ -1171,7 +1172,7 @@ static long ieee_putld(long start, long end, unsigned char *buf) ieee_putascii(".\r\n"); return (start); } -static long ieee_putlr(struct ieeeFixupp *p) +static int32_t ieee_putlr(struct ieeeFixupp *p) { /* * To deal with the vagaries of segmentation the LADsoft linker @@ -1188,8 +1189,8 @@ static long ieee_putlr(struct ieeeFixupp *p) * becomes an issue if real mode code is used. A pure 32-bit linker could * get away without defining the virtual mode... */ - char buf[40]; - long size = p->size; + int8_t buf[40]; + int32_t size = p->size; switch (p->ftype) { case FT_SEG: if (p->id1 < 0) @@ -1240,7 +1241,7 @@ static long ieee_putlr(struct ieeeFixupp *p) /* Dump all segment data (text and fixups )*/ -static void ieee_unqualified_name(char *dest, char *source) +static void ieee_unqualified_name(int8_t *dest, int8_t *source) { if (ieee_uppercase) { while (*source) @@ -1296,7 +1297,7 @@ static void dbgls_cleanup(void) * so, we have to make sure the ??LINE segment is avaialbe * as the first segment when this debug format is selected */ -static void dbgls_linnum(const char *lnfname, long lineno, long segto) +static void dbgls_linnum(const int8_t *lnfname, int32_t lineno, int32_t segto) { struct FileName *fn; struct ieeeSection *seg; @@ -1343,8 +1344,8 @@ static void dbgls_linnum(const char *lnfname, long lineno, long segto) seg->currentpos); } -static void dbgls_deflabel(char *name, long segment, - long offset, int is_global, char *special) +static void dbgls_deflabel(int8_t *name, int32_t segment, + int32_t offset, int is_global, int8_t *special) { struct ieeeSection *seg; int used_special; /* have we used the special text? */ @@ -1403,7 +1404,7 @@ static void dbgls_deflabel(char *name, long segment, } } } -static void dbgls_typevalue(long type) +static void dbgls_typevalue(int32_t type) { int elem = TYM_ELEMENTS(type); type = TYM_TYPE(type); @@ -1413,7 +1414,7 @@ static void dbgls_typevalue(long type) switch (type) { case TY_BYTE: - last_defined->type = 1; /* unsigned char */ + last_defined->type = 1; /* uint8_t */ break; case TY_WORD: last_defined->type = 3; /* unsigned word */ diff --git a/output/outmacho.c b/output/outmacho.c index 0917cbe..b5054cf 100644 --- a/output/outmacho.c +++ b/output/outmacho.c @@ -14,6 +14,7 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" @@ -50,16 +51,16 @@ struct section { /* nasm internal data */ struct section *next; struct SAA *data; - long index; + int32_t index; struct reloc *relocs; int align; /* data that goes into the file */ - char sectname[16]; /* what this section is called */ - char segname[16]; /* segment this section will be in */ - unsigned long size; /* in-memory and -file size */ - unsigned long nreloc; /* relocation entry count */ - unsigned long flags; /* type and attributes (masked) */ + int8_t sectname[16]; /* what this section is called */ + int8_t segname[16]; /* segment this section will be in */ + uint32_t size; /* in-memory and -file size */ + uint32_t nreloc; /* relocation entry count */ + uint32_t flags; /* type and attributes (masked) */ }; #define SECTION_TYPE 0x000000ff /* section type mask */ @@ -77,10 +78,10 @@ struct section { static struct sectmap { - const char *nasmsect; - const char *segname; - const char *sectname; - const long flags; + const int8_t *nasmsect; + const int8_t *segname; + const int8_t *sectname; + const int32_t flags; } sectmap[] = { { ".text", "__TEXT", "__text", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS}, { ".data", "__DATA", "__data", S_REGULAR}, { @@ -93,12 +94,12 @@ struct reloc { struct reloc *next; /* data that goes into the file */ - long addr; /* op's offset in section */ + int32_t addr; /* op's offset in section */ unsigned int snum:24, /* contains symbol index if ** ext otherwise in-file ** section number */ pcrel:1, /* relative relocation */ - length:2, /* 0=byte, 1=word, 2=long */ + length:2, /* 0=byte, 1=word, 2=int32_t */ ext:1, /* external symbol referenced */ type:4; /* reloc type, 0 for us */ }; @@ -110,17 +111,17 @@ struct reloc { struct symbol { /* nasm internal data */ struct symbol *next; /* next symbol in the list */ - char *name; /* name of this symbol */ - long initial_snum; /* symbol number used above in + int8_t *name; /* name of this symbol */ + int32_t initial_snum; /* symbol number used above in reloc */ - long snum; /* true snum for reloc */ + int32_t snum; /* true snum for reloc */ /* data that goes into the file */ - long strx; /* string table index */ - unsigned char type; /* symbol type */ - unsigned char sect; /* NO_SECT or section number */ - short desc; /* for stab debugging, 0 for us */ - unsigned long value; /* offset of symbol in section */ + int32_t strx; /* string table index */ + uint8_t type; /* symbol type */ + uint8_t sect; /* NO_SECT or section number */ + int16_t desc; /* for stab debugging, 0 for us */ + uint32_t value; /* offset of symbol in section */ }; /* symbol type bits */ @@ -141,7 +142,7 @@ struct symbol { static struct section *sects, **sectstail; static struct symbol *syms, **symstail; -static unsigned long nsyms; +static uint32_t nsyms; /* These variables are set by macho_layout_symbols() to organize the symbol table and string table in order the dynamic linker @@ -157,18 +158,18 @@ static unsigned long nsyms; strings for external symbols strings for local symbols */ -static unsigned long ilocalsym = 0; -static unsigned long iextdefsym = 0; -static unsigned long iundefsym = 0; -static unsigned long nlocalsym; -static unsigned long nextdefsym; -static unsigned long nundefsym; +static uint32_t ilocalsym = 0; +static uint32_t iextdefsym = 0; +static uint32_t iundefsym = 0; +static uint32_t nlocalsym; +static uint32_t nextdefsym; +static uint32_t nundefsym; static struct symbol **extdefsyms = NULL; static struct symbol **undefsyms = NULL; static struct RAA *extsyms; static struct SAA *strs; -static unsigned long strslen; +static uint32_t strslen; static FILE *machofp; static efunc error; @@ -178,12 +179,12 @@ extern struct ofmt of_macho; /* Global file information. This should be cleaned up into either a structure or as function arguments. */ -unsigned long head_ncmds = 0; -unsigned long head_sizeofcmds = 0; -unsigned long seg_filesize = 0; -unsigned long seg_vmsize = 0; -unsigned long seg_nsects = 0; -unsigned long rel_padcnt = 0; +uint32_t head_ncmds = 0; +uint32_t head_sizeofcmds = 0; +uint32_t seg_filesize = 0; +uint32_t seg_vmsize = 0; +uint32_t seg_nsects = 0; +uint32_t rel_padcnt = 0; #define xstrncpy(xdst, xsrc) \ @@ -194,20 +195,20 @@ unsigned long rel_padcnt = 0; #define align(x, y) \ (((x) + (y) - 1) & ~((y) - 1)) /* align x to multiple of y */ -#define alignlong(x) \ - align(x, sizeof(long)) /* align x to long boundary */ +#define alignint32_t(x) \ + align(x, sizeof(int32_t)) /* align x to int32_t boundary */ static void debug_reloc (struct reloc *); static void debug_section_relocs (struct section *) __attribute__ ((unused)); -static int exact_log2 (unsigned long align) { +static int exact_log2 (uint32_t align) { if (align != (align & -align)) { return -1; } else { #ifdef __GNUC__ return (align ? __builtin_ctzl (align) : 0); #else - unsigned long result = 0; + uint32_t result = 0; while (align >>= 1) { ++result; @@ -218,8 +219,8 @@ static int exact_log2 (unsigned long align) { } } -static struct section *get_section_by_name(const char *segname, - const char *sectname) +static struct section *get_section_by_name(const int8_t *segname, + const int8_t *sectname) { struct section *s; @@ -230,7 +231,7 @@ static struct section *get_section_by_name(const char *segname, return s; } -static struct section *get_section_by_index(const long index) +static struct section *get_section_by_index(const int32_t index) { struct section *s; @@ -241,8 +242,8 @@ static struct section *get_section_by_index(const long index) return s; } -static long get_section_index_by_name(const char *segname, - const char *sectname) +static int32_t get_section_index_by_name(const int8_t *segname, + const int8_t *sectname) { struct section *s; @@ -253,7 +254,7 @@ static long get_section_index_by_name(const char *segname, return -1; } -static char *get_section_name_by_index(const long index) +static int8_t *get_section_name_by_index(const int32_t index) { struct section *s; @@ -264,10 +265,10 @@ static char *get_section_name_by_index(const long index) return NULL; } -static unsigned char get_section_fileindex_by_index(const long index) +static uint8_t get_section_fileindex_by_index(const int32_t index) { struct section *s; - unsigned char i = 1; + uint8_t i = 1; for (s = sects; s != NULL && i < MAX_SECT; s = s->next, ++i) if (index == s->index) @@ -283,7 +284,7 @@ static unsigned char get_section_fileindex_by_index(const long index) static void macho_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) { - char zero = 0; + int8_t zero = 0; machofp = fp; error = errfunc; @@ -305,27 +306,27 @@ static void macho_init(FILE * fp, efunc errfunc, ldfunc ldef, strs = saa_init(1L); /* string table starts with a zero byte - don't ask why */ - saa_wbytes(strs, &zero, sizeof(char)); + saa_wbytes(strs, &zero, sizeof(int8_t)); strslen = 1; } -static int macho_setinfo(enum geninfo type, char **val) +static int macho_setinfo(enum geninfo type, int8_t **val) { return 0; } static void sect_write(struct section *sect, - const unsigned char *data, unsigned long len) + const uint8_t *data, uint32_t len) { saa_wbytes(sect->data, data, len); sect->size += len; } -static void add_reloc(struct section *sect, long section, +static void add_reloc(struct section *sect, int32_t section, int pcrel, int bytes) { struct reloc *r; - long fi; + int32_t fi; /* NeXT as puts relocs in reversed order (address-wise) into the ** files, so we do the same, doesn't seem to make much of a @@ -368,13 +369,13 @@ static void add_reloc(struct section *sect, long section, ++sect->nreloc; } -static void macho_output(long secto, const void *data, unsigned long type, - long section, long wrt) +static void macho_output(int32_t secto, const void *data, uint32_t type, + int32_t section, int32_t wrt) { struct section *s, *sbss; - long realbytes = type & OUT_SIZMASK; - long addr; - unsigned char mydata[4], *p; + int32_t realbytes = type & OUT_SIZMASK; + int32_t addr; + uint8_t mydata[4], *p; type &= OUT_TYPMASK; @@ -407,7 +408,7 @@ static void macho_output(long secto, const void *data, unsigned long type, sbss = get_section_by_name("__DATA", "__bss"); if (s == sbss && type != OUT_RESERVE) { - error(ERR_WARNING, "attempt to initialise memory in the" + error(ERR_WARNING, "attempt to initialize memory in the" " BSS section: ignored"); switch (type) { @@ -430,7 +431,7 @@ static void macho_output(long secto, const void *data, unsigned long type, switch (type) { case OUT_RESERVE: if (s != sbss) { - error(ERR_WARNING, "uninitialised space declared in" + error(ERR_WARNING, "uninitialized space declared in" " %s section: zeroing", get_section_name_by_index(secto)); @@ -448,7 +449,7 @@ static void macho_output(long secto, const void *data, unsigned long type, break; case OUT_ADDRESS: - addr = *(long *)data; + addr = *(int32_t *)data; if (section != NO_SEG) { if (section % 2) { @@ -479,7 +480,7 @@ static void macho_output(long secto, const void *data, unsigned long type, add_reloc(s, section, 1, 2); p = mydata; - WRITESHORT(p, *(long *)data - (realbytes + s->size)); + WRITESHORT(p, *(int32_t *)data - (realbytes + s->size)); sect_write(s, mydata, 2L); break; @@ -494,7 +495,7 @@ static void macho_output(long secto, const void *data, unsigned long type, add_reloc(s, section, 1, 4); p = mydata; - WRITELONG(p, *(long *)data - (realbytes + s->size)); + WRITELONG(p, *(int32_t *)data - (realbytes + s->size)); sect_write(s, mydata, 4L); break; @@ -504,10 +505,10 @@ static void macho_output(long secto, const void *data, unsigned long type, } } -static long macho_section(char *name, int pass, int *bits) +static int32_t macho_section(int8_t *name, int pass, int *bits) { - long index, originalIndex; - char *sectionAttributes; + int32_t index, originalIndex; + int8_t *sectionAttributes; struct sectmap *sm; struct section *s; @@ -518,13 +519,13 @@ static long macho_section(char *name, int pass, int *bits) sectionAttributes = NULL; } else { sectionAttributes = name; - name = strsep(§ionAttributes, " \t"); + name = strtok((char*)§ionAttributes, " \t"); } for (sm = sectmap; sm->nasmsect != NULL; ++sm) { /* make lookup into section name translation table */ if (!strcmp(name, sm->nasmsect)) { - char *currentAttribute; + int8_t *currentAttribute; /* try to find section with that name */ originalIndex = index = get_section_index_by_name(sm->segname, @@ -553,13 +554,13 @@ static long macho_section(char *name, int pass, int *bits) } while ((NULL != sectionAttributes) - && (currentAttribute = strsep(§ionAttributes, " \t"))) { + && (currentAttribute = strtok((char*)§ionAttributes, " \t"))) { if (0 != *currentAttribute) { if (0 == strncasecmp("align=", currentAttribute, 6)) { - char *end; + int8_t *end; int newAlignment, value; - value = strtoul(currentAttribute + 6, &end, 0); + value = strtoul(currentAttribute + 6, (char**)&end, 0); newAlignment = exact_log2(value); if (0 != *end) { @@ -611,8 +612,8 @@ static long macho_section(char *name, int pass, int *bits) return NO_SEG; } -static void macho_symdef(char *name, long section, long offset, - int is_global, char *special) +static void macho_symdef(int8_t *name, int32_t section, int32_t offset, + int is_global, int8_t *special) { struct symbol *sym; @@ -683,22 +684,22 @@ static void macho_symdef(char *name, long section, long offset, ++nsyms; } -static long macho_segbase(long section) +static int32_t macho_segbase(int32_t section) { return section; } -static int macho_directive(char *directive, char *value, int pass) +static int macho_directive(int8_t *directive, int8_t *value, int pass) { return 0; } -static void macho_filename(char *inname, char *outname, efunc error) +static void macho_filename(int8_t *inname, int8_t *outname, efunc error) { standard_extension(inname, outname, ".o", error); } -static const char *macho_stdmac[] = { +static const int8_t *macho_stdmac[] = { "%define __SECT__ [section .text]", "%macro __NASM_CDecl__ 1", "%endmacro", @@ -723,14 +724,14 @@ static int layout_compare (const struct symbol **s1, numsyms is the total number of symbols we have. strtabsize is the number entries in the string table. */ -static void macho_layout_symbols (unsigned long *numsyms, - unsigned long *strtabsize) +static void macho_layout_symbols (uint32_t *numsyms, + uint32_t *strtabsize) { struct symbol *sym, **symp; - unsigned long i,j; + uint32_t i,j; *numsyms = 0; - *strtabsize = sizeof (char); + *strtabsize = sizeof (int8_t); symp = &syms; @@ -754,7 +755,7 @@ static void macho_layout_symbols (unsigned long *numsyms, to check for it here instead of just adding the symbol to the string table. */ sym->strx = *strtabsize; - saa_wbytes (strs, sym->name, (long)(strlen(sym->name) + 1)); + saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1)); *strtabsize += strlen(sym->name) + 1; } symp = &(sym->next); @@ -780,7 +781,7 @@ static void macho_layout_symbols (unsigned long *numsyms, if((sym->type & N_EXT) == 0) { sym->strx = *strtabsize; - saa_wbytes (strs, sym->name, (long)(strlen (sym->name) + 1)); + saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1)); *strtabsize += strlen(sym->name) + 1; } else { @@ -841,72 +842,72 @@ static void macho_calculate_sizes (void) static void macho_write_header (void) { - fwritelong(MH_MAGIC, machofp); /* magic */ - fwritelong(CPU_TYPE_I386, machofp); /* CPU type */ - fwritelong(CPU_SUBTYPE_I386_ALL, machofp); /* CPU subtype */ - fwritelong(MH_OBJECT, machofp); /* Mach-O file type */ - fwritelong(head_ncmds, machofp); /* number of load commands */ - fwritelong(head_sizeofcmds, machofp); /* size of load commands */ - fwritelong(0, machofp); /* no flags */ + fwriteint32_t(MH_MAGIC, machofp); /* magic */ + fwriteint32_t(CPU_TYPE_I386, machofp); /* CPU type */ + fwriteint32_t(CPU_SUBTYPE_I386_ALL, machofp); /* CPU subtype */ + fwriteint32_t(MH_OBJECT, machofp); /* Mach-O file type */ + fwriteint32_t(head_ncmds, machofp); /* number of load commands */ + fwriteint32_t(head_sizeofcmds, machofp); /* size of load commands */ + fwriteint32_t(0, machofp); /* no flags */ } /* Write out the segment load command at offset. */ -static unsigned long macho_write_segment (unsigned long offset) +static uint32_t macho_write_segment (uint32_t offset) { - unsigned long s_addr = 0; - unsigned long rel_base = alignlong (offset + seg_filesize); - unsigned long s_reloff = 0; + uint32_t s_addr = 0; + uint32_t rel_base = alignint32_t (offset + seg_filesize); + uint32_t s_reloff = 0; struct section *s; - fwritelong(LC_SEGMENT, machofp); /* cmd == LC_SEGMENT */ + fwriteint32_t(LC_SEGMENT, machofp); /* cmd == LC_SEGMENT */ /* size of load command including section load commands */ - fwritelong(MACHO_SEGCMD_SIZE + seg_nsects * + fwriteint32_t(MACHO_SEGCMD_SIZE + seg_nsects * MACHO_SECTCMD_SIZE, machofp); /* in an MH_OBJECT file all sections are in one unnamed (name ** all zeros) segment */ fwrite("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16, 1, machofp); - fwritelong(0, machofp); /* in-memory offset */ - fwritelong(seg_vmsize, machofp); /* in-memory size */ - fwritelong(offset, machofp); /* in-file offset to data */ - fwritelong(seg_filesize, machofp); /* in-file size */ - fwritelong(VM_PROT_DEFAULT, machofp); /* maximum vm protection */ - fwritelong(VM_PROT_DEFAULT, machofp); /* initial vm protection */ - fwritelong(seg_nsects, machofp); /* number of sections */ - fwritelong(0, machofp); /* no flags */ + fwriteint32_t(0, machofp); /* in-memory offset */ + fwriteint32_t(seg_vmsize, machofp); /* in-memory size */ + fwriteint32_t(offset, machofp); /* in-file offset to data */ + fwriteint32_t(seg_filesize, machofp); /* in-file size */ + fwriteint32_t(VM_PROT_DEFAULT, machofp); /* maximum vm protection */ + fwriteint32_t(VM_PROT_DEFAULT, machofp); /* initial vm protection */ + fwriteint32_t(seg_nsects, machofp); /* number of sections */ + fwriteint32_t(0, machofp); /* no flags */ /* emit section headers */ for (s = sects; s != NULL; s = s->next) { fwrite(s->sectname, sizeof(s->sectname), 1, machofp); fwrite(s->segname, sizeof(s->segname), 1, machofp); - fwritelong(s_addr, machofp); - fwritelong(s->size, machofp); + fwriteint32_t(s_addr, machofp); + fwriteint32_t(s->size, machofp); /* dummy data for zerofill sections or proper values */ if ((s->flags & SECTION_TYPE) != S_ZEROFILL) { - fwritelong(offset, machofp); + fwriteint32_t(offset, machofp); /* Write out section alignment, as a power of two. e.g. 32-bit word alignment would be 2 (2^^2 = 4). */ - fwritelong(s->align, machofp); + fwriteint32_t(s->align, machofp); /* To be compatible with cctools as we emit a zero reloff if we have no relocations. */ - fwritelong(s->nreloc ? rel_base + s_reloff : 0, machofp); - fwritelong(s->nreloc, machofp); + fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, machofp); + fwriteint32_t(s->nreloc, machofp); offset += s->size; s_reloff += s->nreloc * MACHO_RELINFO_SIZE; } else { - fwritelong(0, machofp); - fwritelong(0, machofp); - fwritelong(0, machofp); - fwritelong(0, machofp); + fwriteint32_t(0, machofp); + fwriteint32_t(0, machofp); + fwriteint32_t(0, machofp); + fwriteint32_t(0, machofp); } - fwritelong(s->flags, machofp); /* flags */ - fwritelong(0, machofp); /* reserved */ - fwritelong(0, machofp); /* reserved */ + fwriteint32_t(s->flags, machofp); /* flags */ + fwriteint32_t(0, machofp); /* reserved */ + fwriteint32_t(0, machofp); /* reserved */ s_addr += s->size; } @@ -923,16 +924,16 @@ static unsigned long macho_write_segment (unsigned long offset) static void macho_write_relocs (struct reloc *r) { while (r) { - unsigned long word2; + uint32_t word2; - fwritelong(r->addr, machofp); /* reloc offset */ + fwriteint32_t(r->addr, machofp); /* reloc offset */ word2 = r->snum; word2 |= r->pcrel << 24; word2 |= r->length << 25; word2 |= r->ext << 27; word2 |= r->type << 28; - fwritelong(word2, machofp); /* reloc data */ + fwriteint32_t(word2, machofp); /* reloc data */ r = r->next; } @@ -943,9 +944,9 @@ static void macho_write_section (void) { struct section *s, *s2; struct reloc *r; - char *rel_paddata = "\0\0\0"; - unsigned char fi, *p, *q, blk[4]; - long l; + int8_t *rel_paddata = "\0\0\0"; + uint8_t fi, *p, *q, blk[4]; + int32_t l; for (s = sects; s != NULL; s = s->next) { if ((s->flags & SECTION_TYPE) == S_ZEROFILL) @@ -959,17 +960,17 @@ static void macho_write_section (void) * for more information. */ saa_rewind(s->data); for (r = s->relocs; r != NULL; r = r->next) { - saa_fread(s->data, r->addr, blk, (long)r->length << 1); + saa_fread(s->data, r->addr, blk, (int32_t)r->length << 1); p = q = blk; l = *p++; /* get offset based on relocation type */ if (r->length > 0) { - l += ((long)*p++) << 8; + l += ((int32_t)*p++) << 8; if (r->length == 2) { - l += ((long)*p++) << 16; - l += ((long)*p++) << 24; + l += ((int32_t)*p++) << 16; + l += ((int32_t)*p++) << 24; } } @@ -993,14 +994,14 @@ static void macho_write_section (void) else *q++ = l & 0xFF; - saa_fwrite(s->data, r->addr, blk, (long)r->length << 1); + saa_fwrite(s->data, r->addr, blk, (int32_t)r->length << 1); } /* dump the section data to file */ saa_fpwrite(s->data, machofp); } - /* pad last section up to reloc entries on long boundary */ + /* pad last section up to reloc entries on int32_t boundary */ fwrite(rel_paddata, rel_padcnt, 1, machofp); /* emit relocation entries */ @@ -1014,17 +1015,17 @@ static void macho_write_symtab (void) { struct symbol *sym; struct section *s; - long fi; - long i; + int32_t fi; + int32_t i; /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */ for (sym = syms; sym != NULL; sym = sym->next) { if ((sym->type & N_EXT) == 0) { - fwritelong(sym->strx, machofp); /* string table entry number */ + fwriteint32_t(sym->strx, machofp); /* string table entry number */ fwrite(&sym->type, 1, 1, machofp); /* symbol type */ fwrite(&sym->sect, 1, 1, machofp); /* section */ - fwriteshort(sym->desc, machofp); /* description */ + fwriteint16_t(sym->desc, machofp); /* description */ /* Fix up the symbol value now that we know the final section sizes. */ @@ -1034,16 +1035,16 @@ static void macho_write_symtab (void) sym->value += s->size; } - fwritelong(sym->value, machofp); /* value (i.e. offset) */ + fwriteint32_t(sym->value, machofp); /* value (i.e. offset) */ } } for (i = 0; i < nextdefsym; i++) { sym = extdefsyms[i]; - fwritelong(sym->strx, machofp); + fwriteint32_t(sym->strx, machofp); fwrite(&sym->type, 1, 1, machofp); /* symbol type */ fwrite(&sym->sect, 1, 1, machofp); /* section */ - fwriteshort(sym->desc, machofp); /* description */ + fwriteint16_t(sym->desc, machofp); /* description */ /* Fix up the symbol value now that we know the final section sizes. */ @@ -1053,15 +1054,15 @@ static void macho_write_symtab (void) sym->value += s->size; } - fwritelong(sym->value, machofp); /* value (i.e. offset) */ + fwriteint32_t(sym->value, machofp); /* value (i.e. offset) */ } for (i = 0; i < nundefsym; i++) { sym = undefsyms[i]; - fwritelong(sym->strx, machofp); + fwriteint32_t(sym->strx, machofp); fwrite(&sym->type, 1, 1, machofp); /* symbol type */ fwrite(&sym->sect, 1, 1, machofp); /* section */ - fwriteshort(sym->desc, machofp); /* description */ + fwriteint16_t(sym->desc, machofp); /* description */ /* Fix up the symbol value now that we know the final section sizes. */ @@ -1071,7 +1072,7 @@ static void macho_write_symtab (void) sym->value += s->size; } - fwritelong(sym->value, machofp); /* value (i.e. offset) */ + fwriteint32_t(sym->value, machofp); /* value (i.e. offset) */ } } @@ -1099,76 +1100,76 @@ static void macho_fixup_relocs (struct reloc *r) static void macho_write (void) { - unsigned long offset = 0; + uint32_t offset = 0; /* mach-o object file structure: ** ** mach header - ** ulong magic + ** uint32_t magic ** int cpu type ** int cpu subtype - ** ulong mach file type - ** ulong number of load commands - ** ulong size of all load commands + ** uint32_t mach file type + ** uint32_t number of load commands + ** uint32_t size of all load commands ** (includes section struct size of segment command) - ** ulong flags + ** uint32_t flags ** ** segment command - ** ulong command type == LC_SEGMENT - ** ulong size of load command + ** uint32_t command type == LC_SEGMENT + ** uint32_t size of load command ** (including section load commands) - ** char[16] segment name - ** ulong in-memory offset - ** ulong in-memory size - ** ulong in-file offset to data area - ** ulong in-file size + ** int8_t[16] segment name + ** uint32_t in-memory offset + ** uint32_t in-memory size + ** uint32_t in-file offset to data area + ** uint32_t in-file size ** (in-memory size excluding zerofill sections) ** int maximum vm protection ** int initial vm protection - ** ulong number of sections - ** ulong flags + ** uint32_t number of sections + ** uint32_t flags ** ** section commands - ** char[16] section name - ** char[16] segment name - ** ulong in-memory offset - ** ulong in-memory size - ** ulong in-file offset - ** ulong alignment + ** int8_t[16] section name + ** int8_t[16] segment name + ** uint32_t in-memory offset + ** uint32_t in-memory size + ** uint32_t in-file offset + ** uint32_t alignment ** (irrelevant in MH_OBJECT) - ** ulong in-file offset of relocation entires - ** ulong number of relocations - ** ulong flags - ** ulong reserved - ** ulong reserved + ** uint32_t in-file offset of relocation entires + ** uint32_t number of relocations + ** uint32_t flags + ** uint32_t reserved + ** uint32_t reserved ** ** symbol table command - ** ulong command type == LC_SYMTAB - ** ulong size of load command - ** ulong symbol table offset - ** ulong number of symbol table entries - ** ulong string table offset - ** ulong string table size + ** uint32_t command type == LC_SYMTAB + ** uint32_t size of load command + ** uint32_t symbol table offset + ** uint32_t number of symbol table entries + ** uint32_t string table offset + ** uint32_t string table size ** ** raw section data ** - ** padding to long boundary + ** padding to int32_t boundary ** ** relocation data (struct reloc) - ** long offset + ** int32_t offset ** uint data (symbolnum, pcrel, length, extern, type) ** ** symbol table data (struct nlist) - ** long string table entry number - ** uchar type + ** int32_t string table entry number + ** uint8_t type ** (extern, absolute, defined in section) - ** uchar section + ** uint8_t section ** (0 for global symbols, section number of definition (>= 1, <= ** 254) for local symbols, size of variable for common symbols ** [type == extern]) - ** short description + ** int16_t description ** (for stab debugging format) - ** ulong value (i.e. file offset) of symbol or stab offset + ** uint32_t value (i.e. file offset) of symbol or stab offset ** ** string table data ** list of null-terminated strings @@ -1187,15 +1188,15 @@ static void macho_write (void) if (nsyms > 0) { /* write out symbol command */ - fwritelong(LC_SYMTAB, machofp); /* cmd == LC_SYMTAB */ - fwritelong(MACHO_SYMCMD_SIZE, machofp); /* size of load command */ - fwritelong(offset, machofp); /* symbol table offset */ - fwritelong(nsyms, machofp); /* number of symbol + fwriteint32_t(LC_SYMTAB, machofp); /* cmd == LC_SYMTAB */ + fwriteint32_t(MACHO_SYMCMD_SIZE, machofp); /* size of load command */ + fwriteint32_t(offset, machofp); /* symbol table offset */ + fwriteint32_t(nsyms, machofp); /* number of symbol ** table entries */ offset += nsyms * MACHO_NLIST_SIZE; - fwritelong(offset, machofp); /* string table offset */ - fwritelong(strslen, machofp); /* string table size */ + fwriteint32_t(offset, machofp); /* string table offset */ + fwriteint32_t(strslen, machofp); /* string table size */ } /* emit section data */ diff --git a/output/outobj.c b/output/outobj.c index 84a7bcd..b77cdae 100644 --- a/output/outobj.c +++ b/output/outobj.c @@ -11,6 +11,7 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" @@ -131,8 +132,8 @@ struct ObjRecord { ObjRecord *child; /* Associated record below this one */ ObjRecord **up; /* Master pointer to this ObjRecord */ ObjRecord *back; /* Previous part of this record */ - unsigned long parm[OBJ_PARMS]; /* Parameters for ori routine */ - unsigned char buf[RECORD_MAX + 3]; + uint32_t parm[OBJ_PARMS]; /* Parameters for ori routine */ + uint8_t buf[RECORD_MAX + 3]; }; static void obj_fwrite(ObjRecord * orp); @@ -268,7 +269,7 @@ static ObjRecord *obj_commit(ObjRecord * orp) /* * Write a byte */ -static ObjRecord *obj_byte(ObjRecord * orp, unsigned char val) +static ObjRecord *obj_byte(ObjRecord * orp, uint8_t val) { orp = obj_check(orp, 1); orp->buf[orp->used] = val; @@ -303,7 +304,7 @@ static ObjRecord *obj_rword(ObjRecord * orp, unsigned int val) /* * Write a dword */ -static ObjRecord *obj_dword(ObjRecord * orp, unsigned long val) +static ObjRecord *obj_dword(ObjRecord * orp, uint32_t val) { orp = obj_check(orp, 4); orp->buf[orp->used] = val; @@ -336,7 +337,7 @@ static ObjRecord *obj_force(ObjRecord * orp, int x) * This routine writes a field of size x. The caller does not need to worry at * all about whether 16-bits or 32-bits are required. */ -static ObjRecord *obj_x(ObjRecord * orp, unsigned long val) +static ObjRecord *obj_x(ObjRecord * orp, uint32_t val) { if (orp->type & 1) orp->x_size = 32; @@ -361,7 +362,7 @@ static ObjRecord *obj_index(ObjRecord * orp, unsigned int val) /* * Writes a variable length value */ -static ObjRecord *obj_value(ObjRecord * orp, unsigned long val) +static ObjRecord *obj_value(ObjRecord * orp, uint32_t val) { if (val <= 128) return (obj_byte(orp, val)); @@ -378,10 +379,10 @@ static ObjRecord *obj_value(ObjRecord * orp, unsigned long val) /* * Writes a counted string */ -static ObjRecord *obj_name(ObjRecord * orp, char *name) +static ObjRecord *obj_name(ObjRecord * orp, int8_t *name) { int len = strlen(name); - unsigned char *ptr; + uint8_t *ptr; orp = obj_check(orp, len + 1); ptr = orp->buf + orp->used; @@ -458,13 +459,13 @@ static void ori_null(ObjRecord * orp) * This concludes the low level section of outobj.c */ -static char obj_infile[FILENAME_MAX]; +static int8_t obj_infile[FILENAME_MAX]; static efunc error; static evalfunc evaluate; static ldfunc deflabel; static FILE *ofp; -static long first_seg; +static int32_t first_seg; static int any_segs; static int passtwo; static int arrindex; @@ -479,13 +480,13 @@ struct Group; struct LineNumber { struct LineNumber *next; struct Segment *segment; - long offset; - long lineno; + int32_t offset; + int32_t lineno; }; static struct FileName { struct FileName *next; - char *name; + int8_t *name; struct LineNumber *lnhead, **lntail; int index; } *fnhead, **fntail; @@ -500,17 +501,17 @@ static struct Array { static struct Public { struct Public *next; - char *name; - long offset; - long segment; /* only if it's far-absolute */ + int8_t *name; + int32_t offset; + int32_t segment; /* only if it's far-absolute */ int type; /* only for local debug syms */ } *fpubhead, **fpubtail, *last_defined; static struct External { struct External *next; - char *name; - long commonsize; - long commonelem; /* element size if FAR, else zero */ + int8_t *name; + int32_t commonsize; + int32_t commonelem; /* element size if FAR, else zero */ int index; /* OBJ-file external index */ enum { DEFWRT_NONE, /* no unusual default-WRT */ @@ -519,7 +520,7 @@ static struct External { DEFWRT_GROUP /* a group */ } defwrt_type; union { - char *string; + int8_t *string; struct Segment *seg; struct Group *grp; } defwrt_ptr; @@ -535,49 +536,49 @@ static struct ExtBack { static struct Segment { struct Segment *next; - long index; /* the NASM segment id */ - long obj_index; /* the OBJ-file segment index */ - struct Group *grp; /* the group it belongs to */ - unsigned long currentpos; - long align; /* can be SEG_ABS + absolute addr */ + int32_t index; /* the NASM segment id */ + int32_t obj_index; /* the OBJ-file segment index */ + struct Group *grp; /* the group it beint32_ts to */ + uint32_t currentpos; + int32_t align; /* can be SEG_ABS + absolute addr */ enum { CMB_PRIVATE = 0, CMB_PUBLIC = 2, CMB_STACK = 5, CMB_COMMON = 6 } combine; - long use32; /* is this segment 32-bit? */ + int32_t use32; /* is this segment 32-bit? */ struct Public *pubhead, **pubtail, *lochead, **loctail; - char *name; - char *segclass, *overlay; /* `class' is a C++ keyword :-) */ + int8_t *name; + int8_t *segclass, *overlay; /* `class' is a C++ keyword :-) */ ObjRecord *orp; } *seghead, **segtail, *obj_seg_needs_update; static struct Group { struct Group *next; - char *name; - long index; /* NASM segment id */ - long obj_index; /* OBJ-file group index */ - long nentries; /* number of elements... */ - long nindices; /* ...and number of index elts... */ + int8_t *name; + int32_t index; /* NASM segment id */ + int32_t obj_index; /* OBJ-file group index */ + int32_t nentries; /* number of elements... */ + int32_t nindices; /* ...and number of index elts... */ union { - long index; - char *name; + int32_t index; + int8_t *name; } segs[GROUP_MAX]; /* ...in this */ } *grphead, **grptail, *obj_grp_needs_update; static struct ImpDef { struct ImpDef *next; - char *extname; - char *libname; + int8_t *extname; + int8_t *libname; unsigned int impindex; - char *impname; + int8_t *impname; } *imphead, **imptail; static struct ExpDef { struct ExpDef *next; - char *intname; - char *extname; + int8_t *intname; + int8_t *extname; unsigned int ordinal; int flags; } *exphead, **exptail; @@ -587,16 +588,16 @@ static struct ExpDef { #define EXPDEF_FLAG_NODATA 0x20 #define EXPDEF_MASK_PARMCNT 0x1F -static long obj_entry_seg, obj_entry_ofs; +static int32_t obj_entry_seg, obj_entry_ofs; struct ofmt of_obj; /* The current segment */ static struct Segment *current_seg; -static long obj_segment(char *, int, int *); +static int32_t obj_segment(int8_t *, int, int *); static void obj_write_file(int debuginfo); -static int obj_directive(char *, char *, int); +static int obj_directive(int8_t *, int8_t *, int); static void obj_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) { @@ -631,7 +632,7 @@ static void obj_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) of_obj.current_dfmt->init(&of_obj, NULL, fp, errfunc); } -static int obj_set_info(enum geninfo type, char **val) +static int obj_set_info(enum geninfo type, int8_t **val) { (void)type; (void)val; @@ -694,7 +695,7 @@ static void obj_cleanup(int debuginfo) } } -static void obj_ext_set_defwrt(struct External *ext, char *id) +static void obj_ext_set_defwrt(struct External *ext, int8_t *id) { struct Segment *seg; struct Group *grp; @@ -721,8 +722,8 @@ static void obj_ext_set_defwrt(struct External *ext, char *id) dws = ext; } -static void obj_deflabel(char *name, long segment, - long offset, int is_global, char *special) +static void obj_deflabel(int8_t *name, int32_t segment, + int32_t offset, int is_global, int8_t *special) { /* * We have three cases: @@ -887,7 +888,7 @@ static void obj_deflabel(char *name, long segment, * We might have a default-WRT specification. */ if (!nasm_strnicmp(special, "wrt", 3)) { - char *p; + int8_t *p; int len; special += 3; special += strspn(special, " \t"); @@ -989,15 +990,15 @@ static void obj_deflabel(char *name, long segment, /* forward declaration */ static void obj_write_fixup(ObjRecord * orp, int bytes, - int segrel, long seg, long wrt, + int segrel, int32_t seg, int32_t wrt, struct Segment *segto); -static void obj_out(long segto, const void *data, unsigned long type, - long segment, long wrt) +static void obj_out(int32_t segto, const void *data, uint32_t type, + int32_t segment, int32_t wrt) { - unsigned long size, realtype; - const unsigned char *ucdata; - long ldata; + uint32_t size, realtype; + const uint8_t *ucdata; + int32_t ldata; struct Segment *seg; ObjRecord *orp; @@ -1059,7 +1060,7 @@ static void obj_out(long segto, const void *data, unsigned long type, if (segment >= SEG_ABS) error(ERR_NONFATAL, "far-absolute relocations not supported" " by OBJ format"); - ldata = *(long *)data; + ldata = *(int32_t *)data; if (realtype == OUT_REL2ADR) { ldata += (size - 2); size = 2; @@ -1101,13 +1102,13 @@ static void obj_out(long segto, const void *data, unsigned long type, } static void obj_write_fixup(ObjRecord * orp, int bytes, - int segrel, long seg, long wrt, + int segrel, int32_t seg, int32_t wrt, struct Segment *segto) { unsigned locat; int method; int base; - long tidx, fidx; + int32_t tidx, fidx; struct Segment *s = NULL; struct Group *g = NULL; struct External *e = NULL; @@ -1170,7 +1171,7 @@ static void obj_write_fixup(ObjRecord * orp, int bytes, if (g) method = 5, tidx = g->obj_index; else { - long i = seg / 2; + int32_t i = seg / 2; struct ExtBack *eb = ebhead; while (i >= EXT_BLKSIZ) { if (eb) @@ -1229,7 +1230,7 @@ static void obj_write_fixup(ObjRecord * orp, int bytes, if (g) method |= 0x10, fidx = g->obj_index; else { - long i = wrt / 2; + int32_t i = wrt / 2; struct ExtBack *eb = ebhead; while (i >= EXT_BLKSIZ) { if (eb) @@ -1254,7 +1255,7 @@ static void obj_write_fixup(ObjRecord * orp, int bytes, obj_commit(forp); } -static long obj_segment(char *name, int pass, int *bits) +static int32_t obj_segment(int8_t *name, int pass, int *bits) { /* * We call the label manager here to define a name for the new @@ -1276,7 +1277,7 @@ static long obj_segment(char *name, int pass, int *bits) struct Group *grp; struct External **extp; int obj_idx, i, attrs, rn_error; - char *p; + int8_t *p; /* * Look for segment attributes. @@ -1505,10 +1506,10 @@ static long obj_segment(char *name, int pass, int *bits) } } -static int obj_directive(char *directive, char *value, int pass) +static int obj_directive(int8_t *directive, int8_t *value, int pass) { if (!strcmp(directive, "group")) { - char *p, *q, *v; + int8_t *p, *q, *v; if (pass == 1) { struct Group *grp; struct Segment *seg; @@ -1622,7 +1623,7 @@ static int obj_directive(char *directive, char *value, int pass) return 1; } if (!strcmp(directive, "import")) { - char *q, *extname, *libname, *impname; + int8_t *q, *extname, *libname, *impname; if (pass == 2) return 1; /* ignore in pass two */ @@ -1668,7 +1669,7 @@ static int obj_directive(char *directive, char *value, int pass) return 1; } if (!strcmp(directive, "export")) { - char *q, *extname, *intname, *v; + int8_t *q, *extname, *intname, *v; struct ExpDef *export; int flags = 0; unsigned int ordinal = 0; @@ -1747,7 +1748,7 @@ static int obj_directive(char *directive, char *value, int pass) return 0; } -static long obj_segbase(long segment) +static int32_t obj_segbase(int32_t segment) { struct Segment *seg; @@ -1762,7 +1763,7 @@ static long obj_segbase(long segment) /* * Might be an external with a default WRT. */ - long i = segment / 2; + int32_t i = segment / 2; struct ExtBack *eb = ebhead; struct External *e; @@ -1796,7 +1797,7 @@ static long obj_segbase(long segment) return segment; /* no special treatment */ } -static void obj_filename(char *inname, char *outname, efunc lerror) +static void obj_filename(int8_t *inname, int8_t *outname, efunc lerror) { strcpy(obj_infile, inname); standard_extension(inname, outname, ".obj", lerror); @@ -1812,7 +1813,7 @@ static void obj_write_file(int debuginfo) struct External *ext; struct ImpDef *imp; struct ExpDef *export; - static char boast[] = "The Netwide Assembler " NASM_VER; + static int8_t boast[] = "The Netwide Assembler " NASM_VER; int lname_idx; ObjRecord *orp; @@ -1876,7 +1877,7 @@ static void obj_write_file(int debuginfo) /* * Write the first LNAMES record, containing LNAME one, which - * is null. Also initialise the LNAME counter. + * is null. Also initialize the LNAME counter. */ orp->type = LNAMES; obj_byte(orp, 0); @@ -1907,7 +1908,7 @@ static void obj_write_file(int debuginfo) orp->type = SEGDEF; for (seg = seghead; seg; seg = seg->next) { int acbp; - unsigned long seglen = seg->currentpos; + uint32_t seglen = seg->currentpos; acbp = (seg->combine << 2); /* C field */ @@ -2274,7 +2275,7 @@ static void obj_write_file(int debuginfo) void obj_fwrite(ObjRecord * orp) { unsigned int cksum, len; - unsigned char *ptr; + uint8_t *ptr; cksum = orp->type; if (orp->x_size == 32) @@ -2282,14 +2283,14 @@ void obj_fwrite(ObjRecord * orp) fputc(cksum, ofp); len = orp->committed + 1; cksum += (len & 0xFF) + ((len >> 8) & 0xFF); - fwriteshort(len, ofp); + fwriteint16_t(len, ofp); fwrite(orp->buf, 1, len - 1, ofp); for (ptr = orp->buf; --len; ptr++) cksum += *ptr; fputc((-cksum) & 0xFF, ofp); } -static const char *obj_stdmac[] = { +static const int8_t *obj_stdmac[] = { "%define __SECT__ [section .text]", "%imacro group 1+.nolist", "[group %1]", @@ -2350,7 +2351,7 @@ static void dbgbi_cleanup(void) } } -static void dbgbi_linnum(const char *lnfname, long lineno, long segto) +static void dbgbi_linnum(const int8_t *lnfname, int32_t lineno, int32_t segto) { struct FileName *fn; struct LineNumber *ln; @@ -2401,8 +2402,8 @@ static void dbgbi_linnum(const char *lnfname, long lineno, long segto) fn->lntail = &ln->next; } -static void dbgbi_deflabel(char *name, long segment, - long offset, int is_global, char *special) +static void dbgbi_deflabel(int8_t *name, int32_t segment, + int32_t offset, int is_global, int8_t *special) { struct Segment *seg; @@ -2457,7 +2458,7 @@ static void dbgbi_deflabel(char *name, long segment, loc->offset = offset; } } -static void dbgbi_typevalue(long type) +static void dbgbi_typevalue(int32_t type) { int vsize; int elem = TYM_ELEMENTS(type); @@ -2468,7 +2469,7 @@ static void dbgbi_typevalue(long type) switch (type) { case TY_BYTE: - last_defined->type = 8; /* unsigned char */ + last_defined->type = 8; /* uint8_t */ vsize = 1; break; case TY_WORD: diff --git a/output/outrdf.c b/output/outrdf.c index dff7cad..624cc72 100644 --- a/output/outrdf.c +++ b/output/outrdf.c @@ -27,10 +27,10 @@ #ifdef OF_RDF -typedef short int16; /* not sure if this will be required to be altered +typedef int16_t int16; /* not sure if this will be required to be altered at all... best to typedef it just in case */ -static const char *RDOFFId = "RDOFF1"; /* written to start of RDOFF files */ +static const int8_t *RDOFFId = "RDOFF1"; /* written to start of RDOFF files */ /* the records that can be found in the RDOFF header */ @@ -42,40 +42,40 @@ static const char *RDOFFId = "RDOFF1"; /* written to start of RDOFF files */ * 32764. */ struct RelocRec { - char type; /* must be 1 */ - char segment; /* only 0 for code, or 1 for data supported, + int8_t type; /* must be 1 */ + int8_t segment; /* only 0 for code, or 1 for data supported, * but add 64 for relative refs (ie do not require * reloc @ loadtime, only linkage) */ - long offset; /* from start of segment in which reference is loc'd */ - char length; /* 1 2 or 4 bytes */ + int32_t offset; /* from start of segment in which reference is loc'd */ + int8_t length; /* 1 2 or 4 bytes */ int16 refseg; /* segment to which reference refers to */ }; struct ImportRec { - char type; /* must be 2 */ + int8_t type; /* must be 2 */ int16 segment; /* segment number allocated to the label for reloc * records - label is assumed to be at offset zero * in this segment, so linker must fix up with offset * of segment and of offset within segment */ - char label[33]; /* zero terminated... should be written to file until + int8_t label[33]; /* zero terminated... should be written to file until * the zero, but not after it - max len = 32 chars */ }; struct ExportRec { - char type; /* must be 3 */ - char segment; /* segment referred to (0/1) */ - long offset; /* offset within segment */ - char label[33]; /* zero terminated as above. max len = 32 chars */ + int8_t type; /* must be 3 */ + int8_t segment; /* segment referred to (0/1) */ + int32_t offset; /* offset within segment */ + int8_t label[33]; /* zero terminated as above. max len = 32 chars */ }; struct DLLRec { - char type; /* must be 4 */ - char libname[128]; /* name of library to link with at load time */ + int8_t type; /* must be 4 */ + int8_t libname[128]; /* name of library to link with at load time */ }; struct BSSRec { - char type; /* must be 5 */ - long amount; /* number of bytes BSS to reserve */ + int8_t type; /* must be 5 */ + int32_t amount; /* number of bytes BSS to reserve */ }; /* code for managing buffers needed to seperate code and data into individual @@ -87,7 +87,7 @@ struct BSSRec { typedef struct memorybuffer { int length; - char buffer[BUF_BLOCK_LEN]; + int8_t buffer[BUF_BLOCK_LEN]; struct memorybuffer *next; } memorybuffer; @@ -105,7 +105,7 @@ static memorybuffer *newmembuf(void) static void membufwrite(memorybuffer * b, void *data, int bytes) { int16 w; - long l; + int32_t l; if (b->next) { /* memory buffer full - use next buffer */ membufwrite(b->next, data, bytes); @@ -114,7 +114,7 @@ static void membufwrite(memorybuffer * b, void *data, int bytes) if ((bytes < 0 && b->length - bytes > BUF_BLOCK_LEN) || (bytes > 0 && b->length + bytes > BUF_BLOCK_LEN)) { - /* buffer full and no next allocated... allocate and initialise next + /* buffer full and no next allocated... allocate and initialize next * buffer */ b->next = newmembuf(); @@ -124,7 +124,7 @@ static void membufwrite(memorybuffer * b, void *data, int bytes) switch (bytes) { case -4: /* convert to little-endian */ - l = *(long *)data; + l = *(int32_t *)data; b->buffer[b->length++] = l & 0xFF; l >>= 8; b->buffer[b->length++] = l & 0xFF; @@ -143,9 +143,9 @@ static void membufwrite(memorybuffer * b, void *data, int bytes) default: while (bytes--) { - b->buffer[b->length++] = *(*(unsigned char **)&data); + b->buffer[b->length++] = *(*(uint8_t **)&data); - (*(unsigned char **)&data)++; + (*(uint8_t **)&data)++; } break; } @@ -190,7 +190,7 @@ static FILE *ofile; static efunc error; static int segtext, segdata, segbss; -static long bsslength; +static int32_t bsslength; static void rdf_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) { @@ -209,7 +209,7 @@ static void rdf_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) bsslength = 0; } -static long rdf_section_names(char *name, int pass, int *bits) +static int32_t rdf_section_names(int8_t *name, int pass, int *bits) { /* * Default is 32 bits. @@ -275,8 +275,8 @@ static void write_dll_rec(struct DLLRec *r) membufwrite(header, r->libname, strlen(r->libname) + 1); } -static void rdf_deflabel(char *name, long segment, long offset, - int is_global, char *special) +static void rdf_deflabel(int8_t *name, int32_t segment, int32_t offset, + int is_global, int8_t *special) { struct ExportRec r; struct ImportRec ri; @@ -320,12 +320,12 @@ static void rdf_deflabel(char *name, long segment, long offset, } } -static void rdf_out(long segto, void *data, unsigned long type, - long segment, long wrt) +static void rdf_out(int32_t segto, void *data, uint32_t type, + int32_t segment, int32_t wrt) { - long bytes = type & OUT_SIZMASK; + int32_t bytes = type & OUT_SIZMASK; struct RelocRec rr; - unsigned char databuf[4], *pd; + uint8_t databuf[8], *pd; if (segto == NO_SEG) { if ((type & OUT_TYPMASK) != OUT_RESERVE) @@ -350,7 +350,7 @@ static void rdf_out(long segto, void *data, unsigned long type, type &= OUT_TYPMASK; if (segto == 2 && type != OUT_RESERVE) { - error(ERR_NONFATAL, "BSS segments may not be initialised"); + error(ERR_NONFATAL, "BSS segments may not be initialized"); /* just reserve the space for now... */ @@ -389,10 +389,13 @@ static void rdf_out(long segto, void *data, unsigned long type, } pd = databuf; /* convert address to little-endian */ - if (bytes == 2) - WRITESHORT(pd, *(long *)data); + if (bytes == 4) + WRITELONG(pd, *(int32_t *)data); + else if (bytes == 8) + WRITEDLONG(pd, *(int64_t *)data); else - WRITELONG(pd, *(long *)data); + WRITESHORT(pd, *(int32_t *)data); + membufwrite(seg[segto], databuf, bytes); @@ -416,7 +419,7 @@ static void rdf_out(long segto, void *data, unsigned long type, * address of imported symbol onto it to get address relative to end of * instruction: import_address + data(offset) - end_of_instrn */ - rr.offset = *(long *)data - (rr.offset + bytes); + rr.offset = *(int32_t *)data - (rr.offset + bytes); membufwrite(seg[segto], &rr.offset, -2); } else if (type == OUT_REL4ADR) { @@ -434,15 +437,15 @@ static void rdf_out(long segto, void *data, unsigned long type, rr.refseg = segment; /* segment referred to */ write_reloc_rec(&rr); - rr.offset = *(long *)data - (rr.offset + bytes); + rr.offset = *(int32_t *)data - (rr.offset + bytes); membufwrite(seg[segto], &rr.offset, -4); } } static void rdf_cleanup(int debuginfo) { - long l; - unsigned char b[4], *d; + int32_t l; + uint8_t b[4], *d; struct BSSRec bs; (void)debuginfo; @@ -485,12 +488,12 @@ static void rdf_cleanup(int debuginfo) fclose(ofile); } -static long rdf_segbase(long segment) +static int32_t rdf_segbase(int32_t segment) { return segment; } -static int rdf_directive(char *directive, char *value, int pass) +static int rdf_directive(int8_t *directive, int8_t *value, int pass) { struct DLLRec r; @@ -506,12 +509,12 @@ static int rdf_directive(char *directive, char *value, int pass) return 0; } -static void rdf_filename(char *inname, char *outname, efunc error) +static void rdf_filename(int8_t *inname, int8_t *outname, efunc error) { standard_extension(inname, outname, ".rdf", error); } -static char *rdf_stdmac[] = { +static int8_t *rdf_stdmac[] = { "%define __SECT__ [section .text]", "%imacro library 1+.nolist", "[library %1]", @@ -521,7 +524,7 @@ static char *rdf_stdmac[] = { NULL }; -static int rdf_set_info(enum geninfo type, char **val) +static int rdf_set_info(enum geninfo type, int8_t **val) { return 0; } diff --git a/output/outrdf2.c b/output/outrdf2.c index 0baca45..e0d9f80 100644 --- a/output/outrdf2.c +++ b/output/outrdf2.c @@ -1,9 +1,7 @@ /* * outrdf2.c output routines for the Netwide Assembler to produce - * RDOFF version 2 format object files, which is used as a - * main binary format in the RadiOS (http://radios.sf.net). - * Originally Julian planned to use it in his MOSCOW - * operating system. + * RDOFF version 2 format object files, which Julian originally + * planned to use it in his MOSCOW operating system. * * The Netwide Assembler is copyright (C) 1996-1998 Simon Tatham and * Julian Hall. All rights reserved. The software is @@ -16,6 +14,7 @@ #include <string.h> #include <ctype.h> #include <assert.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" @@ -29,7 +28,7 @@ #include "rdoff/rdoff.h" /* This signature is written to start of RDOFF files */ -static const char *RDOFF2Id = RDOFF2_SIGNATURE; +static const int8_t *RDOFF2Id = RDOFF2_SIGNATURE; /* Note that whenever a segment is referred to in the RDOFF file, its number * is always half of the segment number that NASM uses to refer to it; this @@ -40,7 +39,7 @@ static const char *RDOFF2Id = RDOFF2_SIGNATURE; #define COUNT_SEGTYPES 9 -static char *segmenttypes[COUNT_SEGTYPES] = { +static int8_t *segmenttypes[COUNT_SEGTYPES] = { "null", "text", "code", "data", "comment", "lcomment", "pcomment", "symdebug", "linedebug" @@ -71,17 +70,17 @@ static FILE *ofile; static efunc error; static struct seginfo { - char *segname; + int8_t *segname; int segnumber; uint16 segtype; uint16 segreserved; - long seglength; + int32_t seglength; } segments[RDF_MAXSEGS]; static int nsegments; -static long bsslength; -static long headerlength; +static int32_t bsslength; +static int32_t headerlength; static void rdf2_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) { @@ -128,10 +127,10 @@ static void rdf2_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) headerlength = 0; } -static long rdf2_section_names(char *name, int pass, int *bits) +static int32_t rdf2_section_names(int8_t *name, int pass, int *bits) { int i; - char *p, *q; + int8_t *p, *q; int code = -1; int reserved = 0; @@ -224,7 +223,7 @@ static long rdf2_section_names(char *name, int pass, int *bits) */ static void write_reloc_rec(struct RelocRec *r) { - char buf[4], *b; + int8_t buf[4], *b; if (r->refseg != (uint16) NO_SEG && (r->refseg & 1)) /* segment base ref */ r->type = RDFREC_SEGRELOC; @@ -249,7 +248,7 @@ static void write_reloc_rec(struct RelocRec *r) */ static void write_export_rec(struct ExportRec *r) { - char buf[4], *b; + int8_t buf[4], *b; r->segment >>= 1; @@ -266,7 +265,7 @@ static void write_export_rec(struct ExportRec *r) static void write_import_rec(struct ImportRec *r) { - char buf[4], *b; + int8_t buf[4], *b; r->segment >>= 1; @@ -285,7 +284,7 @@ static void write_import_rec(struct ImportRec *r) */ static void write_bss_rec(struct BSSRec *r) { - char buf[4], *b; + int8_t buf[4], *b; saa_wbytes(header, &r->type, 1); saa_wbytes(header, &r->reclen, 1); @@ -300,7 +299,7 @@ static void write_bss_rec(struct BSSRec *r) */ static void write_common_rec(struct CommonRec *r) { - char buf[4], *b; + int8_t buf[4], *b; r->segment >>= 1; @@ -344,8 +343,8 @@ static void write_modname_rec(struct ModRec *r) /* * Handle export, import and common records. */ -static void rdf2_deflabel(char *name, long segment, long offset, - int is_global, char *special) +static void rdf2_deflabel(int8_t *name, int32_t segment, int32_t offset, + int is_global, int8_t *special) { struct ExportRec r; struct ImportRec ri; @@ -463,7 +462,7 @@ static void rdf2_deflabel(char *name, long segment, long offset, static void membufwrite(int segment, const void *data, int bytes) { int i; - char buf[4], *b; + int8_t buf[4], *b; for (i = 0; i < nsegments; i++) { if (segments[i].segnumber == segment) @@ -475,9 +474,9 @@ static void membufwrite(int segment, const void *data, int bytes) if (bytes < 0) { b = buf; if (bytes == -2) - WRITESHORT(b, *(short *)data); + WRITESHORT(b, *(int16_t *)data); else - WRITELONG(b, *(long *)data); + WRITELONG(b, *(int32_t *)data); data = buf; bytes = -bytes; } @@ -498,12 +497,12 @@ static int getsegmentlength(int segment) return segments[i].seglength; } -static void rdf2_out(long segto, const void *data, unsigned long type, - long segment, long wrt) +static void rdf2_out(int32_t segto, const void *data, uint32_t type, + int32_t segment, int32_t wrt) { - long bytes = type & OUT_SIZMASK; + int32_t bytes = type & OUT_SIZMASK; struct RelocRec rr; - unsigned char databuf[4], *pd; + uint8_t databuf[8], *pd; int seg; if (segto == NO_SEG) { @@ -533,7 +532,7 @@ static void rdf2_out(long segto, const void *data, unsigned long type, type &= OUT_TYPMASK; if (segto == 2 && type != OUT_RESERVE) { - error(ERR_NONFATAL, "BSS segments may not be initialised"); + error(ERR_NONFATAL, "BSS segments may not be initialized"); /* just reserve the space for now... */ @@ -576,10 +575,12 @@ static void rdf2_out(long segto, const void *data, unsigned long type, } pd = databuf; /* convert address to little-endian */ - if (bytes == 2) - WRITESHORT(pd, *(long *)data); + if (bytes == 4) + WRITESHORT(pd, *(int32_t *)data); + else if (bytes == 8) + WRITEDLONG(pd, *(int64_t *)data); else - WRITELONG(pd, *(long *)data); + WRITESHORT(pd, *(int32_t *)data); membufwrite(segto, databuf, bytes); @@ -600,7 +601,7 @@ static void rdf2_out(long segto, const void *data, unsigned long type, /* what do we put in the code? Simply the data. This should almost * always be zero, unless someone's doing segment arithmetic... */ - rr.offset = *(long *)data; + rr.offset = *(int32_t *)data; } else { rr.type = RDFREC_RELOC; /* type signature */ rr.segment = segto + 64; /* segment we're currently in + rel flag */ @@ -611,7 +612,7 @@ static void rdf2_out(long segto, const void *data, unsigned long type, * address of imported symbol onto it to get address relative to end of * instruction: import_address + data(offset) - end_of_instrn */ - rr.offset = *(long *)data - (rr.offset + bytes); + rr.offset = *(int32_t *)data - (rr.offset + bytes); } membufwrite(segto, &rr.offset, -2); @@ -630,7 +631,7 @@ static void rdf2_out(long segto, const void *data, unsigned long type, rr.reclen = 8; write_reloc_rec(&rr); - rr.offset = *(long *)data - (rr.offset + bytes); + rr.offset = *(int32_t *)data - (rr.offset + bytes); membufwrite(segto, &rr.offset, -4); } @@ -638,7 +639,7 @@ static void rdf2_out(long segto, const void *data, unsigned long type, static void rdf2_cleanup(int debuginfo) { - long l; + int32_t l; struct BSSRec bs; int i; @@ -668,9 +669,9 @@ static void rdf2_cleanup(int debuginfo) } l += 10; /* null segment */ - fwritelong(l, ofile); + fwriteint32_t(l, ofile); - fwritelong(headerlength, ofile); + fwriteint32_t(headerlength, ofile); saa_fpwrite(header, ofile); /* dump header */ saa_free(header); @@ -678,24 +679,24 @@ static void rdf2_cleanup(int debuginfo) if (i == 2) continue; - fwriteshort(segments[i].segtype, ofile); - fwriteshort(segments[i].segnumber, ofile); - fwriteshort(segments[i].segreserved, ofile); - fwritelong(segments[i].seglength, ofile); + fwriteint16_t(segments[i].segtype, ofile); + fwriteint16_t(segments[i].segnumber, ofile); + fwriteint16_t(segments[i].segreserved, ofile); + fwriteint32_t(segments[i].seglength, ofile); saa_fpwrite(seg[i], ofile); saa_free(seg[i]); } /* null segment - write 10 bytes of zero */ - fwritelong(0, ofile); - fwritelong(0, ofile); - fwriteshort(0, ofile); + fwriteint32_t(0, ofile); + fwriteint32_t(0, ofile); + fwriteint16_t(0, ofile); fclose(ofile); } -static long rdf2_segbase(long segment) +static int32_t rdf2_segbase(int32_t segment) { return segment; } @@ -703,7 +704,7 @@ static long rdf2_segbase(long segment) /* * Handle RDOFF2 specific directives */ -static int rdf2_directive(char *directive, char *value, int pass) +static int rdf2_directive(int8_t *directive, int8_t *value, int pass) { int n; @@ -738,12 +739,12 @@ static int rdf2_directive(char *directive, char *value, int pass) return 0; } -static void rdf2_filename(char *inname, char *outname, efunc error) +static void rdf2_filename(int8_t *inname, int8_t *outname, efunc error) { standard_extension(inname, outname, ".rdf", error); } -static const char *rdf2_stdmac[] = { +static const int8_t *rdf2_stdmac[] = { "%define __SECT__ [section .text]", "%imacro library 1+.nolist", "[library %1]", @@ -756,7 +757,7 @@ static const char *rdf2_stdmac[] = { NULL }; -static int rdf2_set_info(enum geninfo type, char **val) +static int rdf2_set_info(enum geninfo type, int8_t **val) { return 0; } @@ -13,6 +13,7 @@ #include <stddef.h> #include <string.h> #include <ctype.h> +#include <inttypes.h> #include "nasm.h" #include "insns.h" @@ -21,8 +22,8 @@ #include "float.h" extern int in_abs_seg; /* ABSOLUTE segment flag */ -extern long abs_seg; /* ABSOLUTE segment */ -extern long abs_offset; /* ABSOLUTE segment offset */ +extern int32_t abs_seg; /* ABSOLUTE segment */ +extern int32_t abs_offset; /* ABSOLUTE segment offset */ #include "regflags.c" /* List of register flags */ @@ -45,7 +46,7 @@ void parser_global_info(struct ofmt *output, loc_t * locp) location = locp; } -insn *parse_line(int pass, char *buffer, insn * result, +insn *parse_line(int pass, int8_t *buffer, insn * result, efunc errfunc, evalfunc evaluate, ldfunc ldef) { int operand; @@ -61,7 +62,7 @@ insn *parse_line(int pass, char *buffer, insn * result, result->label = NULL; /* Assume no label */ result->eops = NULL; /* must do this, whatever happens */ - result->operands = 0; /* must initialise this */ + result->operands = 0; /* must initialize this */ if (i == 0) { /* blank line - ignore */ result->opcode = -1; /* and no instruction either */ @@ -216,10 +217,10 @@ insn *parse_line(int pass, char *buffer, insn * result, } if ((i == TOKEN_FLOAT && is_comma_next()) || i == '-') { - long sign = +1L; + int32_t sign = +1L; if (i == '-') { - char *save = stdscan_bufptr; + int8_t *save = stdscan_bufptr; i = stdscan(NULL, &tokval); sign = -1L; if (i != TOKEN_FLOAT || !is_comma_next()) { @@ -252,10 +253,10 @@ insn *parse_line(int pass, char *buffer, insn * result, nasm_realloc(eop, sizeof(extop) + eop->stringlen); tail = &eop->next; *fixptr = eop; - eop->stringval = (char *)eop + sizeof(extop); + eop->stringval = (int8_t *)eop + sizeof(extop); if (eop->stringlen < 4 || !float_const(tokval.t_charptr, sign, - (unsigned char *)eop->stringval, + (uint8_t *)eop->stringval, eop->stringlen, error)) eop->type = EOT_NOTHING; i = stdscan(NULL, &tokval); /* eat the comma */ @@ -560,7 +561,7 @@ insn *parse_line(int pass, char *buffer, insn * result, if (mref) { /* it's a memory reference */ expr *e = value; int b, i, s; /* basereg, indexreg, scale */ - long o; /* offset */ + int32_t o; /* offset */ b = i = -1, o = s = 0; result->oprs[operand].hintbase = hints.base; @@ -756,7 +757,7 @@ insn *parse_line(int pass, char *buffer, insn * result, static int is_comma_next(void) { - char *p; + int8_t *p; int i; struct tokenval tv; @@ -11,7 +11,7 @@ #define NASM_PARSER_H void parser_global_info(struct ofmt *output, loc_t * locp); -insn *parse_line(int pass, char *buffer, insn * result, +insn *parse_line(int pass, int8_t *buffer, insn * result, efunc error, evalfunc evaluate, ldfunc ldef); void cleanup_insn(insn * instruction); @@ -11,14 +11,14 @@ /* Typical flow of text through preproc * - * pp_getline gets tokenised lines, either + * pp_getline gets tokenized lines, either * * from a macro expansion * * or * { * read_line gets raw text from stdmacpos, or predef, or current input file - * tokenise converts to tokens + * tokenize converts to tokens * } * * expand_mmac_params is used to expand %1 etc., unless a macro is being @@ -41,6 +41,7 @@ #include <string.h> #include <ctype.h> #include <limits.h> +#include <inttypes.h> #include "nasm.h" #include "nasmlib.h" @@ -60,7 +61,7 @@ typedef struct IncPath IncPath; */ struct SMacro { SMacro *next; - char *name; + int8_t *name; int casesense; int nparam; int in_progress; @@ -86,9 +87,9 @@ struct SMacro { */ struct MMacro { MMacro *next; - char *name; + int8_t *name; int casesense; - int nparam_min, nparam_max; + int64_t nparam_min, nparam_max; int plus; /* is the last parameter greedy? */ int nolist; /* is this macro listing-inhibited? */ int in_progress; @@ -102,7 +103,7 @@ struct MMacro { Token **params; /* actual parameters */ Token *iline; /* invocation line */ int nparam, rotate, *paramlen; - unsigned long unique; + uint32_t unique; int lineno; /* Current line number on expansion */ }; @@ -112,8 +113,8 @@ struct MMacro { struct Context { Context *next; SMacro *localmac; - char *name; - unsigned long number; + int8_t *name; + uint32_t number; }; /* @@ -137,7 +138,7 @@ struct Context { */ struct Token { Token *next; - char *text; + int8_t *text; SMacro *mac; /* associated macro for TOK_SMAC_END */ int type; }; @@ -184,7 +185,7 @@ struct Include { FILE *fp; Cond *conds; Line *expansion; - char *fname; + int8_t *fname; int lineno, lineinc; MMacro *mstk; /* stack of active macros/reps */ }; @@ -196,7 +197,7 @@ struct Include { */ struct IncPath { IncPath *next; - char *path; + int8_t *path; }; /* @@ -250,7 +251,7 @@ enum { * we treat CXZ and ECXZ as condition codes, albeit non-invertible * ones, so we need a different enum... */ -static const char *conditions[] = { +static const int8_t *conditions[] = { "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le", "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no", "np", "ns", "nz", "o", "p", "pe", "po", "s", "z" @@ -269,7 +270,7 @@ static int inverse_ccs[] = { /* * Directive names. */ -static const char *directives[] = { +static const int8_t *directives[] = { "%arg", "%assign", "%clear", "%define", "%elif", "%elifctx", "%elifdef", "%elifid", "%elifidn", "%elifidni", "%elifmacro", "%elifnctx", @@ -330,13 +331,13 @@ enum { TM_IFNDEF, TM_INCLUDE, TM_LOCAL }; -static const char *tasm_directives[] = { +static const int8_t *tasm_directives[] = { "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi", "ifndef", "include", "local" }; static int StackSize = 4; -static char *StackPointer = "ebp"; +static int8_t *StackPointer = "ebp"; static int ArgOffset = 8; static int LocalOffset = 4; @@ -349,7 +350,7 @@ static evalfunc evaluate; static int pass; /* HACK: pass 0 = generate dependencies only */ -static unsigned long unique; /* unique identifier numbers */ +static uint32_t unique; /* unique identifier numbers */ static Line *predef = NULL; @@ -384,17 +385,17 @@ static MMacro *defining; #define PARAM_DELTA 16 /* - * The standard macro set: defined as `static char *stdmac[]'. Also + * The standard macro set: defined as `static int8_t *stdmac[]'. Also * gives our position in the macro set, when we're processing it. */ #include "macros.c" -static const char **stdmacpos; +static const int8_t **stdmacpos; /* * The extra standard macros that come from the object format, if * any. */ -static const char **extrastdmac = NULL; +static const int8_t **extrastdmac = NULL; int any_extrastdmac; /* @@ -415,12 +416,12 @@ static Blocks blocks = { NULL, NULL }; static Token *expand_mmac_params(Token * tline); static Token *expand_smacro(Token * tline); static Token *expand_id(Token * tline); -static Context *get_ctx(char *name, int all_contexts); -static void make_tok_num(Token * tok, long val); -static void error(int severity, const char *fmt, ...); +static Context *get_ctx(int8_t *name, int all_contexts); +static void make_tok_num(Token * tok, int32_t val); +static void error(int severity, const int8_t *fmt, ...); static void *new_Block(size_t size); static void delete_Blocks(void); -static Token *new_Token(Token * next, int type, char *text, int txtlen); +static Token *new_Token(Token * next, int type, int8_t *text, int txtlen); static Token *delete_Token(Token * t); /* @@ -436,10 +437,10 @@ static Token *delete_Token(Token * t); * place to do it for the moment, and it is a hack (ideally it would * be nice to be able to use the NASM pre-processor to do it). */ -static char *check_tasm_directive(char *line) +static int8_t *check_tasm_directive(int8_t *line) { - int i, j, k, m, len; - char *p = line, *oldline, oldchar; + int32_t i, j, k, m, len; + int8_t *p = line, *oldline, oldchar; /* Skip whitespace */ while (isspace(*p) && *p != 0) @@ -494,10 +495,10 @@ static char *check_tasm_directive(char *line) * flags') into NASM preprocessor line number indications (`%line * lineno file'). */ -static char *prepreproc(char *line) +static int8_t *prepreproc(int8_t *line) { int lineno, fnlen; - char *fname, *oldline; + int8_t *fname, *oldline; if (line[0] == '#' && line[1] == ' ') { oldline = line; @@ -522,7 +523,7 @@ static char *prepreproc(char *line) * invariant under case changes. We implement this by applying a * perfectly normal hash function to the uppercase of the string. */ -static int hash(char *s) +static int hash(int8_t *s) { unsigned int h = 0; int i = 0; @@ -535,7 +536,7 @@ static int hash(char *s) }; while (*s) { - h += multipliers[i] * (unsigned char)(toupper(*s)); + h += multipliers[i] * (uint8_t)(toupper(*s)); s++; if (++i >= elements(multipliers)) i = 0; @@ -608,14 +609,14 @@ static void ctx_pop(void) * return lines from the standard macro set if this has not already * been done. */ -static char *read_line(void) +static int8_t *read_line(void) { - char *buffer, *p, *q; + int8_t *buffer, *p, *q; int bufsize, continued_count; if (stdmacpos) { if (*stdmacpos) { - char *ret = nasm_strdup(*stdmacpos++); + int8_t *ret = nasm_strdup(*stdmacpos++); if (!*stdmacpos && any_extrastdmac) { stdmacpos = extrastdmac; any_extrastdmac = FALSE; @@ -679,7 +680,7 @@ static char *read_line(void) } } if (p - buffer > bufsize - 10) { - long offset = p - buffer; + int32_t offset = p - buffer; bufsize += BUF_DELTA; buffer = nasm_realloc(buffer, bufsize); p = buffer + offset; /* prevent stale-pointer problems */ @@ -713,13 +714,13 @@ static char *read_line(void) } /* - * Tokenise a line of text. This is a very simple process since we + * Tokenize a line of text. This is a very simple process since we * don't need to parse the value out of e.g. numeric tokens: we * simply split one string into many. */ -static Token *tokenise(char *line) +static Token *tokenize(int8_t *line) { - char *p = line; + int8_t *p = line; int type; Token *list = NULL; Token *t, **tail = &list; @@ -768,7 +769,7 @@ static Token *tokenise(char *line) /* * A string token. */ - char c = *p; + int8_t c = *p; p++; type = TOK_STRING; while (*p && *p != c) @@ -813,7 +814,7 @@ static Token *tokenise(char *line) * Anything else is an operator of some kind. We check * for all the double-character operators (>>, <<, //, * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything - * else is a single-character operator. + * else is a single-int8_tacter operator. */ type = TOK_OTHER; if ((p[0] == '>' && p[1] == '>') || @@ -899,7 +900,7 @@ static void delete_Blocks(void) * back to the caller. It sets the type and text elements, and * also the mac and next elements to NULL. */ -static Token *new_Token(Token * next, int type, char *text, int txtlen) +static Token *new_Token(Token * next, int type, int8_t *text, int txtlen) { Token *t; int i; @@ -941,16 +942,16 @@ static Token *delete_Token(Token * t) * If expand_locals is not zero, identifiers of the form "%$*xxx" * will be transformed into ..@ctxnum.xxx */ -static char *detoken(Token * tlist, int expand_locals) +static int8_t *detoken(Token * tlist, int expand_locals) { Token *t; int len; - char *line, *p; + int8_t *line, *p; len = 0; for (t = tlist; t; t = t->next) { if (t->type == TOK_PREPROC_ID && t->text[1] == '!') { - char *p = getenv(t->text + 2); + int8_t *p = getenv(t->text + 2); nasm_free(t->text); if (p) t->text = nasm_strdup(p); @@ -963,8 +964,8 @@ static char *detoken(Token * tlist, int expand_locals) t->text[0] == '%' && t->text[1] == '$') { Context *ctx = get_ctx(t->text, FALSE); if (ctx) { - char buffer[40]; - char *p, *q = t->text + 2; + int8_t buffer[40]; + int8_t *p, *q = t->text + 2; q += strspn(q, "$"); snprintf(buffer, sizeof(buffer), "..@%lu.", ctx->number); @@ -1049,7 +1050,7 @@ static int ppscan(void *private_data, struct tokenval *tokval) if (tline->type == TOK_STRING) { int rn_warn; - char q, *r; + int8_t q, *r; int l; r = tline->text; @@ -1104,7 +1105,7 @@ static int ppscan(void *private_data, struct tokenval *tokval) * simple wrapper which calls either strcmp or nasm_stricmp * depending on the value of the `casesense' parameter. */ -static int mstrcmp(char *p, char *q, int casesense) +static int mstrcmp(int8_t *p, int8_t *q, int casesense) { return casesense ? strcmp(p, q) : nasm_stricmp(p, q); } @@ -1119,7 +1120,7 @@ static int mstrcmp(char *p, char *q, int casesense) * only the context that directly results from the number of $'s * in variable's name. */ -static Context *get_ctx(char *name, int all_contexts) +static Context *get_ctx(int8_t *name, int all_contexts) { Context *ctx; SMacro *m; @@ -1166,10 +1167,10 @@ static Context *get_ctx(char *name, int all_contexts) * the include path one by one until it finds the file or reaches * the end of the path. */ -static FILE *inc_fopen(char *file) +static FILE *inc_fopen(int8_t *file) { FILE *fp; - char *prefix = "", *combine; + int8_t *prefix = "", *combine; IncPath *ip = ipath; static int namelen = 0; int len = strlen(file); @@ -1222,7 +1223,7 @@ static FILE *inc_fopen(char *file) * is true, macro will be searched in outer contexts as well. */ static int -smacro_defined(Context * ctx, char *name, int nparam, SMacro ** defn, +smacro_defined(Context * ctx, int8_t *name, int nparam, SMacro ** defn, int nocase) { SMacro *m; @@ -1582,12 +1583,12 @@ static int if_condition(Token * tline, int i) /* * Expand macros in a string. Used in %error and %include directives. - * First tokenise the string, apply "expand_smacro" and then de-tokenise back. + * First tokenize the string, apply "expand_smacro" and then de-tokenize back. * The returned variable should ALWAYS be freed after usage. */ -void expand_macros_in_string(char **p) +void expand_macros_in_string(int8_t **p) { - Token *line = tokenise(*p); + Token *line = tokenize(*p); line = expand_smacro(line); *p = detoken(line, FALSE); } @@ -1606,9 +1607,10 @@ void expand_macros_in_string(char **p) */ static int do_directive(Token * tline) { - int i, j, k, m, nparam, nolist; + int i, j, nparam, nolist; + int64_t k, m; int offset; - char *p, *mname; + int8_t *p, *mname; Include *inc; Context *ctx; Cond *cond; @@ -1733,7 +1735,7 @@ static int do_directive(Token * tline) */ offset = ArgOffset; do { - char *arg, directive[256]; + int8_t *arg, directive[256]; int size = StackSize; /* Find the argument name */ @@ -1764,7 +1766,7 @@ static int do_directive(Token * tline) } /* Allow macro expansion of type parameter */ - tt = tokenise(tline->text); + tt = tokenize(tline->text); tt = expand_smacro(tt); if (nasm_stricmp(tt->text, "byte") == 0) { size = MAX(StackSize, 1); @@ -1788,7 +1790,7 @@ static int do_directive(Token * tline) /* Now define the macro for the argument */ snprintf(directive, sizeof(directive), "%%define %s (%s+%d)", arg, StackPointer, offset); - do_directive(tokenise(directive)); + do_directive(tokenize(directive)); offset += size; /* Move to the next argument in the list */ @@ -1812,7 +1814,7 @@ static int do_directive(Token * tline) */ offset = LocalOffset; do { - char *local, directive[256]; + int8_t *local, directive[256]; int size = StackSize; /* Find the argument name */ @@ -1845,7 +1847,7 @@ static int do_directive(Token * tline) } /* Allow macro expansion of type parameter */ - tt = tokenise(tline->text); + tt = tokenize(tline->text); tt = expand_smacro(tt); if (nasm_stricmp(tt->text, "byte") == 0) { size = MAX(StackSize, 1); @@ -1869,13 +1871,13 @@ static int do_directive(Token * tline) /* Now define the macro for the argument */ snprintf(directive, sizeof(directive), "%%define %s (%s-%d)", local, StackPointer, offset); - do_directive(tokenise(directive)); + do_directive(tokenize(directive)); offset += size; /* Now define the assign to setup the enter_c macro correctly */ snprintf(directive, sizeof(directive), "%%assign %%$localsize %%$localsize+%d", size); - do_directive(tokenise(directive)); + do_directive(tokenize(directive)); /* Move to the next argument in the list */ tline = tline->next; @@ -2868,9 +2870,9 @@ static Token *expand_mmac_params(Token * tline) (((tline->text[1] == '+' || tline->text[1] == '-') && tline->text[2]) || tline->text[1] == '%' || (tline->text[1] >= '0' && tline->text[1] <= '9'))) { - char *text = NULL; + int8_t *text = NULL; int type = 0, cc; /* type = 0 to placate optimisers */ - char tmpbuf[30]; + int8_t tmpbuf[30]; int n, i; MMacro *mac; @@ -2994,7 +2996,7 @@ static Token *expand_mmac_params(Token * tline) break; case TOK_ID: if (tt->type == TOK_ID || tt->type == TOK_NUMBER) { - char *tmp = nasm_strcat(t->text, tt->text); + int8_t *tmp = nasm_strcat(t->text, tt->text); nasm_free(t->text); t->text = tmp; t->next = delete_Token(tt); @@ -3002,7 +3004,7 @@ static Token *expand_mmac_params(Token * tline) break; case TOK_NUMBER: if (tt->type == TOK_NUMBER) { - char *tmp = nasm_strcat(t->text, tt->text); + int8_t *tmp = nasm_strcat(t->text, tt->text); nasm_free(t->text); t->text = tmp; t->next = delete_Token(tt); @@ -3029,7 +3031,7 @@ static Token *expand_smacro(Token * tline) int nparam, sparam, brackets, rescan; Token *org_tline = tline; Context *ctx; - char *mname; + int8_t *mname; /* * Trick: we should avoid changing the start token pointer since it can @@ -3082,7 +3084,7 @@ static Token *expand_smacro(Token * tline) */ if (!m->expansion) { if (!strcmp("__FILE__", m->name)) { - long num = 0; + int32_t num = 0; src_get(&num, &(tline->text)); nasm_quote(&(tline->text)); tline->type = TOK_STRING; @@ -3093,6 +3095,11 @@ static Token *expand_smacro(Token * tline) make_tok_num(tline, src_get_linnum()); continue; } + if (!strcmp("__BITS__", m->name)) { + nasm_free(tline->text); + make_tok_num(tline, globalbits); + continue; + } tline = delete_Token(tline); continue; } @@ -3161,7 +3168,7 @@ static Token *expand_smacro(Token * tline) } if (tline->type == TOK_OTHER && tline->text[1] == 0) { - char ch = tline->text[0]; + int8_t ch = tline->text[0]; if (ch == ',' && !paren && brackets <= 0) { if (++nparam >= sparam) { sparam += PARAM_DELTA; @@ -3295,7 +3302,7 @@ static Token *expand_smacro(Token * tline) /* * Now scan the entire line and look for successive TOK_IDs that resulted - * after expansion (they can't be produced by tokenise()). The successive + * after expansion (they can't be produced by tokenize()). The successive * TOK_IDs should be concatenated. * Also we look for %+ tokens and concatenate the tokens before and after * them (without white spaces in between). @@ -3310,7 +3317,7 @@ static Token *expand_smacro(Token * tline) if (t->next->type == TOK_ID || t->next->type == TOK_PREPROC_ID || t->next->type == TOK_NUMBER) { - char *p = nasm_strcat(t->text, t->next->text); + int8_t *p = nasm_strcat(t->text, t->next->text); nasm_free(t->text); t->next = delete_Token(t->next); t->text = p; @@ -3679,10 +3686,10 @@ static int expand_mmacro(Token * tline) * won't want to see same error twice (preprocessing is done once * per pass) we will want to show errors only during pass one. */ -static void error(int severity, const char *fmt, ...) +static void error(int severity, const int8_t *fmt, ...) { va_list arg; - char buff[1024]; + int8_t buff[1024]; /* If we're in a dead branch of IF or something like it, ignore the error */ if (istk && istk->conds && !emitting(istk->conds->state)) @@ -3700,7 +3707,7 @@ static void error(int severity, const char *fmt, ...) } static void -pp_reset(char *file, int apass, efunc errfunc, evalfunc eval, +pp_reset(int8_t *file, int apass, efunc errfunc, evalfunc eval, ListGen * listgen) { int h; @@ -3737,14 +3744,14 @@ pp_reset(char *file, int apass, efunc errfunc, evalfunc eval, pass = apass; } -static char *pp_getline(void) +static int8_t *pp_getline(void) { - char *line; + int8_t *line; Token *tline; while (1) { /* - * Fetch a tokenised line, either from the macro-expansion + * Fetch a tokenized line, either from the macro-expansion * buffer or from the input file. */ tline = NULL; @@ -3833,7 +3840,7 @@ static char *pp_getline(void) while (1) { /* until we get a line we can use */ if (istk->expansion) { /* from a macro expansion */ - char *p; + int8_t *p; Line *l = istk->expansion; if (istk->mstk) istk->mstk->lineno++; @@ -3848,7 +3855,7 @@ static char *pp_getline(void) line = read_line(); if (line) { /* from the current input file */ line = prepreproc(line); - tline = tokenise(line); + tline = tokenize(line); nasm_free(line); break; } @@ -3896,7 +3903,7 @@ static char *pp_getline(void) /* * We're defining a multi-line macro. We emit nothing * at all, and just - * shove the tokenised line on to the macro definition. + * shove the tokenized line on to the macro definition. */ Line *l = nasm_malloc(sizeof(Line)); l->next = defining->expansion; @@ -3928,7 +3935,7 @@ static char *pp_getline(void) tline = expand_smacro(tline); if (!expand_mmacro(tline)) { /* - * De-tokenise the line again, and emit it. + * De-tokenize the line again, and emit it. */ line = detoken(tline, TRUE); free_tlist(tline); @@ -3982,7 +3989,7 @@ static void pp_cleanup(int pass) } } -void pp_include_path(char *path) +void pp_include_path(int8_t *path) { IncPath *i; /* by alexfru: order of path inclusion fixed (was reverse order) */ @@ -4014,11 +4021,11 @@ void pp_include_path(char *path) * The function use is simple: * * The 1st call (with NULL argument) returns a pointer to the 1st path - * (char** type) or NULL if none include paths available. + * (int8_t** type) or NULL if none include paths available. * * All subsequent calls take as argument the value returned by this * function last. The return value is either the next path - * (char** type) or NULL if the end of the paths list is reached. + * (int8_t** type) or NULL if the end of the paths list is reached. * * It is maybe not the best way to do things, but I didn't want * to export too much, just one or two functions and no types or @@ -4027,7 +4034,7 @@ void pp_include_path(char *path) * Can't say I like the current situation with e.g. this path list either, * it seems to be never deallocated after creation... */ -char **pp_get_include_path_ptr(char **pPrevPath) +int8_t **pp_get_include_path_ptr(int8_t **pPrevPath) { /* This macro returns offset of a member of a structure */ #define GetMemberOffset(StructType,MemberName)\ @@ -4040,7 +4047,7 @@ char **pp_get_include_path_ptr(char **pPrevPath) else return NULL; } - i = (IncPath *) ((char *)pPrevPath - GetMemberOffset(IncPath, path)); + i = (IncPath *) ((int8_t *)pPrevPath - GetMemberOffset(IncPath, path)); i = i->next; if (i != NULL) return &i->path; @@ -4049,7 +4056,7 @@ char **pp_get_include_path_ptr(char **pPrevPath) #undef GetMemberOffset } -void pp_pre_include(char *fname) +void pp_pre_include(int8_t *fname) { Token *inc, *space, *name; Line *l; @@ -4065,18 +4072,18 @@ void pp_pre_include(char *fname) predef = l; } -void pp_pre_define(char *definition) +void pp_pre_define(int8_t *definition) { Token *def, *space; Line *l; - char *equals; + int8_t *equals; equals = strchr(definition, '='); space = new_Token(NULL, TOK_WHITESPACE, NULL, 0); def = new_Token(space, TOK_PREPROC_ID, "%define", 0); if (equals) *equals = ' '; - space->next = tokenise(definition); + space->next = tokenize(definition); if (equals) *equals = '='; @@ -4087,14 +4094,14 @@ void pp_pre_define(char *definition) predef = l; } -void pp_pre_undefine(char *definition) +void pp_pre_undefine(int8_t *definition) { Token *def, *space; Line *l; space = new_Token(NULL, TOK_WHITESPACE, NULL, 0); def = new_Token(space, TOK_PREPROC_ID, "%undef", 0); - space->next = tokenise(definition); + space->next = tokenize(definition); l = nasm_malloc(sizeof(Line)); l->next = predef; @@ -4103,14 +4110,34 @@ void pp_pre_undefine(char *definition) predef = l; } -void pp_extra_stdmac(const char **macros) +/* + * Added by Keith Kanios: + * + * This function is used to assist with "runtime" preprocessor + * directives. (e.g. pp_runtime("%define __BITS__ 64");) + * + * ERRORS ARE IGNORED HERE, SO MAKE COMPLETELY SURE THAT YOU + * PASS A VALID STRING TO THIS FUNCTION!!!!! + */ + +void pp_runtime(int8_t *definition) +{ + Token *def; + + def = tokenize(definition); + if(do_directive(def) == NO_DIRECTIVE_FOUND) + free_tlist(def); + +} + +void pp_extra_stdmac(const int8_t **macros) { extrastdmac = macros; } -static void make_tok_num(Token * tok, long val) +static void make_tok_num(Token * tok, int32_t val) { - char numbuf[20]; + int8_t numbuf[20]; snprintf(numbuf, sizeof(numbuf), "%ld", val); tok->text = nasm_strdup(numbuf); tok->type = TOK_NUMBER; @@ -9,12 +9,13 @@ #ifndef NASM_PREPROC_H #define NASM_PREPROC_H -void pp_include_path(char *); -char **pp_get_include_path_ptr(char **pPrevPath); -void pp_pre_include(char *); -void pp_pre_define(char *); -void pp_pre_undefine(char *); -void pp_extra_stdmac(const char **); +void pp_include_path(int8_t *); +int8_t **pp_get_include_path_ptr(int8_t **pPrevPath); +void pp_pre_include(int8_t *); +void pp_pre_define(int8_t *); +void pp_pre_undefine(int8_t *); +void pp_runtime(int8_t *); +void pp_extra_stdmac(const int8_t **); extern Preproc nasmpp; diff --git a/rdoff/collectn.h b/rdoff/collectn.h index 52647d1..9cb229b 100644 --- a/rdoff/collectn.h +++ b/rdoff/collectn.h @@ -2,7 +2,7 @@ * collectn.h - header file for 'collection' abstract data type. * * This file is public domain, and does not come under the NASM license. - * It, along with 'collectn.c' implements what is basically a variable + * It, aint32_t with 'collectn.c' implements what is basically a variable * length array (of pointers). */ diff --git a/rdoff/hash.c b/rdoff/hash.c index 933754a..9f80002 100644 --- a/rdoff/hash.c +++ b/rdoff/hash.c @@ -79,9 +79,9 @@ const crc32 consttab[] = { 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; -unsigned hash(const char *name) +unsigned hash(const int8_t *name) { - register const char *n; + register const int8_t *n; register crc32 hashval = 0xffffffff; for (n = name; *n; n++) diff --git a/rdoff/hash.h b/rdoff/hash.h index cda4f61..ac9af98 100644 --- a/rdoff/hash.h +++ b/rdoff/hash.h @@ -8,4 +8,4 @@ * distributed in the NASM archive. */ -unsigned hash(const char *name); +unsigned hash(const int8_t *name); diff --git a/rdoff/ldrdf.c b/rdoff/ldrdf.c index 977aeb8..ad1cc7f 100644 --- a/rdoff/ldrdf.c +++ b/rdoff/ldrdf.c @@ -47,7 +47,7 @@ struct segment_infonode { int dest_seg; /* output segment to be placed into, -1 to skip linking this segment */ - long reloc; /* segment's relocation factor */ + int32_t reloc; /* segment's relocation factor */ }; struct modulenode { @@ -55,9 +55,9 @@ struct modulenode { struct segment_infonode seginfo[RDF_MAXSEGS]; /* what are we doing with each segment? */ void *header; - char *name; + int8_t *name; struct modulenode *next; - long bss_reloc; + int32_t bss_reloc; }; #include "ldsegs.h" @@ -69,11 +69,11 @@ struct modulenode { * Function prototypes of private utility functions */ -void processmodule(const char *filename, struct modulenode *mod); +void processmodule(const int8_t *filename, struct modulenode *mod); int allocnewseg(uint16 type, uint16 reserved); int findsegment(uint16 type, uint16 reserved); -void symtab_add(const char *symbol, int segment, long offset); -int symtab_get(const char *symbol, int *segment, long *offset); +void symtab_add(const int8_t *symbol, int segment, int32_t offset); +int symtab_get(const int8_t *symbol, int *segment, int32_t *offset); /* ========================================================================= * Global data structures. @@ -91,13 +91,13 @@ struct librarynode *lastlib = NULL; void *symtab = NULL; /* objects search path */ -char *objpath = NULL; +int8_t *objpath = NULL; /* libraries search path */ -char *libpath = NULL; +int8_t *libpath = NULL; /* file to embed as a generic record */ -char *generic_rec_file = NULL; +int8_t *generic_rec_file = NULL; /* error file */ static FILE *error_file; @@ -111,7 +111,7 @@ rdf_headerbuf *newheader = NULL; */ struct SegmentHeaderRec outputseg[RDF_MAXSEGS]; int nsegs = 0; -long bss_length; +int32_t bss_length; /* global options which affect how the program behaves */ struct ldrdfoptions { @@ -157,11 +157,11 @@ void initsegments() /* * loadmodule * - * Determine the characteristics of a module, and decide what to do with + * Determine the int8_tacteristics of a module, and decide what to do with * each segment it contains (including determining destination segments and * relocation factors for segments that are kept). */ -void loadmodule(const char *filename) +void loadmodule(const int8_t *filename) { if (options.verbose) printf("loading `%s'\n", filename); @@ -207,13 +207,13 @@ void loadmodule(const char *filename) * (b) is fairly easy, because we're now keeping track of how big each * segment in our output file is... */ -void processmodule(const char *filename, struct modulenode *mod) +void processmodule(const int8_t *filename, struct modulenode *mod) { struct segconfig sconf; int seg, outseg; void *header; rdfheaderrec *hr; - long bssamount = 0; + int32_t bssamount = 0; int bss_was_referenced = 0; for (seg = 0; seg < mod->f.nsegs; seg++) { @@ -311,7 +311,7 @@ void processmodule(const char *filename, struct modulenode *mod) case RDFREC_GLOBAL:{ /* exported symbol */ int destseg; - long destreloc; + int32_t destreloc; if (hr->e.segment == 2) { bss_was_referenced = 1; @@ -395,7 +395,7 @@ void processmodule(const char *filename, struct modulenode *mod) /* * Return 1 if a given module is in the list, 0 otherwise. */ -int lookformodule(const char *name) +int lookformodule(const int8_t *name) { struct modulenode *curr = modules; @@ -457,7 +457,7 @@ int findsegment(uint16 type, uint16 reserved) * routine won't change a previously existing symbol. It will change * to segment = -2 only if the segment was previously < 0. */ -void symtab_add(const char *symbol, int segment, long offset) +void symtab_add(const int8_t *symbol, int segment, int32_t offset) { symtabEnt *ste; @@ -509,7 +509,7 @@ void symtab_add(const char *symbol, int segment, long offset) * are assumed to have -1:0 associated. Returns 1 if the symbol was * successfully located. */ -int symtab_get(const char *symbol, int *segment, long *offset) +int symtab_get(const int8_t *symbol, int *segment, int32_t *offset) { symtabEnt *ste = symtabFind(symtab, symbol); if (!ste) { @@ -529,7 +529,7 @@ int symtab_get(const char *symbol, int *segment, long *offset) * checks that a library can be opened and is in the correct format, * then adds it to the linked list of libraries. */ -void add_library(const char *name) +void add_library(const int8_t *name) { if (rdl_verify(name)) { rdl_perror("ldrdf", name); @@ -575,7 +575,7 @@ int search_libraries() int i; void *header; int segment; - long offset; + int32_t offset; int doneanything = 0, pass = 1, keepfile; rdfheaderrec *hr; @@ -675,7 +675,7 @@ int search_libraries() * all the modules into a single output module, and then writes this to a * file. */ -void write_output(const char *filename) +void write_output(const int8_t *filename) { FILE *f; rdf_headerbuf *rdfheader; @@ -685,7 +685,7 @@ void write_output(const char *filename) rdfheaderrec *hr, newrec; symtabEnt *se; segtab segs; - long offset; + int32_t offset; byte *data; if ((f = fopen(filename, "wb")) == NULL) { @@ -885,19 +885,19 @@ void write_output(const char *filename) "warning: relocation out of range " "at %s(%02x:%08lx)\n", cur->name, (int)hr->r.segment, hr->r.offset); - *data = (char)offset; + *data = (int8_t)offset; break; case 2: - offset += *(short *)data; + offset += *(int16_t *)data; if (offset < -32767 || offset > 32768) fprintf(error_file, "warning: relocation out of range " "at %s(%02x:%08lx)\n", cur->name, (int)hr->r.segment, hr->r.offset); - *(short *)data = (short)offset; + *(int16_t *)data = (int16_t)offset; break; case 4: - *(long *)data += offset; + *(int32_t *)data += offset; /* we can't easily detect overflow on this one */ break; } @@ -1097,18 +1097,18 @@ void write_output(const char *filename) */ for (i = 0; i < nsegs; i++) { uint16 s; - long l; + int32_t l; if (i == 2) continue; - s = translateshort(outputseg[i].type); + s = translateint16_t(outputseg[i].type); fwrite(&s, 2, 1, f); - s = translateshort(outputseg[i].number); + s = translateint16_t(outputseg[i].number); fwrite(&s, 2, 1, f); - s = translateshort(outputseg[i].reserved); + s = translateint16_t(outputseg[i].reserved); fwrite(&s, 2, 1, f); - l = translatelong(outputseg[i].length); + l = translateint32_t(outputseg[i].length); fwrite(&l, 4, 1, f); fwrite(outputseg[i].data, outputseg[i].length, 1, f); @@ -1138,11 +1138,11 @@ void usage() exit(0); } -int main(int argc, char **argv) +int main(int argc, int8_t **argv) { - char *outname = "aout.rdf"; + int8_t *outname = "aout.rdf"; int moduleloaded = 0; - char *respstrings[128] = { 0, }; + int8_t *respstrings[128] = { 0, }; options.verbose = 0; options.align = 16; @@ -1217,7 +1217,7 @@ int main(int argc, char **argv) } case '@':{ int i = 0; - char buf[256]; + int8_t buf[256]; FILE *f; options.respfile = 1; @@ -1237,7 +1237,7 @@ int main(int argc, char **argv) argv++, argc--; while (fgets(buf, sizeof(buf), f) != NULL) { - char *p; + int8_t *p; if (buf[0] == '\n') continue; if ((p = strchr(buf, '\n')) != NULL) diff --git a/rdoff/ldsegs.h b/rdoff/ldsegs.h index 2a8ae88..038bb39 100644 --- a/rdoff/ldsegs.h +++ b/rdoff/ldsegs.h @@ -4,12 +4,12 @@ */ #ifndef UI16 -#define UI16 unsigned short +#define UI16 uint16_t #endif struct segconfig { UI16 typelow, typehi; /* range of seg nos for which this is valid */ - char *typedesc; /* a description of the segment type */ + int8_t *typedesc; /* a description of the segment type */ UI16 dowhat; /* one of the SEG_xxxx values below */ UI16 mergetype; /* if SEG_MERGE what type segment do we merge with? 0 -> same type of segment. This type is also diff --git a/rdoff/rdf2bin.c b/rdoff/rdf2bin.c index ac51c0e..2858cd5 100644 --- a/rdoff/rdf2bin.c +++ b/rdoff/rdf2bin.c @@ -9,13 +9,13 @@ #include "rdfload.h" #include "nasmlib.h" -long origin = 0; +int32_t origin = 0; int align = 16; -char *getfilename(char *pathname) +int8_t *getfilename(int8_t *pathname) { - char *lastslash = pathname - 1; - char *i = pathname; + int8_t *lastslash = pathname - 1; + int8_t *i = pathname; while (*i) { if (*i == '/') @@ -25,12 +25,12 @@ char *getfilename(char *pathname) return lastslash + 1; } -int main(int argc, char **argv) +int main(int argc, int8_t **argv) { rdfmodule *m; int tmp; FILE *of; - char *padding; + int8_t *padding; int codepad, datapad, bsspad = 0; if (argc < 2) { diff --git a/rdoff/rdf2ihx.c b/rdoff/rdf2ihx.c index 512af55..d7cd2cd 100644 --- a/rdoff/rdf2ihx.c +++ b/rdoff/rdf2ihx.c @@ -12,13 +12,13 @@ #include "nasmlib.h" #include "symtab.h" -long origin = 0; +int32_t origin = 0; int align = 16; /* This function writes a single n-byte data record to of. Maximum value for n is 255. */ static int write_data_record(FILE * of, int ofs, int nbytes, - unsigned char *data) + uint8_t *data) { int i, iofs; unsigned int checksum; @@ -40,15 +40,15 @@ static int write_data_record(FILE * of, int ofs, int nbytes, return (ofs); } -int main(int argc, char **argv) +int main(int argc, int8_t **argv) { rdfmodule *m; int tmp; FILE *of; - char *padding; - unsigned char *segbin[2]; + int8_t *padding; + uint8_t *segbin[2]; int pad[2], segn, ofs, i; - long segaddr; + int32_t segaddr; unsigned int checksum; symtabEnt *s; diff --git a/rdoff/rdfdump.c b/rdoff/rdfdump.c index de2bb59..1244b2f 100644 --- a/rdoff/rdfdump.c +++ b/rdoff/rdfdump.c @@ -14,11 +14,11 @@ FILE *infile; -void print_header(long length, int rdf_version) +void print_header(int32_t length, int rdf_version) { - char buf[129], t, l, s, flags; - unsigned char reclen; - long o, ll; + int8_t buf[129], t, l, s, flags; + uint8_t reclen; + int32_t o, ll; uint16 rs; while (length > 0) { @@ -41,7 +41,7 @@ void print_header(long length, int rdf_version) printf(" %s: location (%04x:%08lx), length %d, " "referred seg %04x\n", t == 1 ? "relocation" : "seg relocation", (int)s, - translatelong(o), (int)l, translateshort(rs)); + translateint32_t(o), (int)l, translateint16_t(rs)); if (rdf_version >= 2 && reclen != 8) printf(" warning: reclen != 8\n"); if (rdf_version == 1) @@ -73,7 +73,7 @@ void print_header(long length, int rdf_version) printf(" proc"); if (flags & SYM_DATA) printf(" data"); - printf(": segment %04x = %s\n", translateshort(rs), buf); + printf(": segment %04x = %s\n", translateint16_t(rs), buf); if (rdf_version == 1) length -= ll + 3; if (rdf_version == 1 && t == 7) @@ -100,7 +100,7 @@ void print_header(long length, int rdf_version) printf(" proc"); if (flags & SYM_DATA) printf(" data"); - printf(": (%04x:%08lx) = %s\n", (int)s, translatelong(o), buf); + printf(": (%04x:%08lx) = %s\n", (int)s, translateint32_t(o), buf); if (rdf_version == 1) length -= ll + 6; break; @@ -126,7 +126,7 @@ void print_header(long length, int rdf_version) case RDFREC_BSS: /* BSS reservation */ fread(&ll, 4, 1, infile); - printf(" bss reservation: %08lx bytes\n", translatelong(ll)); + printf(" bss reservation: %08lx bytes\n", translateint32_t(ll)); if (rdf_version == 1) length -= 5; if (rdf_version > 1 && reclen != 4) @@ -134,8 +134,8 @@ void print_header(long length, int rdf_version) break; case RDFREC_COMMON:{ - unsigned short seg, align; - unsigned long size; + uint16_t seg, align; + uint32_t size; fread(&seg, 2, 1, infile); fread(&size, 4, 1, infile); @@ -143,8 +143,8 @@ void print_header(long length, int rdf_version) for (ll = 0; ll < reclen - 8; ll++) fread(buf + ll, 1, 1, infile); printf(" common: segment %04x = %s, %ld:%d\n", - translateshort(seg), buf, translatelong(size), - translateshort(align)); + translateint16_t(seg), buf, translateint32_t(size), + translateint16_t(align)); break; } @@ -162,19 +162,19 @@ void print_header(long length, int rdf_version) } } -int main(int argc, char **argv) +int main(int argc, int8_t **argv) { - char id[7]; - long l; + int8_t id[7]; + int32_t l; uint16 s; int verbose = 0; - long offset; + int32_t offset; int foundnullsegment = 0; int version; - long segmentcontentlength = 0; + int32_t segmentcontentlength = 0; int nsegments = 0; - long headerlength = 0; - long objectlength = 0; + int32_t headerlength = 0; + int32_t objectlength = 0; printf("RDOFF dump utility, version %s\n", PROGRAM_VERSION); printf("RDOFF2 revision %s\n", RDOFF2_REVISION); @@ -217,18 +217,18 @@ int main(int argc, char **argv) if (version > 1) { fread(&l, 4, 1, infile); - objectlength = translatelong(l); + objectlength = translateint32_t(l); printf("Object content size: %ld bytes\n", objectlength); } fread(&l, 4, 1, infile); - headerlength = translatelong(l); + headerlength = translateint32_t(l); printf("Header (%ld bytes):\n", headerlength); print_header(headerlength, version); if (version == 1) { fread(&l, 4, 1, infile); - l = translatelong(l); + l = translateint32_t(l); printf("\nText segment length = %ld bytes\n", l); offset = 0; while (l--) { @@ -236,7 +236,7 @@ int main(int argc, char **argv) if (verbose) { if (offset % 16 == 0) printf("\n%08lx ", offset); - printf(" %02x", (int)(unsigned char)id[0]); + printf(" %02x", (int)(uint8_t)id[0]); offset++; } } @@ -244,7 +244,7 @@ int main(int argc, char **argv) printf("\n\n"); fread(&l, 4, 1, infile); - l = translatelong(l); + l = translateint32_t(l); printf("Data segment length = %ld bytes\n", l); if (verbose) { @@ -253,7 +253,7 @@ int main(int argc, char **argv) fread(id, 1, 1, infile); if (offset % 16 == 0) printf("\n%08lx ", offset); - printf(" %02x", (int)(unsigned char)id[0]); + printf(" %02x", (int)(uint8_t)id[0]); offset++; } printf("\n"); @@ -261,7 +261,7 @@ int main(int argc, char **argv) } else { do { fread(&s, 2, 1, infile); - s = translateshort(s); + s = translateint16_t(s); if (!s) { printf("\nNULL segment\n"); foundnullsegment = 1; @@ -272,11 +272,11 @@ int main(int argc, char **argv) nsegments++; fread(&s, 2, 1, infile); - printf(" Number = %04X\n", (int)translateshort(s)); + printf(" Number = %04X\n", (int)translateint16_t(s)); fread(&s, 2, 1, infile); - printf(" Resrvd = %04X\n", (int)translateshort(s)); + printf(" Resrvd = %04X\n", (int)translateint16_t(s)); fread(&l, 4, 1, infile); - l = translatelong(l); + l = translateint32_t(l); printf(" Length = %ld bytes\n", l); segmentcontentlength += l; @@ -286,7 +286,7 @@ int main(int argc, char **argv) if (verbose) { if (offset % 16 == 0) printf("\n%08lx ", offset); - printf(" %02x", (int)(unsigned char)id[0]); + printf(" %02x", (int)(uint8_t)id[0]); offset++; } } diff --git a/rdoff/rdflib.c b/rdoff/rdflib.c index cd5861c..aa6e6f6 100644 --- a/rdoff/rdflib.c +++ b/rdoff/rdflib.c @@ -3,11 +3,11 @@ /* * an rdoff library is simply a sequence of RDOFF object files, each * preceded by the name of the module, an ASCII string of up to 255 - * characters, terminated by a zero. + * int8_tacters, terminated by a zero. * * When a library is being created, special signature block is placed * in the beginning of the file. It is a string 'RDLIB' followed by a - * version number, then long content size and a long time stamp. + * version number, then int32_t content size and a int32_t time stamp. * The module name of the signature block is '.sig'. * * @@ -19,7 +19,7 @@ * * All module names beginning with '.' are reserved for possible future * extensions. The linker ignores all such modules, assuming they have - * the format of a six byte type & version identifier followed by long + * the format of a six byte type & version identifier followed by int32_t * content size, followed by data. */ @@ -39,7 +39,7 @@ * list modules */ -const char *usage = +const int8_t *usage = "usage:\n" " rdflib x libname [extra operands]\n\n" " where x is one of:\n" @@ -50,17 +50,17 @@ const char *usage = " d - delete (module-name)\n" " t - list\n"; /* Library signature */ -const char *rdl_signature = "RDLIB2", *sig_modname = ".sig"; +const int8_t *rdl_signature = "RDLIB2", *sig_modname = ".sig"; -char **_argv; +int8_t **_argv; #define _ENDIANNESS 0 /* 0 for little, 1 for big */ -static void longtolocal(long *l) +static void int32_ttolocal(int32_t *l) { #if _ENDIANNESS - unsigned char t; - unsigned char *p = (unsigned char *)l; + uint8_t t; + uint8_t *p = (uint8_t *)l; t = p[0]; p[0] = p[3]; @@ -71,7 +71,7 @@ static void longtolocal(long *l) #endif } -char copybytes(FILE * fp, FILE * fp2, int n) +int8_t copybytes(FILE * fp, FILE * fp2, int n) { int i, t = 0; @@ -88,14 +88,14 @@ char copybytes(FILE * fp, FILE * fp2, int n) exit(1); } } - return (char)t; /* return last char read */ + return (int8_t)t; /* return last int8_t read */ } -long copylong(FILE * fp, FILE * fp2) +int32_t copyint32_t(FILE * fp, FILE * fp2) { - long l; + int32_t l; int i, t; - unsigned char *p = (unsigned char *)&l; + uint8_t *p = (uint8_t *)&l; for (i = 0; i < 4; i++) { /* skip magic no */ t = fgetc(fp); @@ -111,18 +111,18 @@ long copylong(FILE * fp, FILE * fp2) } *p++ = t; } - longtolocal(&l); + int32_ttolocal(&l); return l; } -int main(int argc, char **argv) +int main(int argc, int8_t **argv) { FILE *fp, *fp2 = NULL, *fptmp; - char *p, buf[256], c; + int8_t *p, buf[256], c; int i; - long l; + int32_t l; time_t t; - char rdbuf[10]; + int8_t rdbuf[10]; _argv = argv; @@ -207,7 +207,7 @@ int main(int argc, char **argv) while (!feof(fp)) { /* read name */ p = buf; - while ((*(p++) = (char)fgetc(fp))) + while ((*(p++) = (int8_t)fgetc(fp))) if (feof(fp)) break; @@ -240,14 +240,14 @@ int main(int argc, char **argv) else copybytes(fp, fp2, 6); - l = copylong(fp, fp2); + l = copyint32_t(fp, fp2); if (argv[1][0] == 't') printf(" %ld bytes content\n", l); copybytes(fp, fp2, l); } else if ((c = copybytes(fp, fp2, 6)) >= '2') { /* version 2 or above */ - l = copylong(fp, fp2); + l = copyint32_t(fp, fp2); if (argv[1][0] == 't') printf("RDOFF%c %ld bytes content\n", c, l); @@ -259,9 +259,9 @@ int main(int argc, char **argv) * version 1 object, so we don't have an object content * length field. */ - copybytes(fp, fp2, copylong(fp, fp2)); /* header */ - copybytes(fp, fp2, copylong(fp, fp2)); /* text */ - copybytes(fp, fp2, copylong(fp, fp2)); /* data */ + copybytes(fp, fp2, copyint32_t(fp, fp2)); /* header */ + copybytes(fp, fp2, copyint32_t(fp, fp2)); /* text */ + copybytes(fp, fp2, copyint32_t(fp, fp2)); /* data */ } if (fp2) @@ -319,7 +319,7 @@ int main(int argc, char **argv) while (!feof(fptmp)) { /* read name */ p = buf; - while ((*(p++) = (char)fgetc(fptmp))) + while ((*(p++) = (int8_t)fgetc(fptmp))) if (feof(fptmp)) break; @@ -329,13 +329,13 @@ int main(int argc, char **argv) /* check against desired name */ if (!strcmp(buf, argv[3])) { fread(p = rdbuf, 1, sizeof(rdbuf), fptmp); - l = *(long *)(p + 6); + l = *(int32_t *)(p + 6); fseek(fptmp, l, SEEK_CUR); break; } else { fwrite(buf, 1, strlen(buf) + 1, fp); /* module name */ if ((c = copybytes(fptmp, fp, 6)) >= '2') { - l = copylong(fptmp, fp); /* version 2 or above */ + l = copyint32_t(fptmp, fp); /* version 2 or above */ copybytes(fptmp, fp, l); /* entire object */ } } diff --git a/rdoff/rdfload.c b/rdoff/rdfload.c index e5da423..09e3636 100644 --- a/rdoff/rdfload.c +++ b/rdoff/rdfload.c @@ -5,7 +5,7 @@ * redistributable under the licence given in the file "Licence" * distributed in the NASM archive. * - * Permission to use this file in your own projects is granted, as long + * Permission to use this file in your own projects is granted, as int32_t * as acknowledgement is given in an appropriate manner to its authors, * with instructions of how to obtain a copy via ftp. */ @@ -27,11 +27,11 @@ extern int rdf_errno; -rdfmodule *rdfload(const char *filename) +rdfmodule *rdfload(const int8_t *filename) { rdfmodule *f; - long bsslength = 0; - char *hdr; + int32_t bsslength = 0; + int8_t *hdr; rdfheaderrec *r; f = malloc(sizeof(rdfmodule)); @@ -102,9 +102,9 @@ rdfmodule *rdfload(const char *filename) rdfheaderrewind(&f->f); - f->textrel = (long)f->t; - f->datarel = (long)f->d; - f->bssrel = (long)f->b; + f->textrel = (int32_t)f->t; + f->datarel = (int32_t)f->d; + f->bssrel = (int32_t)f->b; return f; } @@ -114,8 +114,8 @@ int rdf_relocate(rdfmodule * m) rdfheaderrec *r; Collection imports; symtabEnt e; - long rel; - unsigned char *seg; + int32_t rel; + uint8_t *seg; rdfheaderrewind(&m->f); collection_init(&imports); @@ -150,13 +150,13 @@ int rdf_relocate(rdfmodule * m) non-portable */ switch (r->r.length) { case 1: - seg[r->r.offset] += (char)rel; + seg[r->r.offset] += (int8_t)rel; break; case 2: *(uint16 *) (seg + r->r.offset) += (uint16) rel; break; case 4: - *(long *)(seg + r->r.offset) += rel; + *(int32_t *)(seg + r->r.offset) += rel; break; } break; diff --git a/rdoff/rdfload.h b/rdoff/rdfload.h index 34446b6..11c34f3 100644 --- a/rdoff/rdfload.h +++ b/rdoff/rdfload.h @@ -18,14 +18,14 @@ typedef struct RDFModuleStruct { rdffile f; /* file structure */ - unsigned char *t, *d, *b; /* text, data, and bss segments */ - long textrel; - long datarel; - long bssrel; + uint8_t *t, *d, *b; /* text, data, and bss segments */ + int32_t textrel; + int32_t datarel; + int32_t bssrel; void *symtab; } rdfmodule; -rdfmodule *rdfload(const char *filename); +rdfmodule *rdfload(const int8_t *filename); int rdf_relocate(rdfmodule * m); #endif diff --git a/rdoff/rdlar.c b/rdoff/rdlar.c index 53c12c8..dc79368 100644 --- a/rdoff/rdlar.c +++ b/rdoff/rdlar.c @@ -22,12 +22,12 @@ typedef enum { FALSE, TRUE } bool; /** Constants **/ -const char commands[] = "adnrtx"; -const char modifiers[] = "cflouvV"; +const int8_t commands[] = "adnrtx"; +const int8_t modifiers[] = "cflouvV"; /** Global variables **/ -char *progname = "rdlar"; -char **_argv = NULL; +int8_t *progname = "rdlar"; +int8_t **_argv = NULL; struct { bool createok; bool usefname; @@ -41,13 +41,13 @@ struct { #define _ENDIANNESS 0 /* 0 for little, 1 for big */ /* - * Convert long to little endian (if we were compiled on big-endian machine) + * Convert int32_t to little endian (if we were compiled on big-endian machine) */ -static void longtolocal(long *l) +static void int32_ttolocal(int32_t *l) { #if _ENDIANNESS - unsigned char t; - unsigned char *p = (unsigned char *)l; + uint8_t t; + uint8_t *p = (uint8_t *)l; t = p[0]; p[0] = p[3]; @@ -96,7 +96,7 @@ void usage(void) /* * Print an error message and exit */ -void error_exit(int errcode, bool useperror, const char *fmt, ...) +void error_exit(int errcode, bool useperror, const int8_t *fmt, ...) { va_list ap; @@ -113,7 +113,7 @@ void error_exit(int errcode, bool useperror, const char *fmt, ...) /* * Fill in and write a header */ -void put_header(struct rdlm_hdr *hdr, FILE * libfp, char *modname) +void put_header(struct rdlm_hdr *hdr, FILE * libfp, int8_t *modname) { int n = 0; @@ -128,9 +128,9 @@ void put_header(struct rdlm_hdr *hdr, FILE * libfp, char *modname) } /* - * Copy n bytes from one file to another and return last character read. + * Copy n bytes from one file to another and return last int8_tacter read. */ -char copybytes(FILE * fp, FILE * fp2, int n) +int8_t copybytes(FILE * fp, FILE * fp2, int n) { int i, t = 0; @@ -143,18 +143,18 @@ char copybytes(FILE * fp, FILE * fp2, int n) if (fputc(t, fp2) == EOF) error_exit(1, FALSE, "write error"); } - return (char)t; + return (int8_t)t; } /* - * Copy unsigned long from one file to another. - * Return local presentation of long. + * Copy uint32_t from one file to another. + * Return local presentation of int32_t. */ -long copylong(FILE * fp, FILE * fp2) +int32_t copyint32_t(FILE * fp, FILE * fp2) { - long l; + int32_t l; int i, t; - unsigned char *p = (unsigned char *)&l; + uint8_t *p = (uint8_t *)&l; for (i = 0; i < 4; i++) { t = fgetc(fp); @@ -166,14 +166,14 @@ long copylong(FILE * fp, FILE * fp2) error_exit(1, FALSE, "write error"); *p++ = t; } - longtolocal(&l); + int32_ttolocal(&l); return l; } /* * Create a new library */ -int create_library(char *libname) +int create_library(int8_t *libname) { FILE *libfp; struct rdlm_hdr hdr; @@ -200,7 +200,7 @@ int create_library(char *libname) /* * Add a module to the library */ -int add_module(FILE * libfp, const char *fname, char *modname) +int add_module(FILE * libfp, const int8_t *fname, int8_t *modname) { FILE *modfp; struct rdlm_hdr hdr = { RDLMMAG, 0, 0, 0, 0, 0, 0 }; @@ -241,13 +241,13 @@ int add_module(FILE * libfp, const char *fname, char *modname) /* * Main */ -int main(int argc, char *argv[]) +int main(int argc, int8_t *argv[]) { FILE *libfp, *tmpfp, *modfp = NULL; struct stat finfo; struct rdlm_hdr hdr; - char buf[MAXMODNAMELEN], *p = NULL; - char c; + int8_t buf[MAXMODNAMELEN], *p = NULL; + int8_t c; int i; progname = argv[0]; @@ -368,7 +368,7 @@ int main(int argc, char *argv[]) if (options.verbose) { printf("%ld bytes", hdr.size); } - putchar('\n'); + putint8_t('\n'); } copybytes(libfp, modfp, hdr.size); diff --git a/rdoff/rdlar.h b/rdoff/rdlar.h index bf9e84f..48e3293 100644 --- a/rdoff/rdlar.h +++ b/rdoff/rdlar.h @@ -17,13 +17,13 @@ #define MAXMODNAMELEN 256 /* Maximum length of module name */ struct rdlm_hdr { - unsigned long magic; /* Must be RDLAMAG */ - unsigned long hdrsize; /* Header size + sizeof(module_name) */ - unsigned long date; /* Creation date */ - unsigned long owner; /* UID */ - unsigned long group; /* GID */ - unsigned long mode; /* File mode */ - unsigned long size; /* File size */ + uint32_t magic; /* Must be RDLAMAG */ + uint32_t hdrsize; /* Header size + sizeof(module_name) */ + uint32_t date; /* Creation date */ + uint32_t owner; /* UID */ + uint32_t group; /* GID */ + uint32_t mode; /* File mode */ + uint32_t size; /* File size */ /* NULL-terminated module name immediately follows */ }; diff --git a/rdoff/rdlib.c b/rdoff/rdlib.c index 28a2bdf..8f13d1d 100644 --- a/rdoff/rdlib.c +++ b/rdoff/rdlib.c @@ -16,19 +16,19 @@ int rdl_error = 0; -char *rdl_errors[5] = { +int8_t *rdl_errors[5] = { "no error", "could not open file", "invalid file structure", "file contains modules of an unsupported RDOFF version", "module not found" }; -int rdl_verify(const char *filename) +int rdl_verify(const int8_t *filename) { FILE *fp = fopen(filename, "rb"); - char buf[257]; + int8_t buf[257]; int i; - long length; - static char lastverified[256]; + int32_t length; + static int8_t lastverified[256]; static int lastresult = -1; if (lastresult != -1 && !strcmp(filename, lastverified)) @@ -51,8 +51,8 @@ int rdl_verify(const char *filename) /* * A special module, eg a signature block or a directory. * Format of such a module is defined to be: - * six char type identifier - * long count bytes content + * six int8_t type identifier + * int32_t count bytes content * content * so we can handle it uniformaly with RDOFF2 modules. */ @@ -75,7 +75,7 @@ int rdl_verify(const char *filename) return lastresult = 0; /* library in correct format */ } -int rdl_open(struct librarynode *lib, const char *name) +int rdl_open(struct librarynode *lib, const int8_t *name) { int i = rdl_verify(name); if (i) @@ -95,13 +95,13 @@ void rdl_close(struct librarynode *lib) free(lib->name); } -int rdl_searchlib(struct librarynode *lib, const char *label, rdffile * f) +int rdl_searchlib(struct librarynode *lib, const int8_t *label, rdffile * f) { - char buf[512]; + int8_t buf[512]; int i, t; void *hdr; rdfheaderrec *r; - long l; + int32_t l; rdl_error = 0; lib->referenced++; @@ -182,9 +182,9 @@ int rdl_searchlib(struct librarynode *lib, const char *label, rdffile * f) int rdl_openmodule(struct librarynode *lib, int moduleno, rdffile * f) { - char buf[512]; + int8_t buf[512]; int i, cmod, t; - long length; + int32_t length; lib->referenced++; @@ -251,7 +251,7 @@ int rdl_openmodule(struct librarynode *lib, int moduleno, rdffile * f) return rdl_error = 4; /* module not found */ } -void rdl_perror(const char *apname, const char *filename) +void rdl_perror(const int8_t *apname, const int8_t *filename) { if (rdl_error >= 16) rdfperror(apname, filename); diff --git a/rdoff/rdlib.h b/rdoff/rdlib.h index 36438bd..0ca34ae 100644 --- a/rdoff/rdlib.h +++ b/rdoff/rdlib.h @@ -3,7 +3,7 @@ */ struct librarynode { - char *name; + int8_t *name; FILE *fp; /* initialised to NULL - always check */ int referenced; /* & open if required. Close afterwards */ struct librarynode *next; /* if ! referenced. */ @@ -16,9 +16,9 @@ extern int rdl_error; #define RDL_EVERSION 3 #define RDL_ENOTFOUND 4 -int rdl_verify(const char *filename); -int rdl_open(struct librarynode *lib, const char *filename); -int rdl_searchlib(struct librarynode *lib, const char *label, rdffile * f); +int rdl_verify(const int8_t *filename); +int rdl_open(struct librarynode *lib, const int8_t *filename); +int rdl_searchlib(struct librarynode *lib, const int8_t *label, rdffile * f); int rdl_openmodule(struct librarynode *lib, int module, rdffile * f); -void rdl_perror(const char *apname, const char *filename); +void rdl_perror(const int8_t *apname, const int8_t *filename); diff --git a/rdoff/rdoff.c b/rdoff/rdoff.c index 8f19702..9c48278 100644 --- a/rdoff/rdoff.c +++ b/rdoff/rdoff.c @@ -5,7 +5,7 @@ * redistributable under the licence given in the file "Licence" * distributed in the NASM archive. * - * Permission to use this file in your own projects is granted, as long + * Permission to use this file in your own projects is granted, as int32_t * as acknowledgement is given in an appropriate manner to its authors, * with instructions of how to obtain a copy via ftp. */ @@ -38,7 +38,7 @@ /* ======================================================================== * Code for memory buffers (for delayed writing of header until we know - * how long it is). + * how int32_t it is). * ======================================================================== */ memorybuffer *newmembuf() @@ -57,7 +57,7 @@ memorybuffer *newmembuf() void membufwrite(memorybuffer * const b, void *data, int bytes) { uint16 w; - long l; + int32_t l; if (b->next) { /* memory buffer full - use next buffer */ membufwrite(b->next, data, bytes); @@ -76,7 +76,7 @@ void membufwrite(memorybuffer * const b, void *data, int bytes) switch (bytes) { case -4: /* convert to little-endian */ - l = *(long *)data; + l = *(int32_t *)data; b->buffer[b->length++] = l & 0xFF; l >>= 8; b->buffer[b->length++] = l & 0xFF; @@ -95,9 +95,9 @@ void membufwrite(memorybuffer * const b, void *data, int bytes) default: while (bytes--) { - b->buffer[b->length++] = *(*(unsigned char **)&data); + b->buffer[b->length++] = *(*(uint8_t **)&data); - (*(unsigned char **)&data)++; + (*(uint8_t **)&data)++; } break; } @@ -133,16 +133,16 @@ void freemembuf(memorybuffer * b) ========================================================================= */ /* - * translatelong() and translateshort() + * translateint32_t() and translateint16_t() * * translate from little endian to local representation */ -long translatelong(long in) +int32_t translateint32_t(int32_t in) { - long r; - unsigned char *i; + int32_t r; + uint8_t *i; - i = (unsigned char *)∈ + i = (uint8_t *)∈ r = i[3]; r = (r << 8) + i[2]; r = (r << 8) + i[1]; @@ -151,26 +151,26 @@ long translatelong(long in) return r; } -uint16 translateshort(uint16 in) +uint16 translateint16_t(uint16 in) { uint16 r; - unsigned char *i; + uint8_t *i; - i = (unsigned char *)∈ + i = (uint8_t *)∈ r = (i[1] << 8) + i[0]; return r; } /* Segment types */ -static char *knownsegtypes[8] = { +static int8_t *knownsegtypes[8] = { "NULL", "text", "data", "object comment", "linked comment", "loader comment", "symbolic debug", "line number debug" }; /* Get a textual string describing the segment type */ -char *translatesegmenttype(uint16 type) +int8_t *translatesegmenttype(uint16 type) { if (type < 8) return knownsegtypes[type]; @@ -188,10 +188,10 @@ char *translatesegmenttype(uint16 type) } /* This signature is written to the start of RDOFF files */ -const char *RDOFFId = RDOFF2_SIGNATURE; +const int8_t *RDOFFId = RDOFF2_SIGNATURE; /* Error messages. Must correspond to the codes defined in rdoff.h */ -const char *rdf_errors[11] = { +const int8_t *rdf_errors[11] = { /* 0 */ "no error occurred", /* 1 */ "could not open file", /* 2 */ "invalid file format", @@ -211,7 +211,7 @@ int rdf_errno = 0; The library functions ======================================================================== */ -int rdfopen(rdffile * f, const char *name) +int rdfopen(rdffile * f, const int8_t *name) { FILE *fp; @@ -222,18 +222,18 @@ int rdfopen(rdffile * f, const char *name) return rdfopenhere(f, fp, NULL, name); } -int rdfopenhere(rdffile * f, FILE * fp, int *refcount, const char *name) +int rdfopenhere(rdffile * f, FILE * fp, int *refcount, const int8_t *name) { - char buf[8]; - long initpos; - long l; + int8_t buf[8]; + int32_t initpos; + int32_t l; uint16 s; - if (translatelong(0x01020304) != 0x01020304) { + if (translateint32_t(0x01020304) != 0x01020304) { /* fix this to be portable! */ fputs("*** this program requires a little endian machine\n", stderr); - fprintf(stderr, "01020304h = %08lxh\n", translatelong(0x01020304)); + fprintf(stderr, "01020304h = %08lxh\n", translateint32_t(0x01020304)); exit(3); } @@ -257,7 +257,7 @@ int rdfopenhere(rdffile * f, FILE * fp, int *refcount, const char *name) } f->header_ofs = ftell(f->fp); - f->eof_offset = f->header_ofs + translatelong(l) - 4; + f->eof_offset = f->header_ofs + translateint32_t(l) - 4; if (fseek(f->fp, f->header_len, SEEK_CUR)) { fclose(f->fp); @@ -321,7 +321,7 @@ int rdfclose(rdffile * f) /* * Print the message for last error (from rdf_errno) */ -void rdfperror(const char *app, const char *name) +void rdfperror(const int8_t *app, const int8_t *name) { fprintf(stderr, "%s:%s: %s\n", app, name, rdf_errors[rdf_errno]); if (rdf_errno == RDF_ERR_OPEN || rdf_errno == RDF_ERR_READ) { @@ -347,7 +347,7 @@ int rdffindsegment(rdffile * f, int segno) */ int rdfloadseg(rdffile * f, int segment, void *buffer) { - long fpos, slen; + int32_t fpos, slen; switch (segment) { case RDOFF_HEADER: @@ -551,7 +551,7 @@ int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r) return 0; } -int rdfaddsegment(rdf_headerbuf * h, long seglength) +int rdfaddsegment(rdf_headerbuf * h, int32_t seglength) { h->nsegments++; h->seglength += seglength; @@ -560,14 +560,14 @@ int rdfaddsegment(rdf_headerbuf * h, long seglength) int rdfwriteheader(FILE * fp, rdf_headerbuf * h) { - long l, l2; + int32_t l, l2; fwrite(RDOFFId, 1, strlen(RDOFFId), fp); l = membuflength(h->buf); l2 = l + 14 + 10 * h->nsegments + h->seglength; - l = translatelong(l); - l2 = translatelong(l2); + l = translateint32_t(l); + l2 = translateint32_t(l2); fwrite(&l2, 4, 1, fp); /* object length */ fwrite(&l, 4, 1, fp); /* header length */ diff --git a/rdoff/rdoff.h b/rdoff/rdoff.h index 68f156b..248c614 100644 --- a/rdoff/rdoff.h +++ b/rdoff/rdoff.h @@ -6,7 +6,7 @@ * redistributable under the licence given in the file "Licence" * distributed in the NASM archive. * - * Permission to use this file in your own projects is granted, as long + * Permission to use this file in your own projects is granted, as int32_t * as acknowledgement is given in an appropriate manner to its authors, * with instructions of how to obtain a copy via ftp. */ @@ -20,9 +20,9 @@ */ /* Type definitions */ -typedef unsigned long uint32; -typedef unsigned short uint16; -typedef unsigned char byte; +typedef uint32_t uint32; +typedef uint16_t uint16; +typedef uint8_t byte; typedef unsigned int bool; /* RDOFF format revision (currently used only when printing the version) */ @@ -54,12 +54,12 @@ typedef unsigned int bool; /* * Generic record - contains the type and length field, plus a 128 byte - * char array 'data' + * int8_t array 'data' */ struct GenericRec { byte type; byte reclen; - char data[128]; + int8_t data[128]; }; /* @@ -71,7 +71,7 @@ struct RelocRec { byte segment; /* only 0 for code, or 1 for data supported, but add 64 for relative refs (ie do not require reloc @ loadtime, only linkage) */ - long offset; /* from start of segment in which reference is loc'd */ + int32_t offset; /* from start of segment in which reference is loc'd */ byte length; /* 1 2 or 4 bytes */ uint16 refseg; /* segment to which reference refers to */ }; @@ -87,7 +87,7 @@ struct ImportRec { records - label is assumed to be at offset zero in this segment, so linker must fix up with offset of segment and of offset within segment */ - char label[EXIM_LABEL_MAX]; /* zero terminated, should be written to file + int8_t label[EXIM_LABEL_MAX]; /* zero terminated, should be written to file until the zero, but not after it */ }; @@ -99,8 +99,8 @@ struct ExportRec { byte reclen; /* content length */ byte flags; /* SYM_* flags (see below) */ byte segment; /* segment referred to (0/1/2) */ - long offset; /* offset within segment */ - char label[EXIM_LABEL_MAX]; /* zero terminated as in import */ + int32_t offset; /* offset within segment */ + int8_t label[EXIM_LABEL_MAX]; /* zero terminated as in import */ }; /* @@ -109,7 +109,7 @@ struct ExportRec { struct DLLRec { byte type; /* must be 4 */ byte reclen; /* content length */ - char libname[MODLIB_NAME_MAX]; /* name of library to link with at load time */ + int8_t libname[MODLIB_NAME_MAX]; /* name of library to link with at load time */ }; /* @@ -118,7 +118,7 @@ struct DLLRec { struct BSSRec { byte type; /* must be 5 */ byte reclen; /* content length */ - long amount; /* number of bytes BSS to reserve */ + int32_t amount; /* number of bytes BSS to reserve */ }; /* @@ -127,7 +127,7 @@ struct BSSRec { struct ModRec { byte type; /* must be 8 */ byte reclen; /* content length */ - char modname[MODLIB_NAME_MAX]; /* module name */ + int8_t modname[MODLIB_NAME_MAX]; /* module name */ }; /* @@ -137,9 +137,9 @@ struct CommonRec { byte type; /* must be 10 */ byte reclen; /* equals 7+label length */ uint16 segment; /* segment number */ - long size; /* size of common variable */ + int32_t size; /* size of common variable */ uint16 align; /* alignment (power of two) */ - char label[EXIM_LABEL_MAX]; /* zero terminated as in import */ + int8_t label[EXIM_LABEL_MAX]; /* zero terminated as in import */ }; /* Flags for ExportRec */ @@ -154,11 +154,11 @@ struct CommonRec { /* Some systems don't define this automatically */ #if !defined(strdup) -extern char *strdup(const char *); +extern int8_t *strdup(const int8_t *); #endif typedef union RDFHeaderRec { - char type; /* invariant throughout all below */ + int8_t type; /* invariant throughout all below */ struct GenericRec g; /* type 0 */ struct RelocRec r; /* type == 1 / 6 */ struct ImportRec i; /* type == 2 / 7 */ @@ -174,29 +174,29 @@ struct SegmentHeaderRec { uint16 type; uint16 number; uint16 reserved; - long length; + int32_t length; /* information built up here */ - long offset; + int32_t offset; byte *data; /* pointer to segment data if it exists in memory */ }; typedef struct RDFFileInfo { FILE *fp; /* file descriptor; must be open to use this struct */ int rdoff_ver; /* should be 1; any higher => not guaranteed to work */ - long header_len; - long header_ofs; + int32_t header_len; + int32_t header_ofs; byte *header_loc; /* keep location of header */ - long header_fp; /* current location within header for reading */ + int32_t header_fp; /* current location within header for reading */ struct SegmentHeaderRec seg[RDF_MAXSEGS]; int nsegs; - long eof_offset; /* offset of the first byte beyond the end of this + int32_t eof_offset; /* offset of the first byte beyond the end of this module */ - char *name; /* name of module in libraries */ + int8_t *name; /* name of module in libraries */ int *refcount; /* pointer to reference count on file, or NULL */ } rdffile; @@ -211,7 +211,7 @@ typedef struct memorybuffer { typedef struct { memorybuffer *buf; /* buffer containing header records */ int nsegments; /* number of segments to be written */ - long seglength; /* total length of all the segments */ + int32_t seglength; /* total length of all the segments */ } rdf_headerbuf; /* segments used by RDOFF, understood by rdoffloadseg */ @@ -241,30 +241,30 @@ enum { }; /* utility functions */ -long translatelong(long in); -uint16 translateshort(uint16 in); -char *translatesegmenttype(uint16 type); +int32_t translateint32_t(int32_t in); +uint16 translateint16_t(uint16 in); +int8_t *translatesegmenttype(uint16 type); /* RDOFF file manipulation functions */ -int rdfopen(rdffile * f, const char *name); -int rdfopenhere(rdffile * f, FILE * fp, int *refcount, const char *name); +int rdfopen(rdffile * f, const int8_t *name); +int rdfopenhere(rdffile * f, FILE * fp, int *refcount, const int8_t *name); int rdfclose(rdffile * f); int rdffindsegment(rdffile * f, int segno); int rdfloadseg(rdffile * f, int segment, void *buffer); rdfheaderrec *rdfgetheaderrec(rdffile * f); /* returns static storage */ void rdfheaderrewind(rdffile * f); /* back to start of header */ -void rdfperror(const char *app, const char *name); +void rdfperror(const int8_t *app, const int8_t *name); /* functions to write a new RDOFF header to a file - use rdfnewheader to allocate a header, rdfaddheader to add records to it, rdfaddsegment to notify the header routines that a segment exists, and - to tell it how long the segment will be. + to tell it how int32_t the segment will be. rdfwriteheader to write the file id, object length, and header to a file, and then rdfdoneheader to dispose of the header */ rdf_headerbuf *rdfnewheader(void); int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r); -int rdfaddsegment(rdf_headerbuf * h, long seglength); +int rdfaddsegment(rdf_headerbuf * h, int32_t seglength); int rdfwriteheader(FILE * fp, rdf_headerbuf * h); void rdfdoneheader(rdf_headerbuf * h); diff --git a/rdoff/rdx.c b/rdoff/rdx.c index 82210a6..0a23941 100644 --- a/rdoff/rdx.c +++ b/rdoff/rdx.c @@ -18,9 +18,9 @@ #include "rdfload.h" #include "symtab.h" -typedef int (*main_fn) (int, char **); /* Main function prototype */ +typedef int (*main_fn) (int, int8_t **); /* Main function prototype */ -int main(int argc, char **argv) +int main(int argc, int8_t **argv) { rdfmodule *m; main_fn code; diff --git a/rdoff/segtab.c b/rdoff/segtab.c index ed26aea..8ee1b7b 100644 --- a/rdoff/segtab.c +++ b/rdoff/segtab.c @@ -5,7 +5,7 @@ struct segtabnode { int localseg; int destseg; - long offset; + int32_t offset; struct segtabnode *left; struct segtabnode *right; @@ -36,7 +36,7 @@ void init_seglocations(segtab * root) } void descend_tree_add(struct segtabnode **node, - int localseg, int destseg, long offset) + int localseg, int destseg, int32_t offset) { struct segtabnode *n; @@ -83,14 +83,14 @@ void descend_tree_add(struct segtabnode **node, } } -void add_seglocation(segtab * root, int localseg, int destseg, long offset) +void add_seglocation(segtab * root, int localseg, int destseg, int32_t offset) { descend_tree_add((struct segtabnode **)root, localseg, destseg, offset); } int get_seglocation(segtab * root, int localseg, int *destseg, - long *offset) + int32_t *offset) { struct segtabnode *n = (struct segtabnode *)*root; diff --git a/rdoff/segtab.h b/rdoff/segtab.h index bd29357..14cb600 100644 --- a/rdoff/segtab.h +++ b/rdoff/segtab.h @@ -1,6 +1,6 @@ typedef void *segtab; void init_seglocations(segtab * r); -void add_seglocation(segtab * r, int localseg, int destseg, long offset); -int get_seglocation(segtab * r, int localseg, int *destseg, long *offset); +void add_seglocation(segtab * r, int localseg, int destseg, int32_t offset); +int get_seglocation(segtab * r, int localseg, int *destseg, int32_t *offset); void done_seglocations(segtab * r); diff --git a/rdoff/symtab.c b/rdoff/symtab.c index 8d8ac62..d05cf18 100644 --- a/rdoff/symtab.c +++ b/rdoff/symtab.c @@ -82,7 +82,7 @@ void symtabInsert(void *stab, symtabEnt * ent) } /* ------------------------------------- */ -symtabEnt *symtabFind(void *stab, const char *name) +symtabEnt *symtabFind(void *stab, const int8_t *name) { symtab mytab = (symtab) stab; int slot = slotnum(name); @@ -103,7 +103,7 @@ void symtabDump(void *stab, FILE * of) { symtab mytab = (symtab) stab; int i; - char *SegNames[3] = { "code", "data", "bss" }; + int8_t *SegNames[3] = { "code", "data", "bss" }; fprintf(of, "Symbol table is ...\n"); for (i = 0; i < SYMTABSIZE; ++i) { diff --git a/rdoff/symtab.h b/rdoff/symtab.h index 5bd9bcb..170f328 100644 --- a/rdoff/symtab.h +++ b/rdoff/symtab.h @@ -7,14 +7,14 @@ */ typedef struct { - char *name; + int8_t *name; int segment; - long offset; - long flags; + int32_t offset; + int32_t flags; } symtabEnt; void *symtabNew(void); void symtabDone(void *symtab); void symtabInsert(void *symtab, symtabEnt * ent); -symtabEnt *symtabFind(void *symtab, const char *name); +symtabEnt *symtabFind(void *symtab, const int8_t *name); void symtabDump(void *symtab, FILE * of); @@ -6,63 +6,198 @@ # A * means the line should be repeated for each value from 0 to 7 # +# Legacy Registers +# 000-007 = 8-bit Registers +# 010-017 = 16-bit Registers +# 020-027 = 32-bit Registers + +# System Registers +# 100-107 = Segment Registers +# 110-127 = Control Registers +# 130-147 = Debug Registers +# 150-167 = Test Registers + +# Legacy Extended Registers +# 200-207 = FPU Registers +# 210-217 = MMX Registers +# 220-227 = XMM Registers (XMM0-XMM7) + +# x64 Extended Registers +# 400-407 = 8-bit Extensions (SIL/DIL/BPL/SPL) +# 410-417 = 8-bit Registers (R8B-R15B) +# 420-427 = 16-bit Registers (R8W-R15W) +# 430-437 = 32-bit Registers (R8D-R15D) +# 440-457 = 64-bit Registers (RAX-RDI+R8-R15) +# 460-467 = XMM Extended Registers (XMM8-XMM15) + +# Special Registers +# 0500 = RIP (for RIP-relative Addressing) + + # General-purpose registers -al REG_AL reg8 0 -ah REG8 reg8 4 -ax REG_AX reg16 0 -eax REG_EAX reg32 0 -bl REG8 reg8 3 -bh REG8 reg8 7 -bx REG16 reg16 3 -ebx REG32 reg32 3 -cl REG_CL reg8 1 -ch REG8 reg8 5 -cx REG_CX reg16 1 -ecx REG_ECX reg32 1 -dl REG_DL reg8 2 -dh REG8 reg8 6 -dx REG_DX reg16 2 -edx REG_EDX reg32 2 -sp REG16 reg16 4 -esp REG32 reg32 4 -bp REG16 reg16 5 -ebp REG32 reg32 5 -si REG16 reg16 6 -esi REG32 reg32 6 -di REG16 reg16 7 -edi REG32 reg32 7 +al REG_AL reg8 0000 +ah REG8 reg8 0004 +ax REG_AX reg16 0010 +eax REG_EAX reg32 0020 +rax REG_RAX reg64 0440 +bl REG8 reg8 0003 +bh REG8 reg8 0007 +bx REG16 reg16 0013 +ebx REG32 reg32 0023 +rbx REG64 reg64 0443 +cl REG_CL reg8 0001 +ch REG8 reg8 0005 +cx REG_CX reg16 0011 +ecx REG_ECX reg32 0021 +rcx REG_RCX reg64 0441 +dl REG_DL reg8 0002 +dh REG8 reg8 0006 +dx REG_DX reg16 0012 +edx REG_EDX reg32 0022 +rdx REG_RDX reg64 0442 +spl REG8 reg8 0404 +sp REG16 reg16 0014 +esp REG32 reg32 0024 +rsp REG64 reg64 0444 +bpl REG8 reg8 0405 +bp REG16 reg16 0015 +ebp REG32 reg32 0025 +rbp REG64 reg64 0445 +sil REG8 reg8 0406 +si REG16 reg16 0016 +esi REG32 reg32 0026 +rsi REG64 reg64 0446 +dil REG8 reg8 0407 +di REG16 reg16 0017 +edi REG32 reg32 0027 +rdi REG64 reg64 0447 +r8b REG8 reg8 0410 +r8w REG16 reg16 0420 +r8d REG32 reg32 0430 +r8 REG64 reg64 0450 +r9b REG8 reg8 0411 +r9w REG16 reg16 0421 +r9d REG32 reg32 0431 +r9 REG64 reg64 0451 +r10b REG8 reg8 0412 +r10w REG16 reg16 0422 +r10d REG32 reg32 0432 +r10 REG64 reg64 0452 +r11b REG8 reg8 0413 +r11w REG16 reg16 0423 +r11d REG32 reg32 0433 +r11 REG64 reg64 0453 +r12b REG8 reg8 0414 +r12w REG16 reg16 0424 +r12d REG32 reg32 0434 +r12 REG64 reg64 0454 +r13b REG8 reg8 0415 +r13w REG16 reg16 0425 +r13d REG32 reg32 0435 +r13 REG64 reg64 0455 +r14b REG8 reg8 0416 +r14w REG16 reg16 0426 +r14d REG32 reg32 0436 +r14 REG64 reg64 0456 +r15b REG8 reg8 0417 +r15w REG16 reg16 0427 +r15d REG32 reg32 0437 +r15 REG64 reg64 0457 # Segment registers -cs REG_CS sreg 1 -ds REG_DESS sreg 3 -es REG_DESS sreg 0 -ss REG_DESS sreg 2 -fs REG_FSGS sreg 4 -gs REG_FSGS sreg 5 -segr6 REG_SEG67 sreg 6 -segr7 REG_SEG67 sreg 7 +cs REG_CS sreg 0101 +ds REG_DESS sreg 0103 +es REG_DESS sreg 0100 +ss REG_DESS sreg 0102 +fs REG_FSGS sreg 0104 +gs REG_FSGS sreg 0105 +segr6 REG_SEG67 sreg 0106 +segr7 REG_SEG67 sreg 0107 # Control registers -cr* REG_CREG creg * +cr0 REG_CREG creg 0110 +cr1 REG_CREG creg 0111 +cr2 REG_CREG creg 0112 +cr3 REG_CREG creg 0113 +cr4 REG_CREG creg 0114 +cr5 REG_CREG creg 0115 +cr6 REG_CREG creg 0116 +cr7 REG_CREG creg 0127 +cr8 REG_C8REG creg 0120 +cr9 REG_CREG creg 0121 +cr10 REG_CREG creg 0122 +cr11 REG_CREG creg 0123 +cr12 REG_CREG creg 0124 +cr13 REG_CREG creg 0125 +cr14 REG_CREG creg 0126 +cr15 REG_CREG creg 0127 # Debug registers -dr* REG_DREG dreg * +dr0 REG_DREG dreg 0130 +dr1 REG_DREG dreg 0131 +dr2 REG_DREG dreg 0132 +dr3 REG_DREG dreg 0133 +dr4 REG_DREG dreg 0134 +dr5 REG_DREG dreg 0135 +dr6 REG_DREG dreg 0136 +dr7 REG_DREG dreg 0137 +dr8 REG_DREG dreg 0140 +dr9 REG_DREG dreg 0141 +dr10 REG_DREG dreg 0142 +dr11 REG_DREG dreg 0143 +dr12 REG_DREG dreg 0144 +dr13 REG_DREG dreg 0145 +dr14 REG_DREG dreg 0146 +dr15 REG_DREG dreg 0147 # Test registers -tr* REG_TREG treg * +tr0 REG_TREG treg 0150 +tr1 REG_TREG treg 0151 +tr2 REG_TREG treg 0152 +tr3 REG_TREG treg 0153 +tr4 REG_TREG treg 0154 +tr5 REG_TREG treg 0155 +tr6 REG_TREG treg 0156 +tr7 REG_TREG treg 0157 # Floating-point registers -st0 FPU0 fpureg 0 -st1 FPUREG fpureg 1 -st2 FPUREG fpureg 2 -st3 FPUREG fpureg 3 -st4 FPUREG fpureg 4 -st5 FPUREG fpureg 5 -st6 FPUREG fpureg 6 -st7 FPUREG fpureg 7 +st0 FPU0 fpureg 0200 +st1 FPUREG fpureg 0201 +st2 FPUREG fpureg 0202 +st3 FPUREG fpureg 0203 +st4 FPUREG fpureg 0204 +st5 FPUREG fpureg 0205 +st6 FPUREG fpureg 0206 +st7 FPUREG fpureg 0207 # MMX registers -mm* MMXREG mmxreg * +mm0 MMXREG mmxreg 0220 +mm1 MMXREG mmxreg 0221 +mm2 MMXREG mmxreg 0222 +mm3 MMXREG mmxreg 0223 +mm4 MMXREG mmxreg 0224 +mm5 MMXREG mmxreg 0225 +mm6 MMXREG mmxreg 0226 +mm7 MMXREG mmxreg 0227 + # SSE registers -xmm* XMMREG xmmreg * +xmm0 XMMREG xmmreg 0240 +xmm1 XMMREG xmmreg 0241 +xmm2 XMMREG xmmreg 0242 +xmm3 XMMREG xmmreg 0243 +xmm4 XMMREG xmmreg 0244 +xmm5 XMMREG xmmreg 0245 +xmm6 XMMREG xmmreg 0246 +xmm7 XMMREG xmmreg 0247 +xmm8 XMMREG xmmreg 0460 +xmm9 XMMREG xmmreg 0461 +xmm10 XMMREG xmmreg 0462 +xmm11 XMMREG xmmreg 0463 +xmm12 XMMREG xmmreg 0464 +xmm13 XMMREG xmmreg 0465 +xmm14 XMMREG xmmreg 0466 +xmm15 XMMREG xmmreg 0467 + +# Special registers +rip REG_RIP ripreg 0500 @@ -10,7 +10,7 @@ sub process_line($) { my($line) = @_; my @v; - if ( $line !~ /^\s*(\S+)\s*(\S+)\s*(\S+)\s*([0-7])\s*$/ ) { + if ( $line !~ /^\s*(\S+)\s*(\S+)\s*(\S+)\s*([0-9]+)\s*$/ ) { die "regs.dat:$nline: invalid input\n"; } $reg = $1; @@ -63,11 +63,15 @@ if ( $fmt eq 'h' ) { $attach = ''; $ch = ','; } print " REG_ENUM_LIMIT\n"; - print "};\n"; + print "};\n\n"; + foreach $reg ( sort(keys(%regs)) ) { + print "#define REG_NUM_\U${reg} $regvals{$reg}\n"; + } + print "\n"; } elsif ( $fmt eq 'c' ) { # Output regs.c print "/* automatically generated from $file - do not edit */\n"; - print "static const char *reg_names[] = "; $ch = '{'; + print "static const int8_t *reg_names[] = "; $ch = '{'; # This one has no dummy entry for 0 foreach $reg ( sort(keys(%regs)) ) { print "$ch\n \"${reg}\""; @@ -77,7 +81,7 @@ if ( $fmt eq 'h' ) { } elsif ( $fmt eq 'fc' ) { # Output regflags.c print "/* automatically generated from $file - do not edit */\n"; - print "static const long reg_flags[] = {\n"; + print "static const int32_t reg_flags[] = {\n"; print " 0"; # Dummy entry for 0 foreach $reg ( sort(keys(%regs)) ) { print ",\n ", $regs{$reg}; # Print the class of the register diff --git a/standard.mac b/standard.mac index bbbf90d..fa2b8b7 100644 --- a/standard.mac +++ b/standard.mac @@ -17,10 +17,11 @@ ; here, not all of them are: the user-level form of a format-specific ; directive should be defined in the module for that directive. -; These two need to be defined, though the actual definitions will +; These three need to be defined, though the actual definitions will ; be constantly updated during preprocessing. %define __FILE__ %define __LINE__ +%define __BITS__ %define __SECT__ ; it ought to be defined, even if as nothing @@ -88,6 +89,9 @@ __SECT__ %imacro use32 0.nolist [bits 32] %endmacro +%imacro use64 0.nolist +[bits 64] +%endmacro %imacro global 1-*.nolist %rep %0 @@ -9,6 +9,7 @@ #include <stdio.h> #include <stdlib.h> #include <limits.h> +#include <inttypes.h> #include "sync.h" @@ -20,8 +21,8 @@ */ static struct Sync { - unsigned long pos; - unsigned long length; + uint32_t pos; + uint32_t length; } *synx; static int nsynx; @@ -49,7 +50,7 @@ void init_sync(void) nsynx = 0; } -void add_sync(unsigned long pos, unsigned long length) +void add_sync(uint32_t pos, uint32_t length) { int i; @@ -70,7 +71,7 @@ void add_sync(unsigned long pos, unsigned long length) } } -unsigned long next_sync(unsigned long position, unsigned long *length) +uint32_t next_sync(uint32_t position, uint32_t *length) { while (nsynx > 0 && synx[1].pos + synx[1].length <= position) { int i, j; @@ -10,7 +10,7 @@ #define NASM_SYNC_H void init_sync(void); -void add_sync(unsigned long position, unsigned long length); -unsigned long next_sync(unsigned long position, unsigned long *length); +void add_sync(uint32_t position, uint32_t length); +uint32_t next_sync(uint32_t position, uint32_t *length); #endif diff --git a/test/aouttest.c b/test/aouttest.c index 68b9f07..2514ce1 100644 --- a/test/aouttest.c +++ b/test/aouttest.c @@ -7,10 +7,11 @@ */ #include <stdio.h> +#include <inttypes.h> -extern int lrotate(long, int); +extern int lrotate(int32_t, int); extern void greet(void); -extern char asmstr[]; +extern int8_t asmstr[]; extern void *selfptr; extern void *textptr; extern int integer, commvar; diff --git a/test/cofftest.c b/test/cofftest.c index e259aef..0ffce3e 100644 --- a/test/cofftest.c +++ b/test/cofftest.c @@ -7,9 +7,9 @@ #include <stdio.h> -extern int lrotate(long, int); +extern int lrotate(int32_t, int); extern void greet(void); -extern char asmstr[]; +extern int8_t asmstr[]; extern void *selfptr; extern void *textptr; extern int integer, commvar; diff --git a/test/elftest.c b/test/elftest.c index 8ad481e..e6f472e 100644 --- a/test/elftest.c +++ b/test/elftest.c @@ -8,9 +8,9 @@ #include <stdio.h> -extern int lrotate(long, int); +extern int lrotate(int32_t, int); extern void greet(void); -extern char asmstr[]; +extern int8_t asmstr[]; extern void *selfptr; extern void *textptr; extern int integer, commvar; diff --git a/test/objlink.c b/test/objlink.c index 05ff732..982ca59 100644 --- a/test/objlink.c +++ b/test/objlink.c @@ -9,9 +9,9 @@ #include <stdio.h> -char text[] = "hello, world\n"; +int8_t text[] = "hello, world\n"; -extern void function(char *); +extern void function(int8_t *); extern int bsssym, commvar; extern void *selfptr; extern void *selfptr2; @@ -19,9 +19,9 @@ extern void *selfptr2; int main(void) { printf("these should be identical: %p, %p\n", - (long)selfptr, (long)&selfptr); + (int32_t)selfptr, (int32_t)&selfptr); printf("these should be equivalent but different: %p, %p\n", - (long)selfptr2, (long)&selfptr2); + (int32_t)selfptr2, (int32_t)&selfptr2); printf("you should see \"hello, world\" twice:\n"); bsssym = 0xF00D; commvar = 0xD00F; @@ -1 +1 @@ -0.98.40 +0.99.00 |