aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2020-06-27 15:36:59 -0700
committerH. Peter Anvin (Intel) <hpa@zytor.com>2020-06-27 15:36:59 -0700
commit513e19c8da06745525492b58795d8d8caa545049 (patch)
treeda6c947aa0aff1a4fd00ee538e14d64e827166f3
parentf53966af8b81d7ef11f46f084a4f91e9faa55914 (diff)
parenta825b33423d5046dfc4c0992c3ebfea5b8a531c4 (diff)
downloadnasm-513e19c8da06745525492b58795d8d8caa545049.tar.gz
nasm-513e19c8da06745525492b58795d8d8caa545049.tar.xz
nasm-513e19c8da06745525492b58795d8d8caa545049.zip
Merge tag 'nasm-2.15'
NASM 2.15 Resolved Conflicts: version
-rw-r--r--Makefile.in2
-rw-r--r--Mkfiles/msvc.mak2
-rw-r--r--Mkfiles/openwcom.mak2
-rw-r--r--asm/assemble.c1
-rw-r--r--asm/directiv.c2
-rw-r--r--asm/eval.c2
-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.c2
-rw-r--r--asm/parser.c2
-rw-r--r--doc/changes.src10
-rw-r--r--doc/nasmdoc.src201
-rw-r--r--output/codeview.c62
-rw-r--r--output/outelf.c173
-rw-r--r--test/Makefile19
-rw-r--r--test/a64.asm22
-rw-r--r--test/dup.asm4
-rw-r--r--x86/insns.dat6
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"
diff --git a/asm/eval.c b/asm/eval.c
index 0dd7e61a..cd3c526d 100644
--- a/asm/eval.c
+++ b/asm/eval.c
@@ -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 */
diff --git a/asm/nasm.c b/asm/nasm.c
index 333ba70c..7c64569f 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -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