diff options
author | H. Peter Anvin (Intel) <hpa@zytor.com> | 2020-06-27 15:36:59 -0700 |
---|---|---|
committer | H. Peter Anvin (Intel) <hpa@zytor.com> | 2020-06-27 15:36:59 -0700 |
commit | 513e19c8da06745525492b58795d8d8caa545049 (patch) | |
tree | da6c947aa0aff1a4fd00ee538e14d64e827166f3 | |
parent | f53966af8b81d7ef11f46f084a4f91e9faa55914 (diff) | |
parent | a825b33423d5046dfc4c0992c3ebfea5b8a531c4 (diff) | |
download | nasm-513e19c8da06745525492b58795d8d8caa545049.tar.gz |
Merge tag 'nasm-2.15'
NASM 2.15
Resolved Conflicts:
version
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | Mkfiles/msvc.mak | 2 | ||||
-rw-r--r-- | Mkfiles/openwcom.mak | 2 | ||||
-rw-r--r-- | asm/assemble.c | 1 | ||||
-rw-r--r-- | asm/directiv.c | 2 | ||||
-rw-r--r-- | asm/eval.c | 2 | ||||
-rw-r--r-- | asm/floats.c (renamed from asm/float.c) | 2 | ||||
-rw-r--r-- | asm/floats.h (renamed from asm/float.h) | 10 | ||||
-rw-r--r-- | asm/nasm.c | 2 | ||||
-rw-r--r-- | asm/parser.c | 2 | ||||
-rw-r--r-- | doc/changes.src | 10 | ||||
-rw-r--r-- | doc/nasmdoc.src | 201 | ||||
-rw-r--r-- | output/codeview.c | 62 | ||||
-rw-r--r-- | output/outelf.c | 173 | ||||
-rw-r--r-- | test/Makefile | 19 | ||||
-rw-r--r-- | test/a64.asm | 22 | ||||
-rw-r--r-- | test/dup.asm | 4 | ||||
-rw-r--r-- | x86/insns.dat | 6 |
18 files changed, 382 insertions, 142 deletions
diff --git a/Makefile.in b/Makefile.in index dbf8c6e3..dd4bf09f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -123,7 +123,7 @@ LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \ x86/disp8.$(O) x86/iflag.$(O) \ \ asm/error.$(O) asm/warnings.$(O) \ - asm/float.$(O) \ + asm/floats.$(O) \ asm/directiv.$(O) asm/directbl.$(O) \ asm/pragma.$(O) \ asm/assemble.$(O) asm/labels.$(O) asm/parser.$(O) \ diff --git a/Mkfiles/msvc.mak b/Mkfiles/msvc.mak index 09bb42fe..f004e984 100644 --- a/Mkfiles/msvc.mak +++ b/Mkfiles/msvc.mak @@ -87,7 +87,7 @@ LIBOBJ = stdlib\snprintf.$(O) stdlib\vsnprintf.$(O) stdlib\strlcpy.$(O) \ x86\disp8.$(O) x86\iflag.$(O) \ \ asm\error.$(O) asm\warnings.$(O) \ - asm\float.$(O) \ + asm\floats.$(O) \ asm\directiv.$(O) asm\directbl.$(O) \ asm\pragma.$(O) \ asm\assemble.$(O) asm\labels.$(O) asm\parser.$(O) \ diff --git a/Mkfiles/openwcom.mak b/Mkfiles/openwcom.mak index d13b780f..82ce05ac 100644 --- a/Mkfiles/openwcom.mak +++ b/Mkfiles/openwcom.mak @@ -76,7 +76,7 @@ LIBOBJ = stdlib\snprintf.$(O) stdlib\vsnprintf.$(O) stdlib\strlcpy.$(O) & x86\disp8.$(O) x86\iflag.$(O) & & asm\error.$(O) asm\warnings.$(O) & - asm\float.$(O) & + asm\floats.$(O) & asm\directiv.$(O) asm\directbl.$(O) & asm\pragma.$(O) & asm\assemble.$(O) asm\labels.$(O) asm\parser.$(O) & diff --git a/asm/assemble.c b/asm/assemble.c index 7a0830ca..e5d5682c 100644 --- a/asm/assemble.c +++ b/asm/assemble.c @@ -2083,7 +2083,6 @@ static void gencode(struct out_data *data, insn *ins) break; case 0313: - ins->rex = 0; break; case4(0314): diff --git a/asm/directiv.c b/asm/directiv.c index 96464d62..53422098 100644 --- a/asm/directiv.c +++ b/asm/directiv.c @@ -43,7 +43,7 @@ #include "nasmlib.h" #include "ilog2.h" #include "error.h" -#include "float.h" +#include "floats.h" #include "stdscan.h" #include "preproc.h" #include "eval.h" @@ -45,7 +45,7 @@ #include "error.h" #include "eval.h" #include "labels.h" -#include "float.h" +#include "floats.h" #include "assemble.h" #define TEMPEXPRS_DELTA 128 diff --git a/asm/float.c b/asm/floats.c index 77d576c6..adc6afbf 100644 --- a/asm/float.c +++ b/asm/floats.c @@ -40,7 +40,7 @@ #include "nctype.h" #include "nasm.h" -#include "float.h" +#include "floats.h" #include "error.h" /* diff --git a/asm/float.h b/asm/floats.h index b07e542a..4f80acac 100644 --- a/asm/float.h +++ b/asm/floats.h @@ -32,12 +32,12 @@ * ----------------------------------------------------------------------- */ /* - * float.h header file for the floating-point constant module of - * the Netwide Assembler + * floats.h header file for the floating-point constant module of + * the Netwide Assembler */ -#ifndef NASM_FLOAT_H -#define NASM_FLOAT_H +#ifndef NASM_FLOATS_H +#define NASM_FLOATS_H #include "nasm.h" @@ -51,4 +51,4 @@ enum float_round { int float_const(const char *string, int sign, uint8_t *result, int bytes); int float_option(const char *option); -#endif +#endif /* NASM_FLOATS_H */ @@ -44,7 +44,7 @@ #include "error.h" #include "saa.h" #include "raa.h" -#include "float.h" +#include "floats.h" #include "stdscan.h" #include "insns.h" #include "preproc.h" diff --git a/asm/parser.c b/asm/parser.c index a59acb19..de24103e 100644 --- a/asm/parser.c +++ b/asm/parser.c @@ -46,7 +46,7 @@ #include "stdscan.h" #include "eval.h" #include "parser.h" -#include "float.h" +#include "floats.h" #include "assemble.h" #include "tables.h" diff --git a/doc/changes.src b/doc/changes.src index 85f3a9e2..c1e7451a 100644 --- a/doc/changes.src +++ b/doc/changes.src @@ -9,6 +9,16 @@ since 2007. \S{cl-2.15} Version 2.15 +\b The comparison and booleanizing operators can now be used in any +expression context, not just \c{%if}. See \k{expr}. + +\b New operator \c{?} ... \c{:}. See \k{exptri}. + +\b Signed shift operators \c{<<<} and \c{>>>}. See \k{expshift}. + +\b The MASM \c{DUP} syntax for data definitions is now supported, in a +somewhat enhanced form. See \k{db}. + \b Warn for strange legacy behavior regarding empty arguments in multi-line macro expansion, but try to match legacy behavior in most cases. Legacy behavior can be disabled with the directive \c{%pragma diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src index 4378a0a2..8d815396 100644 --- a/doc/nasmdoc.src +++ b/doc/nasmdoc.src @@ -88,6 +88,7 @@ \IR{$, prefix} \c{$}, prefix \IR{$$} \c{$$} token \IR{%} \c{%} operator +\IR{%db} \c{%} prefix to \c{DB} lists \IR{%%} \c{%%} operator \IR{%+1} \c{%+1} and \c{%-1} syntax \IA{%-1}{%+1} @@ -100,14 +101,19 @@ \IR{//} \c{//} operator \IR{<} \c{<} operator \IR{<<} \c{<<} operator +\IR{<<<} \c{<<<} operator +\IR{<=>} \c{<=>} operator \IR{<=} \c{<=} operator \IR{<>} \c{<>} operator +\IR{<=>} \c{<=>} operator \IR{=} \c{=} operator \IR{==} \c{==} operator \IR{>} \c{>} operator \IR{>=} \c{>=} operator \IR{>>} \c{>>} operator -\IR{?} \c{?} MASM syntax +\IR{>>>} \c{>>>} operator +\IR{?db} \c{?}, data syntax +\IR{?op} \c{?}, operator \IR{^} \c{^} operator \IR{^^} \c{^^} operator \IR{|} \c{|} operator @@ -161,6 +167,7 @@ in ELF \IR{dos} DOS \IR{dos archive} DOS archive \IR{dos source archive} DOS source archive +\IR{dup} \c{DUP} \IA{effective address}{effective addresses} \IA{effective-address}{effective addresses} \IR{elf} ELF @@ -202,6 +209,7 @@ convention \IR{macho64} \c{macho64} \IR{macos x} MacOS X \IR{masm} MASM +\IR{masmdb} MASM, \c{DB} syntax \IA{memory reference}{memory references} \IR{minix} Minix \IA{misc directory}{misc subdirectory} @@ -1112,13 +1120,14 @@ 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{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 +Historically, 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 \c{?} as a valid character in symbol names, you can code \c{? equ 0} and then writing \c{dw ?} will at least do something vaguely useful. -\I\c{RESB}\i\c{DUP} is still not a supported syntax, however. + +As of NASM 2.15, the MASM syntax is also supported. In addition to all of this, macros and directives work completely differently to MASM. See \k{preproc} and \k{directive} for further @@ -1254,6 +1263,49 @@ the output file. They can be invoked in a wide range of ways: \c{DT}, \c{DO}, \c{DY} and \c{DZ} do not accept \i{numeric constants} as operands. +\I{masmdb} Starting in NASM 2.15, a the following MASM-like features +have been implemented: + +\b A \I{?db}\c{?} argument to declare uninitialized data: + +\c db ? ; uninitialized data + +\b A superset of the \i\c{DUP} syntax. The NASM version of this has +the following syntax specification; capital letters indicate literal +keywords: + +\c dx := DB | DW | DD | DQ | DT | DO | DY | DZ +\c type := BYTE | WORD | DWORD | QWORD | TWORD | OWORD | YWORD | ZWORD +\c atom := expression | string | float | '?' +\c parlist := '(' value [, value ...] ')' +\c duplist := expression DUP [type] ['%'] parlist +\c list := duplist | '%' parlist | type ['%'] parlist +\c value := atom | type value | list +\c +\c stmt := dx value [, value...] + +\> Note that a \e{list} needs to be prefixed with a \I{%db}\c{%} sign unless +prefixed by either \c{DUP} or a \e{type} in order to avoid confusing it with +a parentesis starting an expression. The following expressions are all +valid: + +\c db 33 +\c db (44) ; Integer expression +\c ; db (44,55) ; Invalid - error +\c db %(44,55) +\c db %('XX','YY') +\c db ('AA') ; Integer expression - outputs single byte +\c db %('BB') ; List, containing a string +\c db ? +\c db 6 dup (33) +\c db 6 dup (33, 34) +\c db 6 dup (33, 34), 35 +\c db 7 dup (99) +\c db 7 dup dword (?, word ?, ?) +\c dw byte (?,44) +\c dw 3 dup (0xcc, 4 dup byte ('PQR'), ?), 0xabcd +\c dd 16 dup (0xaaaa, ?, 0xbbbbbb) +\c dd 64 dup (?) \S{resb} \c{RESB} and Friends: Declaring \i{Uninitialized} Data @@ -1261,11 +1313,9 @@ as operands. \i\c{RESO}, \i\c{RESY} and \i\c\{RESZ} are designed to be used in the BSS section of a module: they declare \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 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}. +words, doublewords or whatever to reserve. The operand to a +\c{RESB}-type pseudo-instruction is a \i\e{critical expression}: see +\k{crit}. For example: @@ -1275,6 +1325,17 @@ For example: \c ymmval: resy 1 ; one YMM register \c zmmvals: resz 32 ; 32 ZMM registers +\I{masmdb} Since NASM 2.15, the MASM syntax of using \I{?db}\c{?} +and \i\c{DUP} in the \c{D}\e{x} directives is also supported. Thus, +the above example could also be written: + +\c buffer: db 64 dup (?) ; reserve 64 bytes +\c wordvar: dw ? ; reserve a word +\c realarray dq 10 dup (?) ; array of ten reals +\c ymmval: dy ? ; one YMM register +\c zmmvals: dz 32 dup (?) ; 32 ZMM registers + + \S{incbin} \i\c{INCBIN}: Including External \i{Binary Files} \c{INCBIN} is borrowed from the old Amiga assembler \i{DevPac}: it @@ -1726,12 +1787,71 @@ into the section you are by using \c{($-$$)}. The arithmetic \i{operators} provided by NASM are listed here, in increasing order of \i{precedence}. +A \e{boolean} value is true if nonzero and false if zero. The +operators which return a boolean value always return 1 for true and 0 +for false. + + +\S{exptri} \I{?op}\c{?} ... \c{:}: Conditional Operator + +The syntax of this operator, similar to the C conditional operator, is: + +\e{boolean} \c{?} \e{trueval} \c{:} \e{falseval} + +This operator evaluates to \e{trueval} if \e{boolean} is true, +otherwise to \e{falseval}. + +Note that NASM allows \c{?} characters in symbol names. Therefore, it +is highly advisable to always put spaces around the \c{?} and \c{:} +characters. + + +\S{expbor}: \i\c{||}: \i{Boolean OR} Operator + +The \c{||} operator gives a boolean OR: it evaluates to 1 if both sides of +the expression are nonzero, otherwise 0. + + +\S{expbxor}: \i\c{^^}: \i{Boolean XOR} Operator + +The \c{^^} operator gives a boolean XOR: it evaluates to 1 if any one side of +the expression is nonzero, otherwise 0. + + +\S{expband}: \i\c{&&}: \i{Boolean AND} Operator + +The \c{&&} operator gives a boolean AND: it evaluates to 1 if both sides of +the expression is nonzero, otherwise 0. + + +\S{exprel}: \i{Comparison Operators} + +NASM supports the following comparison operators: + +\b \i\c{=} or \i\c{==} compare for equality. + +\b \i\c{!=} or \i\c{<>} compare for inequality. + +\b \i\c{<} compares signed less than. + +\b \i\c{<=} compares signed less than or equal. + +\b \i\c{>} compares signed greater than. + +\b \i\c{>=} compares signed greather than or equal. + +These operators evaluate to 0 for false or 1 for true. + +\b \i{<=>} does a signed comparison, and evaluates to -1 for less +than, 0 for equal, and 1 for greater than. + +At this time, NASM does not provide unsigned comparison operators. + \S{expor} \i\c{|}: \i{Bitwise OR} Operator The \c{|} operator gives a bitwise OR, exactly as performed by the -\c{OR} machine instruction. Bitwise OR is the lowest-priority -arithmetic operator supported by NASM. +\c{OR} machine instruction. \S{expxor} \i\c{^}: \i{Bitwise XOR} Operator @@ -1744,13 +1864,18 @@ arithmetic operator supported by NASM. \c{&} provides the bitwise AND operation. -\S{expshift} \i\c{<<} and \i\c{>>}: \i{Bit Shift} Operators +\S{expshift} \i{Bit Shift} Operators -\c{<<} gives a bit-shift to the left, just as it does in C. So \c{5<<3} -evaluates to 5 times 8, or 40. \c{>>} gives a bit-shift to the -right; in NASM, such a shift is \e{always} unsigned, so that -the bits shifted in from the left-hand end are filled with zero -rather than a sign-extension of the previous highest bit. +\i\c{<<} gives a bit-shift to the left, just as it does in C. So +\c{5<<3} evaluates to 5 times 8, or 40. \i\c{>>} gives an \e{unsigned} +(logical) bit-shift to the right; the bits shifted in from the left +are set to zero. + +\i\c{<<<} gives a bit-shift to the left, exactly equivalent to the +\c{<<} operator; it is included for completeness. \i\c{>>>} gives an +\e{signed} (arithmetic) bit-shift to the right; the bits shifted in +from the left are filled with copies of the most significant (sign) +bit. \S{expplmi} \I{+ opaddition}\c{+} and \I{- opsubtraction}\c{-}: @@ -1760,22 +1885,26 @@ The \c{+} and \c{-} operators do perfectly ordinary addition and subtraction. -\S{expmul} \i\c{*}, \i\c{/}, \i\c{//}, \i\c{%} and \i\c{%%}: -\i{Multiplication} and \i{Division} +\S{expmul} \i{Multiplication}, \i{Division} and \i{Modulo} -\c{*} is the multiplication operator. \c{/} and \c{//} are both -division operators: \c{/} is \i{unsigned division} and \c{//} is -\i{signed division}. Similarly, \c{%} and \c{%%} provide \I{unsigned -modulo}\I{modulo operators}unsigned and -\i{signed modulo} operators respectively. +\i\c{*} is the multiplication operator. -NASM, like ANSI C, provides no guarantees about the sensible -operation of the signed modulo operator. +\i\c{/} and \i\c{//} are both division operators: \c{/} is \i{unsigned +division} and \c{//} is \i{signed division}. + +Similarly, \i\c{%} and \i\c{%%} provide \I{unsigned modulo}\I{modulo +operators} unsigned and \i{signed modulo} operators respectively. Since the \c{%} character is used extensively by the macro \i{preprocessor}, you should ensure that both the signed and unsigned modulo operators are followed by white space wherever they appear. +NASM, like ANSI C, provides no guarantees about the sensible +operation of the signed modulo operator. On most systems it will match +the signed division operator, such that: + +\c b * (a // b) + (a %% b) = a (b != 0) + \S{expmul} \i{Unary Operators} @@ -1803,7 +1932,7 @@ multiple \i{segments}, it is often necessary to be able to refer to the \I{segment address}segment part of the address of a symbol. NASM supports the \c{SEG} operator to perform this function. -The \c{SEG} operator returns the \i\e{preferred} segment base of a +The \c{SEG} operator evaluates to the \i\e{preferred} segment base of a symbol, defined as the segment base relative to which the offset of the symbol makes sense. So the code @@ -3085,20 +3214,6 @@ preprocessor loop: see \k{rep} for a detailed example. The expression given to \c{%if}, and its counterpart \i\c{%elif}, is a critical expression (see \k{crit}). -\c{%if} extends the normal NASM expression syntax, by providing a -set of \i{relational operators} which are not normally available in -expressions. The operators \i\c{=}, \i\c{<}, \i\c{>}, \i\c{<=}, -\i\c{>=} and \i\c{<>} test equality, less-than, greater-than, -less-or-equal, greater-or-equal and not-equal respectively. The -C-like forms \i\c{==} and \i\c{!=} are supported as alternative -forms of \c{=} and \c{<>}. In addition, low-priority logical -operators \i\c{&&}, \i\c{^^} and \i\c{||} are provided, supplying -\i{logical AND}, \i{logical XOR} and \i{logical OR}. These work like -the C logical operators (although C has no logical XOR), in that -they always return either 0 or 1, and treat any non-zero input as 1 -(so that \c{^^}, for example, returns 1 if exactly one of its inputs -is zero, and 0 otherwise). The relational operators also return 1 -for true and 0 for false. Like other \c{%if} constructs, \c{%if} has a counterpart \i\c{%elif}, and negative forms \i\c{%ifn} and \i\c{%elifn}. diff --git a/output/codeview.c b/output/codeview.c index 4dbc9b3a..be3fd27a 100644 --- a/output/codeview.c +++ b/output/codeview.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2017 The NASM Authors - All Rights Reserved + * Copyright 1996-2020 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -609,9 +609,9 @@ static void write_linenumber_table(struct coff_Section *const sect) } } -static uint16_t write_symbolinfo_obj(struct coff_Section *sect) +static uint32_t write_symbolinfo_obj(struct coff_Section *sect) { - uint16_t obj_len; + uint32_t obj_len; obj_len = 2 + 4 + cv8_state.outfile.namebytes; @@ -623,11 +623,11 @@ static uint16_t write_symbolinfo_obj(struct coff_Section *sect) return obj_len; } -static uint16_t write_symbolinfo_properties(struct coff_Section *sect, +static uint32_t write_symbolinfo_properties(struct coff_Section *sect, const char *const creator_str) { /* https://github.com/Microsoft/microsoft-pdb/blob/1d60e041/include/cvinfo.h#L3313 */ - uint16_t creator_len; + uint32_t creator_len; creator_len = 2 + 4 + 2 + 3*2 + 3*2 + strlen(creator_str)+1 + 2; @@ -671,9 +671,9 @@ static uint16_t write_symbolinfo_properties(struct coff_Section *sect, return creator_len; } -static uint16_t write_symbolinfo_symbols(struct coff_Section *sect) +static uint32_t write_symbolinfo_symbols(struct coff_Section *sect) { - uint16_t len = 0, field_len; + uint32_t len = 0, field_len; uint32_t field_base; struct cv8_symbol *sym; @@ -727,7 +727,7 @@ static uint16_t write_symbolinfo_symbols(struct coff_Section *sect) static void write_symbolinfo_table(struct coff_Section *const sect) { static const char creator_str[] = "The Netwide Assembler " NASM_VER; - uint16_t obj_length, creator_length, sym_length; + uint32_t obj_length, creator_length, sym_length; uint32_t field_length = 0, out_len; nasm_assert(cv8_state.outfile.namebytes); @@ -791,32 +791,28 @@ static void build_symbol_table(struct coff_Section *const sect) static void build_type_table(struct coff_Section *const sect) { - uint16_t field_len; - struct cv8_symbol *sym; + uint32_t field_len; + uint32_t typeindex = 0x1000; + uint32_t idx_arglist; section_write32(sect, 0x00000004); - saa_rewind(cv8_state.symbols); - while ((sym = saa_rstruct(cv8_state.symbols))) { - if (sym->type != SYMTYPE_PROC) - continue; - - /* proc leaf */ - - field_len = 2 + 4 + 4 + 4 + 2; - section_write16(sect, field_len); - section_write16(sect, 0x1008); /* PROC type */ - - section_write32(sect, 0x00000003); /* return type */ - section_write32(sect, 0); /* calling convention (default) */ - section_write32(sect, sym->typeindex); - section_write16(sect, 0); /* # params */ - - /* arglist */ - - field_len = 2 + 4; - section_write16(sect, field_len); - section_write16(sect, 0x1201); /* ARGLIST */ - section_write32(sect, 0); /*num params */ - } + /* empty argument list type */ + field_len = 2 + 4; + section_write16(sect, field_len); + section_write16(sect, 0x1201); /* ARGLIST */ + section_write32(sect, 0); /* num params */ + idx_arglist = typeindex++; + + /* procedure type: void proc(void) */ + field_len = 2 + 4 + 1 + 1 + 2 + 4; + section_write16(sect, field_len); + section_write16(sect, 0x1008); /* PROC type */ + + section_write32(sect, 0x00000003); /* return type VOID */ + section_write8(sect, 0); /* calling convention (default) */ + section_write8(sect, 0); /* function attributes */ + section_write16(sect, 0); /* # params */ + section_write32(sect, idx_arglist); /* argument list type */ + /* idx_voidfunc = typeindex++; */ } diff --git a/output/outelf.c b/output/outelf.c index 18b52d88..61af0208 100644 --- a/output/outelf.c +++ b/output/outelf.c @@ -176,7 +176,32 @@ static void stabs_generate(void); static void stabs_cleanup(void); /* dwarf debugging routines */ -static void dwarf_init(void); + +/* This should match the order in elf_write() */ +enum dwarf_sect { + DWARF_ARANGES, + DWARF_RELA_ARANGES, + DWARF_PUBNAMES, + DWARF_INFO, + DWARF_RELA_INFO, + DWARF_ABBREV, + DWARF_LINE, + DWARF_RELA_LINE, + DWARF_FRAME, + DWARF_LOC, + DWARF_NSECT +}; + +struct dwarf_format { + uint16_t dwarf_version; + uint16_t sect_version[DWARF_NSECT]; + /* ... add more here to generalize further */ +}; +const struct dwarf_format *dwfmt; + +static void dwarf32_init(void); +static void dwarfx32_init(void); +static void dwarf64_init(void); static void dwarf_linenum(const char *filename, int32_t linenumber, int32_t); static void dwarf_output(int, void *); static void dwarf_generate(void); @@ -2407,7 +2432,7 @@ static const struct pragma_facility elf_pragma_list[] = static const struct dfmt elf32_df_dwarf = { "ELF32 (i386) dwarf (newer)", "dwarf", - dwarf_init, + dwarf32_init, dwarf_linenum, null_debug_deflabel, null_debug_directive, @@ -2459,7 +2484,7 @@ const struct ofmt of_elf32 = { static const struct dfmt elf64_df_dwarf = { "ELF64 (x86-64) dwarf (newer)", "dwarf", - dwarf_init, + dwarf64_init, dwarf_linenum, null_debug_deflabel, null_debug_directive, @@ -2511,7 +2536,7 @@ const struct ofmt of_elf64 = { static const struct dfmt elfx32_df_dwarf = { "ELFx32 (x86-64) dwarf (newer)", "dwarf", - dwarf_init, + dwarfx32_init, dwarf_linenum, null_debug_deflabel, null_debug_directive, @@ -2939,11 +2964,69 @@ static void stabs_cleanup(void) /* dwarf routines */ -static void dwarf_init(void) +static void dwarf_init_common(const struct dwarf_format *fmt) { + dwfmt = fmt; ndebugs = 3; /* 3 debug symbols */ } +static void dwarf32_init(void) +{ + static const struct dwarf_format dwfmt32 = { + 2, /* DWARF 2 */ + /* section version numbers: */ + { 2, /* .debug_aranges */ + 0, /* .rela.debug_aranges */ + 2, /* .debug_pubnames */ + 2, /* .debug_info */ + 0, /* .rela.debug_info */ + 0, /* .debug_abbrev */ + 2, /* .debug_line */ + 0, /* .rela.debug_line */ + 1, /* .debug_frame */ + 0 } /* .debug_loc */ + }; + dwarf_init_common(&dwfmt32); +} + +static void dwarfx32_init(void) +{ + static const struct dwarf_format dwfmtx32 = { + 3, /* DWARF 3 */ + /* section version numbers: */ + { 2, /* .debug_aranges */ + 0, /* .rela.debug_aranges */ + 2, /* .debug_pubnames */ + 3, /* .debug_info */ + 0, /* .rela.debug_info */ + 0, /* .debug_abbrev */ + 3, /* .debug_line */ + 0, /* .rela.debug_line */ + 3, /* .debug_frame */ + 0 } /* .debug_loc */ + }; + dwarf_init_common(&dwfmtx32); +} + +static void dwarf64_init(void) +{ + static const struct dwarf_format dwfmt64 = { + 3, /* DWARF 3 */ + /* section version numbers: */ + { 2, /* .debug_aranges */ + 0, /* .rela.debug_aranges */ + 2, /* .debug_pubnames */ + 3, /* .debug_info */ + 0, /* .rela.debug_info */ + 0, /* .debug_abbrev */ + 3, /* .debug_line */ + 0, /* .rela.debug_line */ + 3, /* .debug_frame */ + 0 } /* .debug_loc */ + }; + dwarf_init_common(&dwfmt64); +} + static void dwarf_linenum(const char *filename, int32_t linenumber, int32_t segto) { @@ -3026,7 +3109,7 @@ static void dwarf_generate(void) /* and build aranges section */ paranges = saa_init(1L); parangesrel = saa_init(1L); - saa_write16(paranges,2); /* dwarf version */ + saa_write16(paranges, dwfmt->sect_version[DWARF_ARANGES]); saa_write32(parangesrel, paranges->datalen+4); saa_write32(parangesrel, (dwarf_infosym << 8) + R_386_32); /* reloc to info */ saa_write32(parangesrel, 0); @@ -3071,7 +3154,7 @@ static void dwarf_generate(void) /* and build aranges section */ paranges = saa_init(1L); parangesrel = saa_init(1L); - saa_write16(paranges,3); /* dwarf version */ + saa_write16(paranges, dwfmt->sect_version[DWARF_ARANGES]); saa_write32(parangesrel, paranges->datalen+4); saa_write32(parangesrel, (dwarf_infosym << 8) + R_X86_64_32); /* reloc to info */ saa_write32(parangesrel, 0); @@ -3117,7 +3200,7 @@ static void dwarf_generate(void) /* and build aranges section */ paranges = saa_init(1L); parangesrel = saa_init(1L); - saa_write16(paranges,3); /* dwarf version */ + saa_write16(paranges, dwfmt->sect_version[DWARF_ARANGES]); saa_write64(parangesrel, paranges->datalen+4); saa_write64(parangesrel, (dwarf_infosym << 32) + R_X86_64_32); /* reloc to info */ saa_write64(parangesrel, 0); @@ -3166,23 +3249,28 @@ static void dwarf_generate(void) saa_free(parangesrel); /* build pubnames section */ - ppubnames = saa_init(1L); - saa_write16(ppubnames,3); /* dwarf version */ - saa_write32(ppubnames,0); /* offset into info */ - saa_write32(ppubnames,0); /* space used in info */ - saa_write32(ppubnames,0); /* end of list */ - saalen = ppubnames->datalen; - pubnameslen = saalen + 4; - pubnamesbuf = pbuf = nasm_malloc(pubnameslen); - WRITELONG(pbuf,saalen); /* initial length */ - saa_rnbytes(ppubnames, pbuf, saalen); - saa_free(ppubnames); + if (0) { + ppubnames = saa_init(1L); + saa_write16(ppubnames,dwfmt->sect_version[DWARF_PUBNAMES]); + saa_write32(ppubnames,0); /* offset into info */ + saa_write32(ppubnames,0); /* space used in info */ + saa_write32(ppubnames,0); /* end of list */ + saalen = ppubnames->datalen; + pubnameslen = saalen + 4; + pubnamesbuf = pbuf = nasm_malloc(pubnameslen); + WRITELONG(pbuf,saalen); /* initial length */ + saa_rnbytes(ppubnames, pbuf, saalen); + saa_free(ppubnames); + } else { + /* Don't write a section without actual information */ + pubnameslen = 0; + } if (is_elf32()) { /* build info section */ pinfo = saa_init(1L); pinforel = saa_init(1L); - saa_write16(pinfo,2); /* dwarf version */ + saa_write16(pinfo, dwfmt->sect_version[DWARF_INFO]); saa_write32(pinforel, pinfo->datalen + 4); saa_write32(pinforel, (dwarf_abbrevsym << 8) + R_386_32); /* reloc to abbrev */ saa_write32(pinforel, 0); @@ -3221,7 +3309,7 @@ static void dwarf_generate(void) /* build info section */ pinfo = saa_init(1L); pinforel = saa_init(1L); - saa_write16(pinfo,3); /* dwarf version */ + saa_write16(pinfo, dwfmt->sect_version[DWARF_INFO]); saa_write32(pinforel, pinfo->datalen + 4); saa_write32(pinforel, (dwarf_abbrevsym << 8) + R_X86_64_32); /* reloc to abbrev */ saa_write32(pinforel, 0); @@ -3261,7 +3349,7 @@ static void dwarf_generate(void) /* build info section */ pinfo = saa_init(1L); pinforel = saa_init(1L); - saa_write16(pinfo,3); /* dwarf version */ + saa_write16(pinfo, dwfmt->sect_version[DWARF_INFO]); saa_write64(pinforel, pinfo->datalen + 4); saa_write64(pinforel, (dwarf_abbrevsym << 32) + R_X86_64_32); /* reloc to abbrev */ saa_write64(pinforel, 0); @@ -3376,7 +3464,7 @@ static void dwarf_generate(void) linelen = linepoff + totlen + 10; linebuf = pbuf = nasm_malloc(linelen); WRITELONG(pbuf,linelen-4); /* initial length */ - WRITESHORT(pbuf,3); /* dwarf version */ + WRITESHORT(pbuf,dwfmt->sect_version[DWARF_LINE]); WRITELONG(pbuf,linepoff); /* offset to line number program */ /* write line header */ saalen = linepoff; @@ -3438,24 +3526,31 @@ static void dwarf_generate(void) saa_rnbytes(plinesrel, pbuf, saalen); saa_free(plinesrel); - /* build frame section */ - framelen = 4; - framebuf = pbuf = nasm_malloc(framelen); - WRITELONG(pbuf,framelen-4); /* initial length */ + /* build .debug_frame section */ + if (0) { + framelen = 4; + framebuf = pbuf = nasm_malloc(framelen); + WRITELONG(pbuf,framelen-4); /* initial length */ + } else { + /* Leave .debug_frame empty if not used! */ + framelen = 0; + } - /* build loc section */ - loclen = 16; - locbuf = pbuf = nasm_malloc(loclen); - if (is_elf32()) { - WRITELONG(pbuf,0); /* null beginning offset */ - WRITELONG(pbuf,0); /* null ending offset */ - } else if (is_elfx32()) { - WRITELONG(pbuf,0); /* null beginning offset */ - WRITELONG(pbuf,0); /* null ending offset */ + /* build .debug_loc section */ + if (0) { + loclen = 16; + locbuf = pbuf = nasm_malloc(loclen); + if (is_elf32() || is_elfx32()) { + WRITELONG(pbuf,0); /* null beginning offset */ + WRITELONG(pbuf,0); /* null ending offset */ + } else { + nasm_assert(is_elf64()); + WRITEDLONG(pbuf,0); /* null beginning offset */ + WRITEDLONG(pbuf,0); /* null ending offset */ + } } else { - nasm_assert(is_elf64()); - WRITEDLONG(pbuf,0); /* null beginning offset */ - WRITEDLONG(pbuf,0); /* null ending offset */ + /* Leave .debug_frame empty if not used! */ + loclen = 0; } } diff --git a/test/Makefile b/test/Makefile index 5f0676b0..e09e1148 100644 --- a/test/Makefile +++ b/test/Makefile @@ -21,16 +21,19 @@ $(NASM): $(NASM) $(NASMOPT) -f srec -o $@ -MD $@.dep -l $@.lst $< %.o: %.asm $(NASMDEP) - $(NASM) $(NASMOPT) -f elf32 -o $@ -MD $@.dep -l $@.lst $< + $(NASM) $(NASMOPT) -f elf32 -gdwarf -o $@ -MD $@.dep -l $@.lst $< + +%.ox: %.asm $(NASMDEP) + $(NASM) $(NASMOPT) -f elfx32 -gdwarf -o $@ -MD $@.dep -l $@.lst $< %.o64: %.asm $(NASMDEP) - $(NASM) $(NASMOPT) -f elf64 -o $@ -MD $@.dep -l $@.lst $< + $(NASM) $(NASMOPT) -f elf64 -gdwarf -o $@ -MD $@.dep -l $@.lst $< %.aout: %.asm $(NASMDEP) $(NASM) $(NASMOPT) -f aout -o $@ -MD $@.dep -l $@.lst $< %.obj: %.asm $(NASMDEP) - $(NASM) $(NASMOPT) -f obj -o $@ -MD $@.dep -l $@.lst $< + $(NASM) $(NASMOPT) -f obj -gborland -F -o $@ -MD $@.dep -l $@.lst $< %.rdf: %.asm $(NASMDEP) $(NASM) $(NASMOPT) -f rdf -o $@ -MD $@.dep -l $@.lst $< @@ -42,19 +45,19 @@ $(NASM): $(NASM) $(NASMOPT) -f coff -o $@ -MD $@.dep -l $@.lst $< %.win32: %.asm $(NASMDEP) - $(NASM) $(NASMOPT) -f win32 -o $@ -MD $@.dep -l $@.lst $< + $(NASM) $(NASMOPT) -f win32 -gcv8 -o $@ -MD $@.dep -l $@.lst $< %.win64: %.asm $(NASMDEP) - $(NASM) $(NASMOPT) -f win64 -o $@ -MD $@.dep -l $@.lst $< + $(NASM) $(NASMOPT) -f win64 -gcv8 -o $@ -MD $@.dep -l $@.lst $< %.mo32: %.asm $(NASMDEP) - $(NASM) $(NASMOPT) -f macho32 -o $@ -MD $@.dep -l $@.lst $< + $(NASM) $(NASMOPT) -f macho32 -gdwarf -o $@ -MD $@.dep -l $@.lst $< %.mo64: %.asm $(NASMDEP) - $(NASM) $(NASMOPT) -f macho64 -o $@ -MD $@.dep -l $@.lst $< + $(NASM) $(NASMOPT) -f macho64 -gdwarf -o $@ -MD $@.dep -l $@.lst $< %.dbg: %.asm $(NASMDEP) - $(NASM) $(NASMOPT) -f dbg -o $@ -MD $@.dep -l $@.lst $< + $(NASM) $(NASMOPT) -f dbg -gdbg -o $@ -MD $@.dep -l $@.lst $< %.asm: %.pl $(PERL) $< > $@ diff --git a/test/a64.asm b/test/a64.asm new file mode 100644 index 00000000..9311624e --- /dev/null +++ b/test/a64.asm @@ -0,0 +1,22 @@ + bits 64 +start: + invlpga eax,ecx + invlpga rax,ecx + jecxz start + jrcxz start + loop start,ecx + loop start,rcx + loope start,ecx + loope start,rcx + loopz start,ecx + loopz start,rcx + loopne start,ecx + loopne start,rcx + loopnz start,ecx + loopnz start,rcx + clzero eax + clzero rax + movdir64b eax,[edi] + movdir64b rax,[rdi] + umonitor eax + umonitor rax diff --git a/test/dup.asm b/test/dup.asm index 2e939119..723da48b 100644 --- a/test/dup.asm +++ b/test/dup.asm @@ -12,10 +12,10 @@ db 6 dup (33, 34) db 6 dup (33, 34), 35 db 7 dup (99) - db 7 dup (?,?) + db 7 dup dword (?, word ?,?) dw byte (?,44) - dw 0xcc, 4 dup byte ('PQR'), ?, 0xabcd + dw 3 dup (0xcc, 4 dup byte ('PQR'), ?), 0xabcd dd 16 dup (0xaaaa, ?, 0xbbbbbb) dd 64 dup (?) diff --git a/x86/insns.dat b/x86/insns.dat index 61e9c007..a59c5306 100644 --- a/x86/insns.dat +++ b/x86/insns.dat @@ -678,7 +678,7 @@ IRETQ void [ o64 cf] X64 IRETW void [ o16 cf] 8086 JCXZ imm [i: a16 e3 rel8] 8086,NOLONG JECXZ imm [i: a32 e3 rel8] 386 -JRCXZ imm [i: a64 e3 rel8] X64 +JRCXZ imm [i: o64nw a64 e3 rel8] X64 JMP imm|short [i: eb rel8] 8086 JMP imm [i: jmp8 eb rel8] 8086,ND JMP imm [i: odf e9 rel] 8086,BND @@ -5844,13 +5844,13 @@ MOVDIRI mem32,reg32 [mr: np 0f 38 f9 /r] FUTURE,SD MOVDIRI mem64,reg64 [mr: o64 0f 38 f9 /r] FUTURE,X64,SQ MOVDIR64B reg16,mem512 [rm: a16 66 0f 38 f8 /r] FUTURE,NOLONG MOVDIR64B reg32,mem512 [rm: a32 66 0f 38 f8 /r] FUTURE -MOVDIR64B reg64,mem512 [rm: a64 66 0f 38 f8 /r] FUTURE,X64 +MOVDIR64B reg64,mem512 [rm: o64nw a64 66 0f 38 f8 /r] FUTURE,X64 PCONFIG void [ np 0f 01 c5] FUTURE TPAUSE reg32 [m: 66 0f ae /6] FUTURE TPAUSE reg32,reg_edx,reg_eax [m--: 66 0f ae /6] FUTURE,ND UMONITOR reg16 [m: a16 f3 0f ae /6] FUTURE,NOLONG UMONITOR reg32 [m: a32 f3 0f ae /6] FUTURE -UMONITOR reg64 [m: a64 f3 0f ae /6] FUTURE,X64 +UMONITOR reg64 [m: o64nw a64 f3 0f ae /6] FUTURE,X64 UMWAIT reg32 [m: f2 0f ae /6] FUTURE UMWAIT reg32,reg_edx,reg_eax [m--: f2 0f ae /6] FUTURE,ND WBNOINVD void [ f3 0f 09] FUTURE |