Merge branch 'master' of ssh://repo.or.cz/nasm

This commit is contained in:
H. Peter Anvin 2018-11-28 09:56:15 -08:00
commit a0ed5b3ffa
470 changed files with 37742 additions and 1672 deletions

3
.gitignore vendored
View file

@ -4,6 +4,7 @@
*.dbg
*.dep
*.exe
*.com
*.lib
*.i
*.ith
@ -40,6 +41,7 @@ TAGS
/*.1
/Makefile
/asm/directbl.c
/asm/directbl.h
/asm/directiv.h
/asm/pptok.c
/asm/pptok.h
@ -101,3 +103,4 @@ TAGS
/x86/regs.c
/x86/regs.h
/x86/regvals.c
/patches/

10
.travis.yml Normal file
View file

@ -0,0 +1,10 @@
language: c
os:
- linux
env:
- TR_ARCH=local
script:
- ./autogen.sh
- ./configure
- make all
- python3 ./travis/nasm-t.py run

View file

@ -50,7 +50,7 @@ XMLTO = @XMLTO@
MAKENSIS = makensis
MKDIR = mkdir
MKDIR = mkdir -p
RM_F = rm -f
RM_RF = rm -rf
LN_S = @LN_S@
@ -67,7 +67,7 @@ ifeq ($(TRACE),1)
endif
.SUFFIXES:
.SUFFIXES: .c .i .s .$(O) .$(A) $(X) .1 .txt .xml
.SUFFIXES: $(X) .$(O) .$(A) .xml .1 .c .i .s .txt
.PHONY: all doc rdf install clean distclean cleaner spotless install_rdf test
.PHONY: install_doc everything install_everything strip perlreq dist tags TAGS
@ -277,6 +277,13 @@ asm/directbl.c: asm/directiv.dat nasmlib/perfhash.pl perllib/phash.ph
perlreq: $(PERLREQ)
# This rule is only used for RDOFF
.$(O)$(X):
$(CC) $(ALL_CFLAGS) -o $@ $< $(LDFLAGS) $(RDFLIB) $(NASMLIB) $(LIBS)
RDFLN = cd rdoff && ln -s
RDFLNPFX =
#-- Begin RDOFF Shared Rules --#
RDFLIBOBJ = rdoff/rdoff.$(O) rdoff/rdfload.$(O) rdoff/symtab.$(O) \
@ -291,31 +298,23 @@ RDF2BINLINKS = rdoff/rdf2com$(X) rdoff/rdf2ith$(X) \
RDFLIB = rdoff/librdoff.$(A)
RDFLIBS = $(RDFLIB) $(NASMLIB)
# This rule is only used for rdoff, to allow common rules
MAKERDF = $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $< $(RDFLIB) $(NASMLIB) $(LIBS)
rdoff/rdfdump$(X): rdoff/rdfdump.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff/ldrdf$(X): rdoff/ldrdf.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff/rdx$(X): rdoff/rdx.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff/rdflib$(X): rdoff/rdflib.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff/rdf2bin$(X): rdoff/rdf2bin.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff/rdf2com$(X): rdoff/rdf2bin$(X)
$(RM_F) rdoff/rdf2com$(X)
cd rdoff && $(LN_S) rdf2bin$(X) rdf2com$(X)
$(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2com$(X)
rdoff/rdf2ith$(X): rdoff/rdf2bin$(X)
$(RM_F) rdoff/rdf2ith$(X)
cd rdoff && $(LN_S) rdf2bin$(X) rdf2ith$(X)
$(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2ith$(X)
rdoff/rdf2ihx$(X): rdoff/rdf2bin$(X)
$(RM_F) rdoff/rdf2ihx$(X)
cd rdoff && $(LN_S) rdf2bin$(X) rdf2ihx$(X)
$(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2ihx$(X)
rdoff/rdf2srec$(X): rdoff/rdf2bin$(X)
$(RM_F) rdoff/rdf2srec$(X)
cd rdoff && $(LN_S) rdf2bin$(X) rdf2srec$(X)
$(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2srec$(X)
#-- End RDOFF Shared Rules --#
@ -345,10 +344,10 @@ nsis: nsis/nasm.nsi nsis/arch.nsh nsis/version.nsh
manpages: nasm.1 ndisasm.1
install: nasm$(X) ndisasm$(X)
$(MKDIR) -p $(DESTDIR)$(bindir)
$(MKDIR) $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) nasm$(X) $(DESTDIR)$(bindir)/nasm$(X)
$(INSTALL_PROGRAM) ndisasm$(X) $(DESTDIR)$(bindir)/ndisasm$(X)
$(MKDIR) -p $(DESTDIR)$(mandir)/man1
$(MKDIR) $(DESTDIR)$(mandir)/man1
$(INSTALL_DATA) $(srcdir)/nasm.1 $(DESTDIR)$(mandir)/man1/nasm.1
$(INSTALL_DATA) $(srcdir)/ndisasm.1 $(DESTDIR)$(mandir)/man1/ndisasm.1
@ -397,7 +396,7 @@ cscope:
cscope -b -f cscope.out
rdf_install install_rdf install_rdoff:
$(MKDIR) -p $(DESTDIR)$(bindir)
$(MKDIR) $(DESTDIR)$(bindir)
for f in $(RDFPROGS); do \
$(INSTALL_PROGRAM) "$$f" '$(DESTDIR)$(bindir)'/ ; \
done
@ -406,7 +405,7 @@ rdf_install install_rdf install_rdoff:
bn=`basename "$$f"` && $(RM_F) "$$bn" && \
$(LN_S) rdf2bin$(X) "$$bn" ; \
done
$(MKDIR) -p $(DESTDIR)$(mandir)/man1
$(MKDIR) $(DESTDIR)$(mandir)/man1
$(INSTALL_DATA) $(srcdir)/rdoff/*.1 $(DESTDIR)$(mandir)/man1/
doc:

View file

@ -46,7 +46,7 @@ RUNPERL = $(PERL) $(PERLFLAGS)
MAKENSIS = makensis
RM_F = del /f
RM_F = -del /f
LN_S = copy
# Binary suffixes
@ -54,15 +54,11 @@ O = obj
A = lib
X = .exe
.SUFFIXES:
.SUFFIXES: .c .i .s .$(O) .$(A) .exe .1 .man
.SUFFIXES: $(X) .$(A) .$(O) .c .i .s .1 .man
.c.obj:
$(CC) /c $(ALL_CFLAGS) /Fo$@ $<
# This rule is only used for rdoff
.obj.exe:
$(CC) $(ALL_CFLAGS) /Fe$@ $< $(LDFLAGS) $(RDFLIB) $(NASMLIB) $(LIBS)
#-- Begin File Lists --#
# Edit in Makefile.in, not here!
NASM = asm\nasm.$(O)
@ -252,6 +248,13 @@ asm\directbl.c: asm\directiv.dat nasmlib\perfhash.pl perllib\phash.ph
perlreq: $(PERLREQ)
# This rule is only used for RDOFF
.obj.exe:
$(CC) /Fe$@ $< $(LDFLAGS) $(RDFLIB) $(NASMLIB) $(LIBS)
RDFLN = copy
RDFLNPFX = rdoff^\
#-- Begin RDOFF Shared Rules --#
# Edit in Makefile.in, not here!
@ -267,31 +270,23 @@ RDF2BINLINKS = rdoff\rdf2com$(X) rdoff\rdf2ith$(X) \
RDFLIB = rdoff\librdoff.$(A)
RDFLIBS = $(RDFLIB) $(NASMLIB)
# This rule is only used for rdoff, to allow common rules
MAKERDF = $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $< $(RDFLIB) $(NASMLIB) $(LIBS)
rdoff\rdfdump$(X): rdoff\rdfdump.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff\ldrdf$(X): rdoff\ldrdf.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff\rdx$(X): rdoff\rdx.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff\rdflib$(X): rdoff\rdflib.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff\rdf2bin$(X): rdoff\rdf2bin.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff\rdf2com$(X): rdoff\rdf2bin$(X)
$(RM_F) rdoff\rdf2com$(X)
cd rdoff && $(LN_S) rdf2bin$(X) rdf2com$(X)
$(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2com$(X)
rdoff\rdf2ith$(X): rdoff\rdf2bin$(X)
$(RM_F) rdoff\rdf2ith$(X)
cd rdoff && $(LN_S) rdf2bin$(X) rdf2ith$(X)
$(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2ith$(X)
rdoff\rdf2ihx$(X): rdoff\rdf2bin$(X)
$(RM_F) rdoff\rdf2ihx$(X)
cd rdoff && $(LN_S) rdf2bin$(X) rdf2ihx$(X)
$(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2ihx$(X)
rdoff\rdf2srec$(X): rdoff\rdf2bin$(X)
$(RM_F) rdoff\rdf2srec$(X)
cd rdoff && $(LN_S) rdf2bin$(X) rdf2srec$(X)
$(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2srec$(X)
#-- End RDOFF Shared Rules --#
@ -384,21 +379,21 @@ dep: msvc.dep
# Include and/or generate msvc.dep as needed. This is too complex to
# use the include-command feature, but we can open-code it here.
!IF $(EXTERNAL_DEPENDENCIES) == 1
!IFDEF MKDEP
MKDEP=0
!IF $(EXTERNAL_DEPENDENCIES) == 1 && $(MKDEP) == 0
!IF EXISTS(msvc.dep)
!INCLUDE msvc.dep
!ENDIF
!ELSEIF [$(MAKE) /c MKDEP=1 /f Mkfiles\msvc.mak msvc.dep] == 0
!INCLUDE msvc.dep
!ELSE
!ERROR Unable to rebuild dependencies file msvc.dep
!ENDIF
!ENDIF
#-- Magic hints to mkdep.pl --#
# @object-ending: ".$(O)"
# @path-separator: "\"
# @exclude: "config/config.h"
# @exclude: "config\config.h"
# @external: "msvc.dep"
# @selfrule: "1"
#-- Everything below is generated by mkdep.pl - do not edit --#

23
README
View file

@ -1,23 +0,0 @@
NASM, the Netwide Assembler.
Many many developers all over the net respect NASM for what it is
- a widespread (thus netwide), portable (thus netwide!), very
flexible and mature assembler tool with support for many output
formats (thus netwide!!).
Now we have good news for you: NASM is licensed under the "simplified"
(2-clause) BSD license. 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
popular Open Source development site on the Internet.
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,
and the file AUTHORS for a list of contributors.
With best regards,
NASM crew.

19
README.md Normal file
View file

@ -0,0 +1,19 @@
NASM, the Netwide Assembler
===========================
[![master](https://travis-ci.org/netwide-assembler/nasm.svg?branch=master)](https://travis-ci.org/netwide-assembler/nasm)
Many many developers all over the net respect NASM for what it is:
a widespread (thus netwide), portable (thus netwide!), very flexible
and mature assembler tool with support for many output formats (thus netwide!!).
Now we have good news for you: NASM is licensed under the "simplified"
[(2-clause) BSD license](https://opensource.org/licenses/BSD-2-Clause).
This means its development is open to even wider society of programmers
wishing to improve their lovely assembler.
Visit our [nasm.us](https://www.nasm.us/) website for more details.
We are gradually moving services away from Sourceforge. For our remaining
Sourceforge services see [here](https://sourceforge.net/projects/nasm/).
With best regards, the NASM crew.

View file

@ -208,6 +208,8 @@ enum match_result {
MERR_ENCMISMATCH,
MERR_BADBND,
MERR_BADREPNE,
MERR_REGSETSIZE,
MERR_REGSET,
/*
* Matching success; the conditional ones first
*/
@ -262,8 +264,7 @@ static int has_prefix(insn * ins, enum prefix_pos pos, int prefix)
static void assert_no_prefix(insn * ins, enum prefix_pos pos)
{
if (ins->prefixes[pos])
nasm_error(ERR_NONFATAL, "invalid %s prefix",
prefix_name(ins->prefixes[pos]));
nasm_nonfatal("invalid %s prefix", prefix_name(ins->prefixes[pos]));
}
static const char *size_name(int size)
@ -292,8 +293,8 @@ static const char *size_name(int size)
static void warn_overflow(int size)
{
nasm_error(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
"%s data exceeds bounds", size_name(size));
nasm_warnf(ERR_PASS2 | ERR_WARN_NOV, "%s data exceeds bounds",
size_name(size));
}
static void warn_overflow_const(int64_t data, int size)
@ -401,11 +402,10 @@ static void out(struct out_data *data)
if (asize > amax) {
if (data->type == OUT_RELADDR || data->sign == OUT_SIGNED) {
nasm_error(ERR_NONFATAL,
"%u-bit signed relocation unsupported by output format %s",
(unsigned int)(asize << 3), ofmt->shortname);
nasm_nonfatal("%u-bit signed relocation unsupported by output format %s",
(unsigned int)(asize << 3), ofmt->shortname);
} else {
nasm_error(ERR_WARNING | ERR_WARN_ZEXTRELOC,
nasm_warnf(ERR_WARN_ZEXTRELOC,
"%u-bit %s relocation zero-extended from %u bits",
(unsigned int)(asize << 3),
data->type == OUT_SEGMENT ? "segment" : "unsigned",
@ -420,10 +420,8 @@ static void out(struct out_data *data)
ofmt->output(data);
} else {
/* Outputting to ABSOLUTE section - only reserve is permitted */
if (data->type != OUT_RESERVE) {
nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
" space");
}
if (data->type != OUT_RESERVE)
nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
/* No need to push to the backend */
}
@ -468,7 +466,7 @@ static inline void out_reserve(struct out_data *data, uint64_t size)
static void out_segment(struct out_data *data, const struct operand *opx)
{
if (opx->opflags & OPFLAG_RELATIVE)
nasm_error(ERR_NONFATAL, "segment references cannot be relative");
nasm_nonfatal("segment references cannot be relative");
data->type = OUT_SEGMENT;
data->sign = OUT_UNSIGNED;
@ -488,7 +486,7 @@ static void out_imm(struct out_data *data, const struct operand *opx,
* already called ofmt->segbase() for us. Sigh.
*/
if (size < 2)
nasm_error(ERR_NONFATAL, "segment reference must be 16 bits");
nasm_nonfatal("segment reference must be 16 bits");
data->type = OUT_SEGMENT;
} else {
@ -515,7 +513,7 @@ static void out_reladdr(struct out_data *data, const struct operand *opx,
int size)
{
if (opx->opflags & OPFLAG_RELATIVE)
nasm_error(ERR_NONFATAL, "invalid use of self-relative expression");
nasm_nonfatal("invalid use of self-relative expression");
data->type = OUT_RELADDR;
data->sign = OUT_SIGNED;
@ -537,9 +535,9 @@ static bool jmp_match(int32_t segment, int64_t offset, int bits,
if (((c & ~1) != 0370) || (ins->oprs[0].type & STRICT))
return false;
if (!optimizing)
if (!optimizing.level || (optimizing.flag & OPTIM_DISABLE_JMP_MATCH))
return false;
if (optimizing < 0 && c == 0371)
if (optimizing.level < 0 && c == 0371)
return false;
isize = calcsize(segment, offset, bits, ins, temp);
@ -557,8 +555,8 @@ static bool jmp_match(int32_t segment, int64_t offset, int bits,
if (is_byte && c == 0371 && ins->prefixes[PPS_REP] == P_BND) {
/* jmp short (opcode eb) cannot be used with bnd prefix. */
ins->prefixes[PPS_REP] = P_none;
nasm_error(ERR_WARNING | ERR_WARN_BND | ERR_PASS2 ,
"jmp short does not init bnd regs - bnd prefix dropped.");
nasm_warnf(ERR_WARN_BND | ERR_PASS2 ,
"jmp short does not init bnd regs - bnd prefix dropped.");
}
return is_byte;
@ -590,9 +588,7 @@ int64_t assemble(int32_t segment, int64_t start, int bits, insn *instruction)
list_for_each(e, instruction->eops) {
if (e->type == EOT_DB_NUMBER) {
if (wsize > 8) {
nasm_error(ERR_NONFATAL,
"integer supplied to a DT, DO, DY or DZ"
" instruction");
nasm_nonfatal("integer supplied to a DT,DO,DY or DZ");
} else {
data.insoffs = 0;
data.inslen = data.size = wsize;
@ -639,16 +635,16 @@ int64_t assemble(int32_t segment, int64_t start, int bits, insn *instruction)
fp = nasm_open_read(fname, NF_BINARY|NF_FORMAP);
if (!fp) {
nasm_error(ERR_NONFATAL, "`incbin': unable to open file `%s'",
fname);
nasm_nonfatal("`incbin': unable to open file `%s'",
fname);
goto done;
}
len = nasm_file_size(fp);
if (len == (off_t)-1) {
nasm_error(ERR_NONFATAL, "`incbin': unable to get length of file `%s'",
fname);
nasm_nonfatal("`incbin': unable to get length of file `%s'",
fname);
goto close_done;
}
@ -697,9 +693,8 @@ int64_t assemble(int32_t segment, int64_t start, int bits, insn *instruction)
off_t l = len;
if (fseeko(fp, base, SEEK_SET) < 0 || ferror(fp)) {
nasm_error(ERR_NONFATAL,
"`incbin': unable to seek on file `%s'",
fname);
nasm_nonfatal("`incbin': unable to seek on file `%s'",
fname);
goto end_incbin;
}
while (l > 0) {
@ -710,9 +705,8 @@ int64_t assemble(int32_t segment, int64_t start, int bits, insn *instruction)
* actually changes while we are reading
* it.
*/
nasm_error(ERR_NONFATAL,
"`incbin': unexpected EOF while"
" reading file `%s'", fname);
nasm_nonfatal("`incbin': unexpected EOF while"
" reading file `%s'", fname);
goto end_incbin;
}
out_rawdata(&data, buf, m);
@ -727,9 +721,8 @@ int64_t assemble(int32_t segment, int64_t start, int bits, insn *instruction)
lfmt->downlevel(LIST_TIMES);
}
if (ferror(fp)) {
nasm_error(ERR_NONFATAL,
"`incbin': error while"
" reading file `%s'", fname);
nasm_nonfatal("`incbin': error while"
" reading file `%s'", fname);
}
close_done:
if (buf)
@ -765,47 +758,48 @@ int64_t assemble(int32_t segment, int64_t start, int bits, insn *instruction)
/* No match */
switch (m) {
case MERR_OPSIZEMISSING:
nasm_error(ERR_NONFATAL, "operation size not specified");
nasm_nonfatal("operation size not specified");
break;
case MERR_OPSIZEMISMATCH:
nasm_error(ERR_NONFATAL, "mismatch in operand sizes");
nasm_nonfatal("mismatch in operand sizes");
break;
case MERR_BRNOTHERE:
nasm_error(ERR_NONFATAL,
"broadcast not permitted on this operand");
nasm_nonfatal("broadcast not permitted on this operand");
break;
case MERR_BRNUMMISMATCH:
nasm_error(ERR_NONFATAL,
"mismatch in the number of broadcasting elements");
nasm_nonfatal("mismatch in the number of broadcasting elements");
break;
case MERR_MASKNOTHERE:
nasm_error(ERR_NONFATAL,
"mask not permitted on this operand");
nasm_nonfatal("mask not permitted on this operand");
break;
case MERR_DECONOTHERE:
nasm_error(ERR_NONFATAL, "unsupported mode decorator for instruction");
nasm_nonfatal("unsupported mode decorator for instruction");
break;
case MERR_BADCPU:
nasm_error(ERR_NONFATAL, "no instruction for this cpu level");
nasm_nonfatal("no instruction for this cpu level");
break;
case MERR_BADMODE:
nasm_error(ERR_NONFATAL, "instruction not supported in %d-bit mode",
bits);
nasm_nonfatal("instruction not supported in %d-bit mode", bits);
break;
case MERR_ENCMISMATCH:
nasm_error(ERR_NONFATAL, "specific encoding scheme not available");
nasm_nonfatal("specific encoding scheme not available");
break;
case MERR_BADBND:
nasm_error(ERR_NONFATAL, "bnd prefix is not allowed");
nasm_nonfatal("bnd prefix is not allowed");
break;
case MERR_BADREPNE:
nasm_error(ERR_NONFATAL, "%s prefix is not allowed",
(has_prefix(instruction, PPS_REP, P_REPNE) ?
"repne" : "repnz"));
nasm_nonfatal("%s prefix is not allowed",
(has_prefix(instruction, PPS_REP, P_REPNE) ?
"repne" : "repnz"));
break;
case MERR_REGSETSIZE:
nasm_nonfatal("invalid register set size");
break;
case MERR_REGSET:
nasm_nonfatal("register set not valid for operand");
break;
default:
nasm_error(ERR_NONFATAL,
"invalid combination of opcode and operands");
nasm_nonfatal("invalid combination of opcode and operands");
break;
}
@ -856,8 +850,8 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, insn *instruction)
len = nasm_file_size_by_path(fname);
if (len == (off_t)-1) {
nasm_error(ERR_NONFATAL, "`incbin': unable to get length of file `%s'",
fname);
nasm_nonfatal("`incbin': unable to get length of file `%s'",
fname);
return 0;
}
@ -916,16 +910,16 @@ static void bad_hle_warn(const insn * ins, uint8_t hleok)
case w_lock:
if (ins->prefixes[PPS_LOCK] != P_LOCK) {
nasm_error(ERR_WARNING | ERR_WARN_HLE | ERR_PASS2,
"%s with this instruction requires lock",
prefix_name(rep_pfx));
nasm_warnf(ERR_WARN_HLE | ERR_PASS2,
"%s with this instruction requires lock",
prefix_name(rep_pfx));
}
break;
case w_inval:
nasm_error(ERR_WARNING | ERR_WARN_HLE | ERR_PASS2,
"%s invalid with this instruction",
prefix_name(rep_pfx));
nasm_warnf(ERR_WARN_HLE | ERR_PASS2,
"%s invalid with this instruction",
prefix_name(rep_pfx));
break;
}
}
@ -1122,7 +1116,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
if (pfx == P_O16)
break;
if (pfx != P_none)
nasm_error(ERR_WARNING | ERR_PASS2, "invalid operand size prefix");
nasm_warnf(ERR_PASS2, "invalid operand size prefix");
else
ins->prefixes[PPS_OSIZE] = P_O16;
break;
@ -1134,7 +1128,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
if (pfx == P_O32)
break;
if (pfx != P_none)
nasm_error(ERR_WARNING | ERR_PASS2, "invalid operand size prefix");
nasm_warnf(ERR_PASS2, "invalid operand size prefix");
else
ins->prefixes[PPS_OSIZE] = P_O32;
break;
@ -1189,11 +1183,11 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
case 0340:
if (!absolute_op(&ins->oprs[0]))
nasm_error(ERR_NONFATAL, "attempt to reserve non-constant"
" quantity of BSS space");
nasm_nonfatal("attempt to reserve non-constant"
" quantity of BSS space");
else if (ins->oprs[0].opflags & OPFLAG_FORWARD)
nasm_error(ERR_WARNING | ERR_PASS1,
"forward reference in RESx can have unpredictable results");
nasm_warnf(ERR_PASS1, "forward reference in RESx "
"can have unpredictable results");
else
length += ins->oprs[0].offset;
break;
@ -1307,7 +1301,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
if (process_ea(opy, &ea_data, bits,
rfield, rflags, ins, &errmsg) != eat) {
nasm_error(ERR_NONFATAL, "%s", errmsg);
nasm_nonfatal("%s", errmsg);
return -1;
} else {
ins->rex |= ea_data.rex;
@ -1327,7 +1321,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
if (ins->rex & REX_NH) {
if (ins->rex & REX_H) {
nasm_error(ERR_NONFATAL, "instruction cannot use high registers");
nasm_nonfatal("instruction cannot use high registers");
return -1;
}
ins->rex &= ~REX_P; /* Don't force REX prefix due to high reg */
@ -1351,7 +1345,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
int bad32 = REX_R|REX_W|REX_X|REX_B;
if (ins->rex & REX_H) {
nasm_error(ERR_NONFATAL, "cannot use high register in AVX instruction");
nasm_nonfatal("cannot use high register in AVX instruction");
return -1;
}
switch (ins->vex_wlp & 060) {
@ -1369,11 +1363,11 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
}
if (bits != 64 && ((ins->rex & bad32) || ins->vexreg > 7)) {
nasm_error(ERR_NONFATAL, "invalid operands in non-64-bit mode");
nasm_nonfatal("invalid operands in non-64-bit mode");
return -1;
} else if (!(ins->rex & REX_EV) &&
((ins->vexreg > 15) || (ins->evex_p[0] & 0xf0))) {
nasm_error(ERR_NONFATAL, "invalid high-16 register in non-AVX-512");
nasm_nonfatal("invalid high-16 register in non-AVX-512");
return -1;
}
if (ins->rex & REX_EV)
@ -1385,7 +1379,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
length += 2;
} else if (ins->rex & REX_MASK) {
if (ins->rex & REX_H) {
nasm_error(ERR_NONFATAL, "cannot use high register in rex instruction");
nasm_nonfatal("cannot use high register in rex instruction");
return -1;
} else if (bits == 64) {
length++;
@ -1397,15 +1391,14 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
lockcheck = false; /* Already errored, no need for warning */
length++;
} else {
nasm_error(ERR_NONFATAL, "invalid operands in non-64-bit mode");
nasm_nonfatal("invalid operands in non-64-bit mode");
return -1;
}
}
if (has_prefix(ins, PPS_LOCK, P_LOCK) && lockcheck &&
(!itemp_has(temp,IF_LOCK) || !is_class(MEMORY, ins->oprs[0].type))) {
nasm_error(ERR_WARNING | ERR_WARN_LOCK | ERR_PASS2 ,
"instruction is not lockable");
nasm_warnf(ERR_WARN_LOCK | ERR_PASS2 , "instruction is not lockable");
}
bad_hle_warn(ins, hleok);
@ -1467,24 +1460,21 @@ static int emit_prefix(struct out_data *data, const int bits, insn *ins)
c = 0xF3;
break;
case R_CS:
if (bits == 64) {
nasm_error(ERR_WARNING | ERR_PASS2,
"cs segment base generated, but will be ignored in 64-bit mode");
}
if (bits == 64)
nasm_warnf(ERR_PASS2, "cs segment base generated, "
"but will be ignored in 64-bit mode");
c = 0x2E;
break;
case R_DS:
if (bits == 64) {
nasm_error(ERR_WARNING | ERR_PASS2,
"ds segment base generated, but will be ignored in 64-bit mode");
}
if (bits == 64)
nasm_warnf(ERR_PASS2, "ds segment base generated, "
"but will be ignored in 64-bit mode");
c = 0x3E;
break;
case R_ES:
if (bits == 64) {
nasm_error(ERR_WARNING | ERR_PASS2,
"es segment base generated, but will be ignored in 64-bit mode");
}
if (bits == 64)
nasm_warnf(ERR_PASS2, "es segment base generated, "
"but will be ignored in 64-bit mode");
c = 0x26;
break;
case R_FS:
@ -1495,21 +1485,19 @@ static int emit_prefix(struct out_data *data, const int bits, insn *ins)
break;
case R_SS:
if (bits == 64) {
nasm_error(ERR_WARNING | ERR_PASS2,
"ss segment base generated, but will be ignored in 64-bit mode");
nasm_warnf(ERR_PASS2, "ss segment base generated, "
"but will be ignored in 64-bit mode");
}
c = 0x36;
break;
case R_SEGR6:
case R_SEGR7:
nasm_error(ERR_NONFATAL,
"segr6 and segr7 cannot be used as prefixes");
nasm_nonfatal("segr6 and segr7 cannot be used as prefixes");
break;
case P_A16:
if (bits == 64) {
nasm_error(ERR_NONFATAL,
"16-bit addressing is not supported "
"in 64-bit mode");
nasm_nonfatal("16-bit addressing is not supported "
"in 64-bit mode");
} else if (bits != 16)
c = 0x67;
break;
@ -1519,9 +1507,8 @@ static int emit_prefix(struct out_data *data, const int bits, insn *ins)
break;
case P_A64:
if (bits != 64) {
nasm_error(ERR_NONFATAL,
"64-bit addressing is only supported "
"in 64-bit mode");
nasm_nonfatal("64-bit addressing is only supported "
"in 64-bit mode");
}
break;
case P_ASP:
@ -1643,7 +1630,7 @@ static void gencode(struct out_data *data, insn *ins)
int64_t delta = opx->offset - data->offset
- (data->inslen - data->insoffs);
if (delta > 127 || delta < -128)
nasm_error(ERR_NONFATAL, "short jump is out of range");
nasm_nonfatal("short jump is out of range");
}
out_reladdr(data, opx, 1);
break;
@ -1671,8 +1658,7 @@ static void gencode(struct out_data *data, insn *ins)
case4(074):
if (opx->segment == NO_SEG)
nasm_error(ERR_NONFATAL, "value referenced by FAR is not"
" relocatable");
nasm_nonfatal("value referenced by FAR is not relocatable");
out_segment(data, opx);
break;
@ -1684,14 +1670,12 @@ static void gencode(struct out_data *data, insn *ins)
c = *codes++;
opx = &ins->oprs[c >> 3];
opy = &ins->oprs[c & 7];
if (!absolute_op(opy)) {
nasm_error(ERR_NONFATAL,
"non-absolute expression not permitted as argument %d",
c & 7);
} else if (opy->offset & ~mask) {
nasm_error(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
if (!absolute_op(opy))
nasm_nonfatal("non-absolute expression not permitted "
"as argument %d", c & 7);
else if (opy->offset & ~mask)
nasm_warnf(ERR_PASS2 | ERR_WARN_NOV,
"is4 argument exceeds bounds");
}
c = opy->offset & mask;
goto emit_is4;
}
@ -1712,8 +1696,8 @@ static void gencode(struct out_data *data, insn *ins)
case4(0254):
if (absolute_op(opx) &&
(int32_t)opx->offset != (int64_t)opx->offset) {
nasm_error(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
"signed dword immediate exceeds bounds");
nasm_warnf(ERR_PASS2 | ERR_WARN_NOV,
"signed dword immediate exceeds bounds");
}
out_imm(data, opx, 4, OUT_SIGNED);
break;
@ -1782,7 +1766,7 @@ static void gencode(struct out_data *data, insn *ins)
/* If this wasn't explicitly byte-sized, warn as though we
* had fallen through to the imm16/32/64 case.
*/
nasm_error(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
nasm_warnf(ERR_PASS2 | ERR_WARN_NOV,
"%s value exceeds bounds",
(opx->type & BITS8) ? "signed byte" :
s == 16 ? "word" :
@ -1940,7 +1924,7 @@ static void gencode(struct out_data *data, insn *ins)
if (process_ea(opy, &ea_data, bits,
rfield, rflags, ins, &errmsg) != eat)
nasm_error(ERR_NONFATAL, "%s", errmsg);
nasm_nonfatal("%s", errmsg);
p = bytes;
*p++ = ea_data.modrm;
@ -2156,8 +2140,7 @@ static uint8_t get_broadcast_num(opflags_t opflags, opflags_t brsize)
uint8_t brcast_num;
if (brsize > BITS64)
nasm_error(ERR_FATAL,
"size of broadcasting element is greater than 64 bits");
nasm_fatal("size of broadcasting element is greater than 64 bits");
/*
* The shift term is to take care of the extra BITS80 inserted
@ -2191,7 +2174,7 @@ static enum match_result matches(const struct itemplate *itemp,
/*
* Is it legal?
*/
if (!(optimizing > 0) && itemp_has(itemp, IF_OPT))
if (!(optimizing.level > 0) && itemp_has(itemp, IF_OPT))
return MERR_INVALOP;
/*
@ -2334,9 +2317,14 @@ static enum match_result matches(const struct itemplate *itemp,
if (~ideco & deco & (Z_MASK|STATICRND_MASK|SAE_MASK))
return MERR_DECONOTHERE;
if (itemp->opd[i] & ~type & ~SIZE_MASK) {
if (itemp->opd[i] & ~type & ~(SIZE_MASK|REGSET_MASK))
return MERR_INVALOP;
} else if (template_opsize) {
if (~itemp->opd[i] & type & REGSET_MASK)
return (itemp->opd[i] & REGSET_MASK)
? MERR_REGSETSIZE : MERR_REGSET;
if (template_opsize) {
if (template_opsize != insn_opsize) {
if (insn_opsize) {
return MERR_INVALOP;
@ -2502,8 +2490,7 @@ static enum ea_type process_ea(operand *input, ea *output, int bits,
if (bits == 64 && ((input->type & IP_REL) == IP_REL)) {
if (input->segment == NO_SEG ||
(input->opflags & OPFLAG_RELATIVE)) {
nasm_error(ERR_WARNING | ERR_PASS2,
"absolute address can not be RIP-relative");
nasm_warnf(ERR_PASS2, "absolute address can not be RIP-relative");
input->type &= ~IP_REL;
input->type |= MEMORY;
}
@ -2517,10 +2504,8 @@ static enum ea_type process_ea(operand *input, ea *output, int bits,
if (eaflags & EAF_BYTEOFFS ||
(eaflags & EAF_WORDOFFS &&
input->disp_size != (addrbits != 16 ? 32 : 16))) {
nasm_error(ERR_WARNING | ERR_PASS1,
"displacement size ignored on absolute address");
}
input->disp_size != (addrbits != 16 ? 32 : 16)))
nasm_warnf(ERR_PASS1, "displacement size ignored on absolute address");
if (bits == 64 && (~input->type & IP_REL)) {
output->sib_present = true;
@ -2976,7 +2961,7 @@ static void add_asp(insn *ins, int addrbits)
ins->addr_size = (addrbits == 32) ? 16 : 32;
} else {
/* Impossible... */
nasm_error(ERR_NONFATAL, "impossible combination of address sizes");
nasm_nonfatal("impossible combination of address sizes");
ins->addr_size = addrbits; /* Error recovery */
}

View file

@ -399,6 +399,7 @@ bool process_directives(char *directive)
"in pass two");
in_absolute = true;
location.segment = NO_SEG;
location.offset = absolute.offset;
break;
}

View file

@ -47,175 +47,207 @@
* the [warning] directive.
*/
const struct warning warnings[ERR_WARN_ALL+1] = {
{"other", "any warning not specifially mentioned below", true},
{"macro-params", "macro calls with wrong parameter count", true},
{"macro-selfref", "cyclic macro references", false},
{"macro-defaults", "macros with more default than optional parameters", true},
{"orphan-labels", "labels alone on lines without trailing `:'", true},
{"number-overflow", "numeric constant does not fit", true},
{"gnu-elf-extensions", "using 8- or 16-bit relocation in ELF32, a GNU extension", false},
{"float-overflow", "floating point overflow", true},
{"float-denorm", "floating point denormal", false},
{"float-underflow", "floating point underflow", false},
{"float-toolong", "too many digits in floating-point number", true},
{"user", "%warning directives", true},
{"lock", "lock prefix on unlockable instructions", true},
{"hle", "invalid hle prefixes", true},
{"bnd", "invalid bnd prefixes", true},
{"zext-reloc", "relocation zero-extended to match output format", true},
{"ptr", "non-NASM keyword used in other assemblers", true},
{"bad-pragma", "empty or malformed %pragma", false},
{"unknown-pragma", "unknown %pragma facility or directive", false},
{"not-my-pragma", "%pragma not applicable to this compilation", false},
{"unknown-warning", "unknown warning in -W/-w or warning directive", false},
{"negative-rep", "regative %rep count", true},
{ "other", "any warning not specifially mentioned below", true },
{ "macro-params", "macro calls with wrong parameter count", true },
{ "macro-selfref", "cyclic macro references", false },
{ "macro-defaults", "macros with more default than optional parameters", true },
{ "orphan-labels", "labels alone on lines without trailing `:'", true },
{ "number-overflow", "numeric constant does not fit", true },
{ "gnu-elf-extensions", "using 8- or 16-bit relocation in ELF32, a GNU extension", false },
{ "float-overflow", "floating point overflow", true },
{ "float-denorm", "floating point denormal", false },
{ "float-underflow", "floating point underflow", false },
{ "float-toolong", "too many digits in floating-point number", true },
{ "user", "%warning directives", true },
{ "lock", "lock prefix on unlockable instructions", true },
{ "hle", "invalid hle prefixes", true },
{ "bnd", "invalid bnd prefixes", true },
{ "zext-reloc", "relocation zero-extended to match output format", true },
{ "ptr", "non-NASM keyword used in other assemblers", true },
{ "bad-pragma", "empty or malformed %pragma", false },
{ "unknown-pragma", "unknown %pragma facility or directive", false },
{ "not-my-pragma", "%pragma not applicable to this compilation", false },
{ "unknown-warning", "unknown warning in -W/-w or warning directive", false },
{ "negative-rep", "regative %rep count", true },
{ "phase", "phase error during stabilization", false },
/* THIS ENTRY MUST COME LAST */
{"all", "all possible warnings", false}
/* THIS ENTRY MUST COME LAST */
{ "all", "all possible warnings", false }
};
uint8_t warning_state[ERR_WARN_ALL];/* Current state */
uint8_t warning_state_init[ERR_WARN_ALL]; /* Command-line state, for reset */
/* Current state and command-line state, for reset */
uint8_t warning_state[ERR_WARN_ALL];
uint8_t warning_state_init[ERR_WARN_ALL];
vefunc nasm_verror; /* Global error handling function */
/* Global error handling function */
vefunc nasm_verror;
void nasm_error(int severity, const char *fmt, ...)
{
va_list ap;
va_list ap;
va_start(ap, fmt);
nasm_verror(severity, fmt, ap);
va_end(ap);
va_start(ap, fmt);
nasm_verror(severity, fmt, ap);
va_end(ap);
}
#define nasm_error_generatorf(__sev, __flags, __fmt) \
va_list __ap; \
va_start(__ap, __fmt); \
nasm_verror(__sev | __flags, __fmt, __ap)
#define nasm_error_generator(__sev, __fmt) \
nasm_error_generatorf(__sev, 0, __fmt)
void nasm_debug(const char *fmt, ...)
{
nasm_error_generator(ERR_DEBUG, fmt);
}
void nasm_debugf(int flags, const char *fmt, ...)
{
nasm_error_generatorf(ERR_DEBUG, flags, fmt);
}
void nasm_warn(const char *fmt, ...)
{
nasm_error_generator(ERR_WARNING, fmt);
}
void nasm_warnf(int flags, const char *fmt, ...)
{
nasm_error_generatorf(ERR_WARNING, flags, fmt);
}
void nasm_nonfatal(const char *fmt, ...)
{
nasm_error_generator(ERR_NONFATAL, fmt);
}
void nasm_nonfatalf(int flags, const char *fmt, ...)
{
nasm_error_generatorf(ERR_NONFATAL, flags, fmt);
}
fatal_func nasm_fatal(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
nasm_verror(ERR_FATAL, fmt, ap);
abort(); /* We should never get here */
nasm_error_generator(ERR_FATAL, fmt);
abort();
}
fatal_func nasm_fatal_fl(int flags, const char *fmt, ...)
fatal_func nasm_fatalf(int flags, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
nasm_verror(flags | ERR_FATAL, fmt, ap);
abort(); /* We should never get here */
nasm_error_generatorf(ERR_FATAL, flags, fmt);
abort();
}
fatal_func nasm_panic(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
nasm_verror(ERR_PANIC, fmt, ap);
abort(); /* We should never get here */
nasm_error_generator(ERR_PANIC, fmt);
abort();
}
fatal_func nasm_panic_fl(int flags, const char *fmt, ...)
fatal_func nasm_panicf(int flags, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
nasm_verror(flags | ERR_PANIC, fmt, ap);
abort(); /* We should never get here */
nasm_error_generatorf(ERR_PANIC, flags, fmt);
abort();
}
fatal_func nasm_panic_from_macro(const char *file, int line)
{
nasm_panic("internal error at %s:%d\n", file, line);
nasm_panic("internal error at %s:%d\n", file, line);
}
fatal_func nasm_assert_failed(const char *file, int line, const char *msg)
{
nasm_panic("assertion %s failed at %s:%d", msg, file, line);
nasm_panic("assertion %s failed at %s:%d", msg, file, line);
}
#undef nasm_error_generator
#undef nasm_error_generatorf
/*
* This is called when processing a -w or -W option, or a warning directive.
* Returns true if if the action was successful.
*/
bool set_warning_status(const char *value)
{
enum warn_action { WID_OFF, WID_ON, WID_RESET };
enum warn_action action;
uint8_t mask;
int i;
bool ok = false;
enum warn_action { WID_OFF, WID_ON, WID_RESET };
enum warn_action action;
bool ok = false;
uint8_t mask;
int i;
value = nasm_skip_spaces(value);
switch (*value) {
case '-':
action = WID_OFF;
value++;
break;
case '+':
action = WID_ON;
value++;
break;
case '*':
action = WID_RESET;
value++;
break;
case 'N':
case 'n':
if (!nasm_strnicmp(value, "no-", 3)) {
action = WID_OFF;
value += 3;
break;
} else if (!nasm_stricmp(value, "none")) {
action = WID_OFF;
value = NULL;
break;
}
/* else fall through */
default:
action = WID_ON;
break;
}
value = nasm_skip_spaces(value);
switch (*value) {
case '-':
action = WID_OFF;
value++;
break;
case '+':
action = WID_ON;
value++;
break;
case '*':
action = WID_RESET;
value++;
break;
case 'N':
case 'n':
if (!nasm_strnicmp(value, "no-", 3)) {
action = WID_OFF;
value += 3;
break;
} else if (!nasm_stricmp(value, "none")) {
action = WID_OFF;
value = NULL;
break;
}
/* else fall through */
default:
action = WID_ON;
break;
}
mask = WARN_ST_ENABLED;
mask = WARN_ST_ENABLED;
if (value && !nasm_strnicmp(value, "error", 5)) {
switch (value[5]) {
case '=':
mask = WARN_ST_ERROR;
value += 6;
break;
case '\0':
mask = WARN_ST_ERROR;
value = NULL;
break;
default:
/* Just an accidental prefix? */
break;
}
}
if (value && !nasm_strnicmp(value, "error", 5)) {
switch (value[5]) {
case '=':
mask = WARN_ST_ERROR;
value += 6;
break;
case '\0':
mask = WARN_ST_ERROR;
value = NULL;
break;
default:
/* Just an accidental prefix? */
break;
}
}
if (value && !nasm_stricmp(value, "all"))
value = NULL;
if (value && !nasm_stricmp(value, "all"))
value = NULL;
/* This is inefficient, but it shouldn't matter... */
for (i = 0; i < ERR_WARN_ALL; i++) {
if (!value || !nasm_stricmp(value, warnings[i].name)) {
ok = true; /* At least one action taken */
switch (action) {
case WID_OFF:
warning_state[i] &= ~mask;
break;
case WID_ON:
warning_state[i] |= mask;
break;
case WID_RESET:
warning_state[i] &= ~mask;
warning_state[i] |= warning_state_init[i] & mask;
break;
}
}
}
/* This is inefficient, but it shouldn't matter... */
for (i = 0; i < ERR_WARN_ALL; i++) {
if (!value || !nasm_stricmp(value, warnings[i].name)) {
ok = true; /* At least one action taken */
switch (action) {
case WID_OFF:
warning_state[i] &= ~mask;
break;
case WID_ON:
warning_state[i] |= mask;
break;
case WID_RESET:
warning_state[i] &= ~mask;
warning_state[i] |= warning_state_init[i] & mask;
break;
}
}
}
return ok;
return ok;
}

View file

@ -592,7 +592,7 @@ static expr *expr5(int critical)
" scalar values");
return NULL;
}
if (j != '*' && !is_unknown(f) && reloc_value(f) == 0) {
if (j != '*' && !is_just_unknown(f) && reloc_value(f) == 0) {
nasm_error(ERR_NONFATAL, "division by zero");
return NULL;
}

View file

@ -182,7 +182,7 @@ static int32_t read_exponent(const char *string, int32_t max)
} else if (*string == '_') {
/* do nothing */
} else {
nasm_error(ERR_NONFATAL|ERR_PASS1,
nasm_error(ERR_NONFATAL,
"invalid character in floating-point constant %s: '%c'",
"exponent", *string);
return INT32_MAX;
@ -219,7 +219,7 @@ static bool ieee_flconvert(const char *string, fp_limb *mant,
if (!seendot) {
seendot = true;
} else {
nasm_error(ERR_NONFATAL|ERR_PASS1,
nasm_error(ERR_NONFATAL,
"too many periods in floating-point constant");
return false;
}
@ -234,7 +234,7 @@ static bool ieee_flconvert(const char *string, fp_limb *mant,
*p++ = *string - '0';
} else {
if (!warned) {
nasm_error(ERR_WARNING|ERR_WARN_FL_TOOLONG|ERR_PASS1,
nasm_error(ERR_WARNING|ERR_WARN_FL_TOOLONG|ERR_PASS2,
"floating-point constant significand contains "
"more than %i digits", MANT_DIGITS);
warned = true;
@ -247,7 +247,7 @@ static bool ieee_flconvert(const char *string, fp_limb *mant,
} else if (*string == '_') {
/* do nothing */
} else {
nasm_error(ERR_NONFATAL|ERR_PASS1,
nasm_error(ERR_NONFATAL|ERR_PASS2,
"invalid character in floating-point constant %s: '%c'",
"significand", *string);
return false;
@ -533,7 +533,7 @@ static bool ieee_flconvert_bin(const char *string, int bits,
if (!seendot)
seendot = true;
else {
nasm_error(ERR_NONFATAL|ERR_PASS1,
nasm_error(ERR_NONFATAL,
"too many periods in floating-point constant");
return false;
}
@ -556,7 +556,7 @@ static bool ieee_flconvert_bin(const char *string, int bits,
mp = &mult[MANT_LIMBS]; /* Guard slot */
ms += LIMB_BITS;
}
*mp |= v << ms;
*mp |= v << (ms % (sizeof(fp_limb) * CHAR_BIT));
ms -= bits;
if (!seendot)
@ -575,7 +575,7 @@ static bool ieee_flconvert_bin(const char *string, int bits,
} else if (c == '_') {
/* ignore */
} else {
nasm_error(ERR_NONFATAL|ERR_PASS1,
nasm_error(ERR_NONFATAL,
"floating-point constant: `%c' is invalid character", c);
return false;
}
@ -608,6 +608,8 @@ static void ieee_shr(fp_limb *mant, int i)
if (offs)
for (j = MANT_LIMBS-1; j >= offs; j--)
mant[j] = mant[j-offs];
} else if (MANT_LIMBS-1-offs < 0) {
j = MANT_LIMBS-1;
} else {
n = mant[MANT_LIMBS-1-offs] >> sr;
for (j = MANT_LIMBS-1; j > offs; j--) {
@ -673,7 +675,7 @@ static int to_packed_bcd(const char *str, const char *p,
int tv = -1;
if (fmt != &ieee_80) {
nasm_error(ERR_NONFATAL|ERR_PASS1,
nasm_error(ERR_NONFATAL,
"packed BCD requires an 80-bit format");
return 0;
}
@ -683,7 +685,7 @@ static int to_packed_bcd(const char *str, const char *p,
if (c >= '0' && c <= '9') {
if (tv < 0) {
if (n == 9) {
nasm_error(ERR_WARNING|ERR_PASS1,
nasm_error(ERR_WARNING|ERR_PASS2,
"packed BCD truncated to 18 digits");
}
tv = c-'0';
@ -696,7 +698,7 @@ static int to_packed_bcd(const char *str, const char *p,
} else if (c == '_') {
/* do nothing */
} else {
nasm_error(ERR_NONFATAL|ERR_PASS1,
nasm_error(ERR_NONFATAL,
"invalid character `%c' in packed BCD constant", c);
return 0;
}
@ -757,7 +759,7 @@ static int to_float(const char *str, int s, uint8_t *result,
type = FL_INFINITY;
break;
default:
nasm_error(ERR_NONFATAL|ERR_PASS1,
nasm_error(ERR_NONFATAL,
"internal error: unknown FP constant token `%s'\n", str);
type = FL_QNAN;
break;
@ -805,7 +807,7 @@ static int to_float(const char *str, int s, uint8_t *result,
type = FL_NORMAL;
} else if (exponent > 0) {
if (pass0 == 1)
nasm_error(ERR_WARNING|ERR_WARN_FL_OVERFLOW|ERR_PASS1,
nasm_error(ERR_WARNING|ERR_WARN_FL_OVERFLOW|ERR_PASS2,
"overflow in floating-point constant");
type = FL_INFINITY;
} else {
@ -840,11 +842,11 @@ static int to_float(const char *str, int s, uint8_t *result,
} else {
if (daz || is_zero(mant)) {
/* Flush denormals to zero */
nasm_error(ERR_WARNING|ERR_WARN_FL_UNDERFLOW|ERR_PASS1,
nasm_error(ERR_WARNING|ERR_WARN_FL_UNDERFLOW|ERR_PASS2,
"underflow in floating-point constant");
goto zero;
} else {
nasm_error(ERR_WARNING|ERR_WARN_FL_DENORM|ERR_PASS1,
nasm_error(ERR_WARNING|ERR_WARN_FL_DENORM|ERR_PASS2,
"denormal floating-point constant");
}
}
@ -860,7 +862,7 @@ static int to_float(const char *str, int s, uint8_t *result,
ieee_shr(mant, 1);
exponent++;
if (exponent >= (expmax << 1)-1) {
nasm_error(ERR_WARNING|ERR_WARN_FL_OVERFLOW|ERR_PASS1,
nasm_error(ERR_WARNING|ERR_WARN_FL_OVERFLOW|ERR_PASS2,
"overflow in floating-point constant");
type = FL_INFINITY;
goto overflow;

View file

@ -72,6 +72,21 @@ static bool ismagic(const char *l)
return l[0] == '.' && l[1] == '.' && l[2] != '@';
}
/*
* Return true if we should update the local label base
* as a result of this symbol. We must exclude local labels
* as well as any kind of special labels, including ..@ ones.
*/
static bool set_prevlabel(const char *l)
{
if (tasm_compatible_mode) {
if (l[0] == '@' && l[1] == '@')
return false;
}
return l[0] != '.';
}
#define LABEL_BLOCK 128 /* no. of labels/block */
#define LBLK_SIZE (LABEL_BLOCK * sizeof(union label))
@ -146,7 +161,7 @@ static void out_symdef(union label *lptr)
case LBL_EXTERN:
case LBL_COMMON:
if (lptr->defn.special)
ofmt->symdef(lptr->defn.label, 0, 0, 3, lptr->defn.special);
ofmt->symdef(lptr->defn.mangled, 0, 0, 3, lptr->defn.special);
break;
default:
break;
@ -160,6 +175,7 @@ static void out_symdef(union label *lptr)
/* Clean up this hack... */
switch(lptr->defn.type) {
case LBL_GLOBAL:
case LBL_EXTERN:
backend_type = 1;
backend_offset = lptr->defn.offset;
break;
@ -203,6 +219,8 @@ static union label *find_label(const char *label, bool create, bool *created)
char *label_str = NULL;
struct hash_insert ip;
nasm_assert(label != NULL);
if (islocal(label))
label = label_str = nasm_strcat(prevlabel, label);
@ -336,15 +354,23 @@ handle_herelabel(union label *lptr, int32_t *segment, int64_t *offset)
if (oldseg == location.segment && *offset == location.offset) {
/* This label is defined at this location */
int32_t newseg;
bool copyoffset = false;
nasm_assert(lptr->defn.mangled);
newseg = ofmt->herelabel(lptr->defn.mangled, lptr->defn.type,
oldseg, &lptr->defn.subsection);
oldseg, &lptr->defn.subsection, &copyoffset);
if (likely(newseg == oldseg))
return;
*segment = newseg;
*offset = switch_segment(newseg);
if (copyoffset) {
/* Maintain the offset from the old to the new segment */
switch_segment(newseg);
location.offset = *offset;
} else {
/* Keep a separate offset for the new segment */
*offset = switch_segment(newseg);
}
}
}
@ -383,7 +409,7 @@ static bool declare_label_lptr(union label *lptr,
type == LBL_EXTERN) {
if (!lptr->defn.special)
lptr->defn.special = perm_copy(special);
return true;
return false; /* Don't call define_label() after this! */
}
nasm_error(ERR_NONFATAL, "symbol `%s' declared both as %s and %s",
@ -394,10 +420,7 @@ static bool declare_label_lptr(union label *lptr,
bool declare_label(const char *label, enum label_type type, const char *special)
{
union label *lptr;
bool created;
lptr = find_label(label, true, &created);
union label *lptr = find_label(label, true, NULL);
return declare_label_lptr(lptr, type, special);
}
@ -419,13 +442,14 @@ void define_label(const char *label, int32_t segment,
*/
lptr = find_label(label, true, &created);
if (pass0 > 1) {
if (created)
nasm_error(ERR_WARNING, "label `%s' defined on pass two", label);
}
if (!segment)
if (segment) {
/* We are actually defining this label */
if (lptr->defn.type == LBL_EXTERN) /* auto-promote EXTERN to GLOBAL */
lptr->defn.type = LBL_GLOBAL;
} else {
/* It's a pseudo-segment (extern, common) */
segment = lptr->defn.segment ? lptr->defn.segment : seg_alloc();
}
if (lptr->defn.defined || lptr->defn.type == LBL_BACKEND) {
/* We have seen this on at least one previous pass */
@ -436,9 +460,8 @@ void define_label(const char *label, int32_t segment,
if (ismagic(label) && lptr->defn.type == LBL_LOCAL)
lptr->defn.type = LBL_SPECIAL;
if (!islocal(label) && normal) {
if (set_prevlabel(label) && normal)
prevlabel = lptr->defn.label;
}
if (lptr->defn.type == LBL_COMMON) {
size = offset;
@ -447,7 +470,8 @@ void define_label(const char *label, int32_t segment,
size = 0; /* This is a hack... */
}
changed = !lptr->defn.defined || lptr->defn.segment != segment ||
changed = created || !lptr->defn.defined ||
lptr->defn.segment != segment ||
lptr->defn.offset != offset || lptr->defn.size != size;
global_offset_changed += changed;
@ -456,9 +480,11 @@ void define_label(const char *label, int32_t segment,
* special case, LBL_SPECIAL symbols are allowed to be changed
* even during the last pass.
*/
if (changed && pass0 == 2 && lptr->defn.type != LBL_SPECIAL)
nasm_error(ERR_WARNING, "label `%s' changed during code generation",
lptr->defn.label);
if (changed && pass0 > 1 && lptr->defn.type != LBL_SPECIAL) {
nasm_error(ERR_WARNING, "label `%s' %s during code generation",
lptr->defn.label,
created ? "defined" : "changed");
}
lptr->defn.segment = segment;
lptr->defn.offset = offset;

View file

@ -75,7 +75,7 @@ struct forwrefinfo { /* info held on forward refs. */
};
static void parse_cmdline(int, char **, int);
static void assemble_file(const char *, StrList **);
static void assemble_file(const char *, struct strlist *);
static bool is_suppressed_warning(int severity);
static bool skip_this_pass(int severity);
static void nasm_verror_gnu(int severity, const char *fmt, va_list args);
@ -117,7 +117,8 @@ const struct dfmt *dfmt;
static FILE *error_file; /* Where to write error messages */
FILE *ofile = NULL;
int optimizing = MAX_OPTIMIZE; /* number of optimization passes to take */
struct optimization optimizing =
{ MAX_OPTIMIZE, OPTIM_ALL_ENABLED }; /* number of optimization passes to take */
static int cmd_sb = 16; /* by default */
iflag_t cpu;
@ -133,6 +134,7 @@ static struct SAA *forwrefs; /* keep track of forward references */
static const struct forwrefinfo *forwref;
static const struct preproc_ops *preproc;
static struct strlist *include_path;
#define OP_NORMAL (1u << 0)
#define OP_PREPROCESS (1u << 1)
@ -145,7 +147,7 @@ static bool depend_emit_phony = false;
static bool depend_missing_ok = false;
static const char *depend_target = NULL;
static const char *depend_file = NULL;
StrList *depend_list;
struct strlist *depend_list;
static bool want_usage;
static bool terminate_after_phase;
@ -257,7 +259,11 @@ static void nasm_fputs(const char *line, FILE * outfile)
puts(line);
}
static void define_macros_early(void)
/*
* Define system-defined macros that are not part of
* macros/standard.mac.
*/
static void define_macros(void)
{
const struct compile_time * const oct = &official_compile_time;
char temp[128];
@ -288,11 +294,6 @@ static void define_macros_early(void)
snprintf(temp, sizeof temp, "__POSIX_TIME__=%"PRId64, oct->posix);
preproc->pre_define(temp);
}
}
static void define_macros_late(void)
{
char temp[128];
/*
* In case if output format is defined by alias
@ -302,15 +303,48 @@ static void define_macros_late(void)
snprintf(temp, sizeof(temp), "__OUTPUT_FORMAT__=%s",
ofmt_alias ? ofmt_alias->shortname : ofmt->shortname);
preproc->pre_define(temp);
/*
* Output-format specific macros.
*/
if (ofmt->stdmac)
preproc->extra_stdmac(ofmt->stdmac);
/*
* Debug format, if any
*/
if (dfmt != &null_debug_form) {
snprintf(temp, sizeof(temp), "__DEBUG_FORMAT__=%s", dfmt->shortname);
preproc->pre_define(temp);
}
}
static void emit_dependencies(StrList *list)
/*
* Initialize the preprocessor, set up the include path, and define
* the system-included macros. This is called between passes 1 and 2
* of parsing the command options; ofmt and dfmt are defined at this
* point.
*
* Command-line specified preprocessor directives (-p, -d, -u,
* --pragma, --before) are processed after this function.
*/
static void preproc_init(struct strlist *ipath)
{
preproc->init();
define_macros();
preproc->include_path(ipath);
}
static void emit_dependencies(struct strlist *list)
{
FILE *deps;
int linepos, len;
StrList *l, *nl;
bool wmake = (quote_for_make == quote_for_wmake);
const char *wrapstr, *nulltarget;
struct strlist_entry *l;
if (!list)
return;
wrapstr = wmake ? " &\n " : " \\\n ";
nulltarget = wmake ? "\t%null\n" : "";
@ -327,7 +361,7 @@ static void emit_dependencies(StrList *list)
}
linepos = fprintf(deps, "%s :", depend_target);
list_for_each(l, list) {
list_for_each(l, list->head) {
char *file = quote_for_make(l->str);
len = strlen(file);
if (linepos + len > 62 && linepos > 1) {
@ -340,15 +374,16 @@ static void emit_dependencies(StrList *list)
}
fprintf(deps, "\n\n");
list_for_each_safe(l, nl, list) {
list_for_each(l, list->head) {
if (depend_emit_phony) {
char *file = quote_for_make(l->str);
fprintf(deps, "%s :\n%s\n", file, nulltarget);
nasm_free(file);
}
nasm_free(l);
}
strlist_free(list);
if (deps != stdout)
fclose(deps);
}
@ -408,13 +443,13 @@ static void timestamp(void)
int main(int argc, char **argv)
{
StrList **depend_ptr;
timestamp();
iflag_set_default_cpu(&cpu);
iflag_set_default_cpu(&cmd_cpu);
include_path = strlist_alloc();
pass0 = 0;
want_usage = terminate_after_phase = false;
nasm_set_verror(nasm_verror_gnu);
@ -424,6 +459,13 @@ int main(int argc, char **argv)
tolower_init();
src_init();
/*
* We must call init_labels() before the command line parsing,
* because we may be setting prefixes/suffixes from the command
* line.
*/
init_labels();
offsets = raa_init();
forwrefs = saa_init((int32_t)sizeof(struct forwrefinfo));
@ -437,12 +479,24 @@ int main(int argc, char **argv)
return 1;
}
/*
* Define some macros dependent on the runtime, but not
* on the command line (as those are scanned in cmdline pass 2.)
*/
preproc->init();
define_macros_early();
/* At this point we have ofmt and the name of the desired debug format */
if (!using_debug_info) {
/* No debug info, redirect to the null backend (empty stubs) */
dfmt = &null_debug_form;
} else if (!debug_format) {
/* Default debug format for this backend */
dfmt = ofmt->default_dfmt;
} else {
dfmt = dfmt_find(ofmt, debug_format);
if (!dfmt) {
nasm_fatalf(ERR_NOFILE | ERR_USAGE,
"unrecognized debug format `%s' for"
" output format `%s'",
debug_format, ofmt->shortname);
}
}
preproc_init(include_path);
parse_cmdline(argc, argv, 2);
if (terminate_after_phase) {
@ -454,33 +508,23 @@ int main(int argc, char **argv)
/* Save away the default state of warnings */
memcpy(warning_state_init, warning_state, sizeof warning_state);
if (!using_debug_info) {
/* No debug info, redirect to the null backend (empty stubs) */
dfmt = &null_debug_form;
} else if (!debug_format) {
/* Default debug format for this backend */
dfmt = ofmt->default_dfmt;
} else {
dfmt = dfmt_find(ofmt, debug_format);
if (!dfmt) {
nasm_fatal_fl(ERR_NOFILE | ERR_USAGE,
"unrecognized debug format `%s' for"
" output format `%s'",
debug_format, ofmt->shortname);
/*
* If no output file name provided and this
* is a preprocess mode, we're perfectly
* fine to output into stdout.
*/
if (!outname && !(operating_mode & OP_PREPROCESS)) {
outname = filename_set_extension(inname, ofmt->extension);
if (!strcmp(outname, inname)) {
outname = "nasm.out";
nasm_error(ERR_WARNING,
"default output file same as input `%s', using `%s' for output\n",
inname, outname);
}
}
if (ofmt->stdmac)
preproc->extra_stdmac(ofmt->stdmac);
/* no output file name? */
if (!outname)
outname = filename_set_extension(inname, ofmt->extension);
/* define some macros dependent of command-line */
define_macros_late();
depend_ptr = (depend_file || (operating_mode & OP_DEPEND)) ? &depend_list : NULL;
if (depend_file || (operating_mode & OP_DEPEND))
depend_list = strlist_alloc();
if (!depend_target)
depend_target = quote_for_make(outname);
@ -491,7 +535,7 @@ int main(int argc, char **argv)
if (depend_missing_ok)
preproc->include_path(NULL); /* "assume generated" */
preproc->reset(inname, 0, depend_ptr);
preproc->reset(inname, 0, depend_list);
ofile = NULL;
while ((line = preproc->getline()))
nasm_free(line);
@ -505,16 +549,16 @@ int main(int argc, char **argv)
if (outname) {
ofile = nasm_open_write(outname, NF_TEXT);
if (!ofile)
nasm_fatal_fl(ERR_NOFILE,
"unable to open output file `%s'",
outname);
nasm_fatalf(ERR_NOFILE,
"unable to open output file `%s'",
outname);
} else
ofile = NULL;
location.known = false;
/* pass = 1; */
preproc->reset(inname, 3, depend_ptr);
preproc->reset(inname, 3, depend_list);
/* Revert all warnings to the default state */
memcpy(warning_state, warning_state_init, sizeof warning_state);
@ -550,20 +594,13 @@ int main(int argc, char **argv)
if (operating_mode & OP_NORMAL) {
ofile = nasm_open_write(outname, (ofmt->flags & OFMT_TEXT) ? NF_TEXT : NF_BINARY);
if (!ofile)
nasm_fatal_fl(ERR_NOFILE,
nasm_fatalf(ERR_NOFILE,
"unable to open output file `%s'", outname);
/*
* We must call init_labels() before ofmt->init() since
* some object formats will want to define labels in their
* init routines. (eg OS/2 defines the FLAT group)
*/
init_labels();
ofmt->init();
dfmt->init();
assemble_file(inname, depend_ptr);
assemble_file(inname, depend_list);
if (!terminate_after_phase) {
ofmt->cleanup();
@ -595,6 +632,7 @@ int main(int argc, char **argv)
eval_cleanup();
stdscan_cleanup();
src_free();
strlist_free(include_path);
return terminate_after_phase;
}
@ -854,7 +892,7 @@ static bool process_arg(char *p, char *q, int pass)
if (pass == 1) {
ofmt = ofmt_find(param, &ofmt_alias);
if (!ofmt) {
nasm_fatal_fl(ERR_NOFILE | ERR_USAGE,
nasm_fatalf(ERR_NOFILE | ERR_USAGE,
"unrecognised output format `%s' - "
"use -hf for a list", param);
}
@ -862,12 +900,12 @@ static bool process_arg(char *p, char *q, int pass)
break;
case 'O': /* Optimization level */
if (pass == 2) {
if (pass == 1) {
int opt;
if (!*param) {
/* Naked -O == -Ox */
optimizing = MAX_OPTIMIZE;
optimizing.level = MAX_OPTIMIZE;
} else {
while (*param) {
switch (*param) {
@ -875,12 +913,12 @@ static bool process_arg(char *p, char *q, int pass)
case '5': case '6': case '7': case '8': case '9':
opt = strtoul(param, &param, 10);
/* -O0 -> optimizing == -1, 0.98 behaviour */
/* -O1 -> optimizing == 0, 0.98.09 behaviour */
/* -O0 -> optimizing.level == -1, 0.98 behaviour */
/* -O1 -> optimizing.level == 0, 0.98.09 behaviour */
if (opt < 2)
optimizing = opt - 1;
optimizing.level = opt - 1;
else
optimizing = opt;
optimizing.level = opt;
break;
case 'v':
@ -891,7 +929,7 @@ static bool process_arg(char *p, char *q, int pass)
case 'x':
param++;
optimizing = MAX_OPTIMIZE;
optimizing.level = MAX_OPTIMIZE;
break;
default:
@ -900,8 +938,8 @@ static bool process_arg(char *p, char *q, int pass)
break;
}
}
if (optimizing > MAX_OPTIMIZE)
optimizing = MAX_OPTIMIZE;
if (optimizing.level > MAX_OPTIMIZE)
optimizing.level = MAX_OPTIMIZE;
}
}
break;
@ -926,8 +964,8 @@ static bool process_arg(char *p, char *q, int pass)
case 'i': /* include search path */
case 'I':
if (pass == 2)
preproc->include_path(param);
if (pass == 1)
strlist_add(include_path, param);
break;
case 'l': /* listing file */
@ -941,7 +979,7 @@ static bool process_arg(char *p, char *q, int pass)
break;
case 'F': /* specify debug format */
if (pass == 2) {
if (pass == 1) {
using_debug_info = true;
debug_format = param;
}
@ -954,14 +992,14 @@ static bool process_arg(char *p, char *q, int pass)
else if (nasm_stricmp("gnu", param) == 0)
nasm_set_verror(nasm_verror_gnu);
else
nasm_fatal_fl(ERR_NOFILE | ERR_USAGE,
"unrecognized error reporting format `%s'",
param);
nasm_fatalf(ERR_NOFILE | ERR_USAGE,
"unrecognized error reporting format `%s'",
param);
}
break;
case 'g':
if (pass == 2) {
if (pass == 1) {
using_debug_info = true;
if (p[2])
debug_format = nasm_skip_spaces(p + 2);
@ -1155,7 +1193,7 @@ static bool process_arg(char *p, char *q, int pass)
preproc->pre_command(NULL, param);
break;
case OPT_LIMIT:
if (pass == 2)
if (pass == 1)
nasm_set_limit(p+olen, param);
break;
case OPT_KEEP_ALL:
@ -1353,26 +1391,26 @@ static void parse_cmdline(int argc, char **argv, int pass)
return;
if (!inname)
nasm_fatal_fl(ERR_NOFILE | ERR_USAGE, "no input file specified");
nasm_fatalf(ERR_NOFILE | ERR_USAGE, "no input file specified");
else if ((errname && !strcmp(inname, errname)) ||
(outname && !strcmp(inname, outname)) ||
(listname && !strcmp(inname, listname)) ||
(depend_file && !strcmp(inname, depend_file)))
nasm_fatal_fl(ERR_USAGE, "will not overwrite input file");
nasm_fatalf(ERR_USAGE, "will not overwrite input file");
if (errname) {
error_file = nasm_open_write(errname, NF_TEXT);
if (!error_file) {
error_file = stderr; /* Revert to default! */
nasm_fatal_fl(ERR_NOFILE | ERR_USAGE,
nasm_fatalf(ERR_NOFILE | ERR_USAGE,
"cannot open file `%s' for error messages",
errname);
}
}
}
static void assemble_file(const char *fname, StrList **depend_ptr)
static void assemble_file(const char *fname, struct strlist *depend_list)
{
char *line;
insn output_ins;
@ -1424,7 +1462,7 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
location.known = true;
ofmt->reset();
switch_segment(ofmt->section(NULL, pass2, &globalbits));
preproc->reset(fname, pass1, pass1 == 2 ? depend_ptr : NULL);
preproc->reset(fname, pass1, pass1 == 2 ? depend_list : NULL);
/* Revert all warnings to the default state */
memcpy(warning_state, warning_state_init, sizeof warning_state);
@ -1434,7 +1472,7 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
while ((line = preproc->getline())) {
if (++globallineno > nasm_limit[LIMIT_LINES])
nasm_fatal("overall line count exceeds the maximum %"PRId64"\n",
nasm_limit[LIMIT_LINES]);
nasm_limit[LIMIT_LINES]);
/*
* Here we parse our directives; this is not handled by the
@ -1446,7 +1484,7 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
/* Not a directive, or even something that starts with [ */
parse_line(pass1, line, &output_ins);
if (optimizing > 0) {
if (optimizing.level > 0) {
if (forwref != NULL && globallineno == forwref->lineno) {
output_ins.forw_ref = true;
do {
@ -1472,13 +1510,11 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
/* forw_ref */
if (output_ins.opcode == I_EQU) {
if (!output_ins.label)
nasm_error(ERR_NONFATAL,
"EQU not preceded by label");
if (output_ins.operands == 1 &&
(output_ins.oprs[0].type & IMMEDIATE) &&
output_ins.oprs[0].wrt == NO_SEG) {
if (!output_ins.label) {
nasm_error(ERR_NONFATAL, "EQU not preceded by label");
} else if (output_ins.operands == 1 &&
(output_ins.oprs[0].type & IMMEDIATE) &&
output_ins.oprs[0].wrt == NO_SEG) {
define_label(output_ins.label,
output_ins.oprs[0].segment,
output_ins.oprs[0].offset, false);
@ -1611,14 +1647,35 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
nasm_free(line);
} /* end while (line = preproc->getline... */
if (pass0 == 2 && global_offset_changed && !terminate_after_phase)
nasm_error(ERR_NONFATAL,
"phase error detected at end of assembly.");
if (global_offset_changed && !terminate_after_phase) {
switch (pass0) {
case 1:
nasm_error(ERR_WARNING|ERR_WARN_PHASE,
"phase error during stabilization pass, hoping for the best");
break;
case 2:
nasm_error(ERR_NONFATAL,
"phase error during code generation pass");
break;
default:
/* This is normal, we'll keep going... */
break;
}
}
if (pass1 == 1)
preproc->cleanup(1);
if ((passn > 1 && !global_offset_changed) || pass0 == 2) {
/*
* Always run at least two optimization passes (pass0 == 0);
* things like subsections will fail miserably without that.
* Once we commit to a stabilization pass (pass0 == 1), we can't
* go back, and if something goes bad, we can only hope
* that we don't end up with a phase error at the end.
*/
if ((passn > 1 && !global_offset_changed) || pass0 > 0) {
pass0++;
} else if (global_offset_changed &&
global_offset_changed < prev_offset_changed) {
@ -1679,7 +1736,9 @@ static void nasm_verror_gnu(int severity, const char *fmt, va_list ap)
if (!(severity & ERR_NOFILE)) {
src_get(&lineno, &currentfile);
if (!currentfile || (severity & ERR_TOPFILE)) {
currentfile = inname[0] ? inname : outname[0] ? outname : NULL;
currentfile = inname && inname[0] ?
inname : outname && outname[0] ?
outname : NULL;
lineno = 0;
}
}
@ -1941,14 +2000,16 @@ static void help(const char xopt)
" -w-foo disable warning foo (equiv. -Wno-foo)\n"
" -w[+-]error[=foo]\n"
" promote [specific] warnings to errors\n"
" -h show invocation summary and exit\n\n"
" -h show invocation summary and exit (also --help)\n\n"
" --pragma str pre-executes a specific %%pragma\n"
" --before str add line (usually a preprocessor statement) before the input\n"
" --prefix str prepend the given string to all the given string\n"
" to all extern, common and global symbols\n"
" --suffix str append the given string to all the given string\n"
" to all extern, common and global symbols\n"
" to all extern, common and global symbols (also --gprefix)\n"
" --postfix str append the given string to all the given string\n"
" to all extern, common and global symbols (also --gpostfix)\n"
" --lprefix str prepend the given string to all other symbols\n"
" --lpostfix str append the given string to all other symbols\n"
" --keep-all output files will not be removed even if an error happens\n"
" --limit-X val set execution limit X\n");
for (i = 0; i <= LIMIT_MAX; i++) {

View file

@ -486,7 +486,8 @@ restart_parse:
* Generally fix things. I think this is right as it is, but
* am still not certain.
*/
define_label(result->label, location.segment,
define_label(result->label,
in_absolute ? absolute.segment : location.segment,
location.offset, true);
}
}
@ -1027,7 +1028,7 @@ is_expression:
op->segment = NO_SEG; /* don't care again */
op->wrt = NO_SEG; /* still don't care */
if(optimizing >= 0 && !(op->type & STRICT)) {
if(optimizing.level >= 0 && !(op->type & STRICT)) {
/* Be optimistic */
op->type |=
UNITY | SBYTEWORD | SBYTEDWORD | UDWORD | SDWORD;
@ -1044,7 +1045,7 @@ is_expression:
if (is_simple(value)) {
if (n == 1)
op->type |= UNITY;
if (optimizing >= 0 && !(op->type & STRICT)) {
if (optimizing.level >= 0 && !(op->type & STRICT)) {
if ((uint32_t) (n + 128) <= 255)
op->type |= SBYTEDWORD;
if ((uint16_t) (n + 128) <= 255)
@ -1077,6 +1078,7 @@ is_expression:
}
} else { /* it's a register */
opflags_t rs;
uint64_t regset_size = 0;
if (value->type >= EXPR_SIMPLE || value->value != 1) {
nasm_error(ERR_NONFATAL, "invalid operand type");
@ -1084,13 +1086,32 @@ is_expression:
}
/*
* check that its only 1 register, not an expression...
* We do not allow any kind of expression, except for
* reg+value in which case it is a register set.
*/
for (i = 1; value[i].type; i++)
if (value[i].value) {
for (i = 1; value[i].type; i++) {
if (!value[i].value)
continue;
switch (value[i].type) {
case EXPR_SIMPLE:
if (!regset_size) {
regset_size = value[i].value + 1;
break;
}
/* fallthrough */
default:
nasm_error(ERR_NONFATAL, "invalid operand type");
goto fail;
}
}
if ((regset_size & (regset_size - 1)) ||
regset_size >= (UINT64_C(1) << REGSET_BITS)) {
nasm_error(ERR_NONFATAL | ERR_PASS2,
"invalid register set size");
regset_size = 0;
}
/* clear overrides, except TO which applies to FPU regs */
if (op->type & ~TO) {
@ -1099,12 +1120,31 @@ is_expression:
* is different from the register size
*/
rs = op->type & SIZE_MASK;
} else
} else {
rs = 0;
}
/*
* Make sure we're not out of nasm_reg_flags, still
* probably this should be fixed when we're defining
* the label.
*
* An easy trigger is
*
* e equ 0x80000000:0
* pshufw word e-0
*
*/
if (value->type < EXPR_REG_START ||
value->type > EXPR_REG_END) {
nasm_error(ERR_NONFATAL, "invalid operand type");
goto fail;
}
op->type &= TO;
op->type |= REGISTER;
op->type |= nasm_reg_flags[value->type];
op->type |= (regset_size >> 1) << REGSET_SHIFT;
op->decoflags |= brace_flags;
op->basereg = value->type;

View file

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2017 The NASM Authors - All Rights Reserved
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@ -49,7 +49,7 @@
#include "assemble.h"
#include "error.h"
static enum directive_result asm_pragma(const struct pragma *pragma);
static enum directive_result output_pragma(const struct pragma *pragma);
static enum directive_result limit_pragma(const struct pragma *pragma);
/*
@ -87,14 +87,14 @@ static enum directive_result limit_pragma(const struct pragma *pragma);
*/
static struct pragma_facility global_pragmas[] =
{
{ "asm", asm_pragma },
{ "asm", NULL },
{ "limit", limit_pragma },
{ "list", NULL },
{ "file", NULL },
{ "input", NULL },
/* None of these should actually happen... */
{ "preproc", NULL }, /* This shouldn't happen... */
/* None of these should actually happen due to special handling */
{ "preproc", NULL }, /* Handled in the preprocessor by necessity */
{ "output", NULL },
{ "debug", NULL },
{ "ignore", NULL },
@ -110,6 +110,7 @@ static struct pragma_facility global_pragmas[] =
*/
static bool search_pragma_list(const struct pragma_facility *list,
const char *default_name,
pragma_handler generic_handler,
struct pragma *pragma)
{
const struct pragma_facility *pf;
@ -137,6 +138,10 @@ found_it:
else
rv = DIRR_UNKNOWN;
/* Is there an additional, applicable generic handler? */
if (rv == DIRR_UNKNOWN && generic_handler)
rv = generic_handler(pragma);
switch (rv) {
case DIRR_UNKNOWN:
switch (pragma->opcode) {
@ -210,15 +215,16 @@ void process_pragma(char *str)
pragma.tail = nasm_trim_spaces(p);
/* Look for a global pragma namespace */
if (search_pragma_list(global_pragmas, NULL, &pragma))
if (search_pragma_list(global_pragmas, NULL, NULL, &pragma))
return;
/* Look to see if it is an output backend pragma */
if (search_pragma_list(ofmt->pragmas, ofmt->shortname, &pragma))
if (search_pragma_list(ofmt->pragmas, ofmt->shortname,
output_pragma, &pragma))
return;
/* Look to see if it is a debug format pragma */
if (search_pragma_list(dfmt->pragmas, dfmt->shortname, &pragma))
if (search_pragma_list(dfmt->pragmas, dfmt->shortname, NULL, &pragma))
return;
/*
@ -234,9 +240,10 @@ void process_pragma(char *str)
}
/*
* Pragmas for the assembler proper
* Generic pragmas that apply to all output backends; these are handled
* specially so they can be made selective based on the output format.
*/
static enum directive_result asm_pragma(const struct pragma *pragma)
static enum directive_result output_pragma(const struct pragma *pragma)
{
switch (pragma->opcode) {
case D_PREFIX:
@ -258,6 +265,9 @@ static enum directive_result asm_pragma(const struct pragma *pragma)
}
}
/*
* %pragma limit to set resource limits
*/
static enum directive_result limit_pragma(const struct pragma *pragma)
{
return nasm_set_limit(pragma->opname, pragma->tail);

View file

@ -63,17 +63,17 @@ static void nop_init(void)
/* Nothing to do */
}
static void nop_reset(const char *file, int pass, StrList **deplist)
static void nop_reset(const char *file, int pass, struct strlist *deplist)
{
src_set(0, file);
nop_lineinc = 1;
nop_fp = nasm_open_read(file, NF_TEXT);
if (!nop_fp)
nasm_fatal_fl(ERR_NOFILE, "unable to open input file `%s'", file);
nasm_fatalf(ERR_NOFILE, "unable to open input file `%s'", file);
(void)pass; /* placate compilers */
nasm_add_string_to_strlist(deplist, file);
strlist_add(deplist, file);
}
static char *nop_getline(void)
@ -170,9 +170,9 @@ static void nop_pre_command(const char *what, char *string)
(void)string;
}
static void nop_include_path(char *path)
static void nop_include_path(struct strlist *list)
{
(void)path;
(void)list;
}
static void nop_error_list_macros(int severity)

File diff suppressed because it is too large Load diff

View file

@ -55,12 +55,14 @@ int64_t readstrnum(char *str, int length, bool *warn)
for (i = 0; i < length; i++) {
if (charconst & UINT64_C(0xFF00000000000000))
*warn = true;
charconst &= ~UINT64_C(0xFF00000000000000);
charconst = (charconst << 8) + (uint8_t)*--str;
}
} else {
for (i = 0; i < length; i++) {
if (charconst & 0xFF000000UL)
if (charconst & UINT32_C(0xFF000000))
*warn = true;
charconst &= ~UINT32_C(0xFF000000);
charconst = (charconst << 8) + (uint8_t)*--str;
}
}

View file

@ -49,6 +49,15 @@
#include "regdis.h"
#include "disp8.h"
#define fetch_safe(_start, _ptr, _size, _need, _op) \
do { \
if (((_ptr) - (_start)) >= ((_size) - (_need))) \
_op; \
} while (0)
#define fetch_or_return(_start, _ptr, _size, _need) \
fetch_safe(_start, _ptr, _size, _need, return 0)
/*
* Flags that go into the `segment' field of `insn' structures
* during disassembly.
@ -1108,8 +1117,8 @@ static const char * const condition_name[16] = {
"s", "ns", "pe", "po", "l", "nl", "ng", "g"
};
int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
int64_t offset, int autosync, iflag_t *prefer)
int32_t disasm(uint8_t *data, int32_t data_size, char *output, int outbufsize, int segsize,
int64_t offset, int autosync, iflag_t *prefer)
{
const struct itemplate * const *p, * const *best_p;
const struct disasm_index *ix;
@ -1144,41 +1153,52 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
switch (*data) {
case 0xF2:
case 0xF3:
fetch_or_return(origdata, data, data_size, 1);
prefix.rep = *data++;
break;
case 0x9B:
fetch_or_return(origdata, data, data_size, 1);
prefix.wait = *data++;
break;
case 0xF0:
fetch_or_return(origdata, data, data_size, 1);
prefix.lock = *data++;
break;
case 0x2E:
fetch_or_return(origdata, data, data_size, 1);
segover = "cs", prefix.seg = *data++;
break;
case 0x36:
fetch_or_return(origdata, data, data_size, 1);
segover = "ss", prefix.seg = *data++;
break;
case 0x3E:
fetch_or_return(origdata, data, data_size, 1);
segover = "ds", prefix.seg = *data++;
break;
case 0x26:
fetch_or_return(origdata, data, data_size, 1);
segover = "es", prefix.seg = *data++;
break;
case 0x64:
fetch_or_return(origdata, data, data_size, 1);
segover = "fs", prefix.seg = *data++;
break;
case 0x65:
fetch_or_return(origdata, data, data_size, 1);
segover = "gs", prefix.seg = *data++;
break;
case 0x66:
fetch_or_return(origdata, data, data_size, 1);
prefix.osize = (segsize == 16) ? 32 : 16;
prefix.osp = *data++;
break;
case 0x67:
fetch_or_return(origdata, data, data_size, 1);
prefix.asize = (segsize == 32) ? 16 : 32;
prefix.asp = *data++;
break;
@ -1186,6 +1206,7 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
case 0xC4:
case 0xC5:
if (segsize == 64 || (data[1] & 0xc0) == 0xc0) {
fetch_or_return(origdata, data, data_size, 2);
prefix.vex[0] = *data++;
prefix.vex[1] = *data++;
@ -1193,6 +1214,7 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
prefix.vex_c = RV_VEX;
if (prefix.vex[0] == 0xc4) {
fetch_or_return(origdata, data, data_size, 1);
prefix.vex[2] = *data++;
prefix.rex |= (~prefix.vex[1] >> 5) & 7; /* REX_RXB */
prefix.rex |= (prefix.vex[2] >> (7-3)) & REX_W;
@ -1214,6 +1236,7 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
case 0x62:
{
if (segsize == 64 || ((data[1] & 0xc0) == 0xc0)) {
fetch_or_return(origdata, data, data_size, 4);
data++; /* 62h EVEX prefix */
prefix.evex[0] = *data++;
prefix.evex[1] = *data++;
@ -1237,6 +1260,7 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
case 0x8F:
if ((data[1] & 030) != 0 &&
(segsize == 64 || (data[1] & 0xc0) == 0xc0)) {
fetch_or_return(origdata, data, data_size, 3);
prefix.vex[0] = *data++;
prefix.vex[1] = *data++;
prefix.vex[2] = *data++;
@ -1272,6 +1296,7 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
case REX_P + 0xE:
case REX_P + 0xF:
if (segsize == 64) {
fetch_or_return(origdata, data, data_size, 1);
prefix.rex = *data++;
if (prefix.rex & REX_W)
prefix.osize = 64;
@ -1293,8 +1318,10 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
return 0; /* No instruction table at all... */
dp = data;
fetch_or_return(origdata, dp, data_size, 1);
ix += *dp++;
while (ix->n == -1) {
fetch_or_return(origdata, dp, data_size, 1);
ix = (const struct disasm_index *)ix->p + *dp++;
}
@ -1431,6 +1458,9 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
slen += snprintf(output + slen, outbufsize - slen, "to ");
slen += snprintf(output + slen, outbufsize - slen, "%s",
nasm_reg_names[reg-EXPR_REG_START]);
if (t & REGSET_MASK)
slen += snprintf(output + slen, outbufsize - slen, "+%d",
(int)((t & REGSET_MASK) >> (REGSET_SHIFT-1))-1);
if (is_evex && deco)
slen += append_evex_reg_deco(output + slen, outbufsize - slen,
deco, ins.evex_p);

View file

@ -42,8 +42,8 @@
#define INSN_MAX 32 /* one instruction can't be longer than this */
int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
int64_t offset, int autosync, iflag_t *prefer);
int32_t disasm(uint8_t *data, int32_t data_size, char *output, int outbufsize, int segsize,
int64_t offset, int autosync, iflag_t *prefer);
int32_t eatbyte(uint8_t *data, char *output, int outbufsize, int segsize);
#endif

View file

@ -316,9 +316,8 @@ int main(int argc, char **argv)
nextsync = next_sync(offset, &synclen);
}
while (p > q && (p - q >= INSN_MAX || lenread == 0)) {
lendis =
disasm((uint8_t *) q, outbuf, sizeof(outbuf), bits,
offset, autosync, &prefer);
lendis = disasm((uint8_t *)q, INSN_MAX, outbuf, sizeof(outbuf),
bits, offset, autosync, &prefer);
if (!lendis || lendis > (p - q)
|| ((nextsync || synclen) &&
(uint32_t)lendis > nextsync - offset))

View file

@ -7,7 +7,82 @@
The NASM 2 series supports x86-64, and is the production version of NASM
since 2007.
\S{cl-2.13.04} Version 2.13.04
\S{cl-2.14.01} Version 2.14.01
\b Create all system-defined macros defore processing command-line
given preprocessing directives (\c{-p}, \c{-d}, \c{-u}, \c{--pragma},
\c{--before}).
\b If debugging is enabled, define a \c{__DEBUG_FORMAT__} predefined
macro. See \k{dfmtm}.
\S{cl-2.14} Version 2.14
\b Changed \c{-I} option semantics by adding a trailing path separator
unconditionally.
\b Fixed null dereference in corrupted invalid single line macros.
\b Fixed division by zero which may happen if source code is malformed.
\b Fixed out of bound access in processing of malformed segment override.
\b Fixed out of bound access in certain \c{EQU} parsing.
\b Fixed buffer underflow in float parsing.
\b Added \c{SGX} (Intel Software Guard Extensions) instructions.
\b Added \c{+n} syntax for multiple contiguous registers.
\b Fixed \c{subsections_via_symbols} for \c{macho} object format.
\b Added the \c{--gprefix}, \c{--gpostfix}, \c{--lprefix}, and
\c{--lpostfix} command line options, to allow command line base symbol
renaming. See \k{opt-pfix}.
\b Allow label renaming to be specified by \c{%pragma} in addition to
from the command line. See \k{mangling}.
\b Supported generic \c{%pragma} namespaces, \c{output} and \c{debug}. See
\k{gen-namespace}.
\b Added the \c{--pragma} command line option to inject a \c{%pragma}
directive. See \k{opt-pragma}.
\b Added the \c{--before} command line option to accept preprocess
statement before input. See \k{opt-before}.
\b Added \c{AVX512} \c{VBMI2} (Additional Bit Manipulation), \c{VNNI} (Vector
Neural Network), \c{BITALG} (Bit Algorithm), and \c{GFNI} (Galois Field New
Instruction) instructions.
\b Added the \c{STATIC} directive for local symbols that should be
renamed using global-symbol rules. See \k{static}.
\b Allow a symbol to be defined as \c{EXTERN} and then later
overridden as \c{GLOBAL} or \c{COMMON}. Furthermore, a symbol declared
\c{EXTERN} and then defined will be treated as \c{GLOBAL}. See \k{extern}.
\b The \c{GLOBAL} directive no longer is required to precede the
definition of the symbol.
\b Support \c{private_extern} as \c{macho} specific extension to the
\c{GLOBAL} directive. See \k{macho-pext}.
\b Updated \c{UD0} encoding to match with the specification
\b Added the \c{--limit-X} command line option to set execution
limits. See \k{opt-limit}.
\b Updated the \c{Codeview} version number to be aligned with \c{MASM}.
\b Added the \c{--keep-all} command line option to preserve output
files. See \k{opt-keep-all}.
\b Added the \c{--include} command line option, an alias to \c{-P} (\k{opt-p}).
\b Added the \c{--help} command line option as an alias to \c{-h} (\k{syntax}).
\b Added \c{-W}, \c{-D}, and \c{-Q} suffix aliases for \c{RET}
instructions so the operand sizes of these instructions can be

View file

@ -368,6 +368,8 @@ To get further usage instructions from NASM, try typing
\c nasm -h
\c{--help} option is also the same.
As \c{-hf}, this will also list the available output file formats, and what they
are.
@ -626,16 +628,12 @@ library}, for example, by typing
(As usual, a space between \c{-i} and the path name is allowed, and
optional).
NASM, in the interests of complete source-code portability, does not
understand the file naming conventions of the OS it is running on;
the string you provide as an argument to the \c{-i} option will be
prepended exactly as written to the name of the include file.
Therefore the trailing backslash in the above example is necessary.
Under Unix, a trailing forward slash is similarly necessary.
(You can use this to your advantage, if you're really \i{perverse},
by noting that the option \c{-ifoo} will cause \c{%include "bar.i"}
to search for the file \c{foobar.i}...)
Prior NASM 2.14 a path provided in the option has been considered as
a verbatim copy and providing a path separator been up to a caller.
One could implicitly concatenate a search path together with a filename.
Still this was rather a trick than something useful. Now the trailing
path separator is made to always present, thus \c{-ifoo} will be
considered as the \c{-ifoo/} directory.
If you want to define a \e{standard} \i{include search path},
similar to \c{/usr/include} on Unix systems, you should place one or
@ -657,10 +655,13 @@ option. So running
is equivalent to running \c{nasm myfile.asm} and placing the
directive \c{%include "myinc.inc"} at the start of the file.
\c{--include} option is also accepted.
For consistency with the \c{-I}, \c{-D} and \c{-U} options, this
option can also be specified as \c{-P}.
\S{opt-d} The \i\c{-d}\I\c{-D} Option: \I{pre-defining macros}Pre-Define a Macro
\I\c{%define}Just as the \c{-p} option gives an alternative to placing
@ -917,13 +918,72 @@ is indicated by an asterisk. For example:
\c dwarf elf32 (i386) dwarf debug format for Linux
\S{opt-pfix} The \i\c{--prefix} and \i\c{--postfix} Options.
\S{opt-pfix} The \i\c{--(g|l)prefix}, \i\c{--(g|l)postfix} Options.
The \c{--prefix} and \c{--postfix} options prepend or append
(respectively) the given argument to all \c{global} or
\c{extern} variables. E.g. \c{--prefix _} will prepend the
underscore to all global and external variables, as C requires it in
some, but not all, system calling conventions.
The \c{--(g)prefix} options prepend the given argument
to all \c{extern}, \c{common}, \c{static}, and \c{global} symbols, and the
\c{--lprefix} option prepends to all other symbols. Similarly,
\c{--(g)postfix} and \c{--lpostfix} options append
the argument in the exactly same way as the \c{--xxprefix} options does.
Running this:
\c nasm -f macho --gprefix _
is equivalent to place the directive with \c{%pragma macho gprefix _}
at the start of the file (\k{mangling}). It will prepend the underscore
to all global and external variables, as C requires it in some, but not all,
system calling conventions.
\S{opt-pragma} The \i\c{--pragma} Option
NASM accepts an argument as \c{%pragma} option, which is like placing
a \c{%pragma} preprocess statement at the beginning of the source.
Running this:
\c nasm -f macho --pragma "macho gprefix _"
is equivalent to the example in \k{opt-pfix}.
\S{opt-before} The \i\c{--before} Option
A preprocess statement can be accepted with this option. The example
shown in \k{opt-pragma} is the same as running this:
\c nasm -f macho --before "%pragma macho gprefix _"
\S{opt-limit} The \i\c{--limit-X} Option
This option allows user to setup various maximum values for these:
\b\c{--limit-passes}: Number of maximum allowed passes. Default is
effectively unlimited.
\b\c{--limit-stalled-passes}: Maximum number of allowed unfinished
passes. Default is 1000.
\b\c{--limit-macro-levels}: Define maximum depth of macro expansion
(in preprocess). Default is 1000000.
\b\c{--limit-rep}: Maximum number of allowed preprocessor loop, defined
under \c{%rep}. Default is 1000000.
\b\c{--limit-eval}: This number sets the boundary condition of allowed
expression length. Default is 1000000.
\b\c{--limit-lines}: Total number of source lines as allowed to be
processed. Default is 2000000000.
In example, running this limits the maximum line count to be 1000.
\c nasm --limit-lines 1000
\S{opt-keep-all} The \i\c{--keep-all} Option
This option doesn't delete any output files even if an error happens.
\S{nasmenv} The \i\c{NASMENV} \i{Environment} Variable
@ -3838,9 +3898,9 @@ mode-dependent macros.
\S{ofmtm} \i\c{__OUTPUT_FORMAT__}: Current Output Format
The \c{__OUTPUT_FORMAT__} standard macro holds the current Output Format,
as given by the \c{-f} option or NASM's default. Type \c{nasm -hf} for a
list.
The \c{__OUTPUT_FORMAT__} standard macro holds the current output
format name, as given by the \c{-f} option or NASM's default. Type
\c{nasm -hf} for a list.
\c %ifidn __OUTPUT_FORMAT__, win32
\c %define NEWLINE 13, 10
@ -3848,6 +3908,15 @@ list.
\c %define NEWLINE 10
\c %endif
\S{dfmtm} \i\c{__DEBUG_FORMAT__}: Current Debug Format
If debugging information generation is enabled, The
\c{__DEBUG_FORMAT__} standard macro holds the current debug format
name as specified by the \c{-F} or \c{-g} option or the output format
default. Type \c{nasm -f} \e{output} \c{y} for a list.
\c{__DEBUG_FORMAT__} is not defined if debugging is not enabled, or if
the debug format specified is \c{null}.
\S{datetime} Assembly Date and Time Macros
@ -4540,8 +4609,12 @@ only in that it can take only one argument at a time: the support
for multiple arguments is implemented at the preprocessor level.
You can declare the same variable as \c{EXTERN} more than once: NASM
will quietly ignore the second and later redeclarations. You can't
declare a variable as \c{EXTERN} as well as something else, though.
will quietly ignore the second and later redeclarations.
If a variable is declared both \c{GLOBAL} and \c{EXTERN}, or if it is
declared as \c{EXTERN} and then defined, it will be treated as
\c{GLOBAL}. If a variable is declared both as \c{COMMON} and
\c{EXTERN}, it will be treated as \c{COMMON}.
\H{global} \i\c{GLOBAL}: \i{Exporting Symbols} to Other Modules
@ -4552,9 +4625,6 @@ linker errors, some other module must actually \e{define} the
symbol and declare it as \c{GLOBAL}. Some assemblers use the name
\i\c{PUBLIC} for this purpose.
The \c{GLOBAL} directive applying to a symbol must appear \e{before}
the definition of the symbol.
\c{GLOBAL} uses the same syntax as \c{EXTERN}, except that it must
refer to symbols which \e{are} defined in the same module as the
\c{GLOBAL} directive. For example:
@ -4607,6 +4677,73 @@ Once again, like \c{EXTERN} and \c{GLOBAL}, the primitive form of
\c{COMMON} differs from the user-level form only in that it can take
only one argument at a time.
\H{static} \i\c{STATIC}: Local Symbols within Modules
Opposite to \c{EXTERN} and \c{GLOBAL}, \c{STATIC} is local symbol, but
should be named according to the global mangling rules (named by
analogy with the C keyword \c{static} as applied to functions or
global variables).
\c static foo
\c foo:
\c ; codes
Unlike \c{GLOBAL}, \c{STATIC} does not allow object formats to accept
private extensions mentioned in \k{global}.
\H{mangling} \i\c{(G|L)PREFIX}, \i\c{(G|L)POSTFIX}: Mangling Symbols
\c{PREFIX}, \c{GPREFIX}, \c{LPREFIX}, \c{POSTFIX}, \c{GPOSTFIX}, and
\c{LPOSTFIX} directives can prepend or append the given argument to
a certain type of symbols. The directive should be as a preprocess
statement. Each usage is:
\b\c{PREFIX}|\c{GPREFIX}: Prepend the argument to all \c{EXTERN}
\c{COMMON}, \c{STATIC}, and \c{GLOBAL} symbols
\b\c{LPREFIX}: Prepend the argument to all other symbols
such as Local Labels, and backend defined symbols
\b\c{POSTFIX}|\c{GPOSTFIX}: Append the argument to all \c{EXTERN}
\c{COMMON}, \c{STATIC}, and \c{GLOBAL} symbols
\b\c{LPOSTFIX}: Append the argument to all other symbols
such as Local Labels, and backend defined symbols
This is a macro implemented as a \c{%pragma}:
\c %pragma macho lprefix L_
Commandline option is also possible. See also \k{opt-pfix}.
Some toolchains is aware of a particular prefix for its own optimization
options, such as code elimination. For instance, Mach-O backend has a
linker that uses a simplistic naming scheme to chunk up sections into a
meta section. When the \c{subsections_via_symbols} directive
(\k{macho-ssvs}) is declared, each symbol is the start of a
separate block. The meta section is, then, defined to include sections
before the one that starts with a 'L'. \c{LPREFIX} is useful here to mark
all local symbols with the 'L' prefix to be excluded to the meta section.
It converts local symbols compatible with the particular toolchain.
Note that local symbols declared with \c{STATIC} (\k{static})
are excluded from the symbol mangling and also not marked as global.
\H{gen-namespace} \i\c{OUTPUT}, \i\c{DEBUG}: Generic Namespaces
\c{OUTPUT} and \c{DEBUG} are generic \c{%pragma} namespaces that are
supposed to redirect to the current output and debug formats.
For example, when mangling local symbols via the generic namespace:
\c %pragma output gprefix _
This is useful when the directive is needed to be output format
agnostic.
The example is also euquivalent to this, when the output format is \c{elf}:
\c %pragma elf gprefix _
\H{CPU} \i\c{CPU}: Defining CPU Dependencies
@ -5658,7 +5795,7 @@ comma. The following flags can also be specified:
\b \c{data} - this section contains initialized data items
\b \c{text} - this section contains code exclusively
\b \c{code} - this section contains code exclusively
\b \c{mixed} - this section contains both code and data
@ -5707,9 +5844,9 @@ right-hand side of the \c{WRT} operator:
\S{macho-ssvs} \c{macho} specfic directive \i\c{subsections_via_symbols}
The directive \c{subsections_via_symbols} sets the
\c{MH_SUBSECTIONS_VIA_SYMBOLS} flag in the Mach-O header, which tells
the linker that the symbols in the file matches the conventions
required to allow for link-time dead code elimination.
\c{MH_SUBSECTIONS_VIA_SYMBOLS} flag in the Mach-O header, that effectively
separates a block (or a subsection) based on a symbol. It is often used
for eliminating dead codes by a linker.
This directive takes no arguments.
@ -5731,6 +5868,19 @@ non-Mach-O builds of the same source code:
\c %pragma macho no_dead_strip symbol...
\S{macho-pext} \c{macho} specific extensions to the \c{GLOBAL}
Directive: \i\c{private_extern}
The directive extension to \c{GLOBAL} marks the symbol with limited
global scope. For example, you can specify the global symbol with
this extension:
\c global foo:private_extern
\c foo:
\c ; codes
Using with static linker will clear the private extern attribute.
But linker option like \c{-keep_private_externs} can avoid it.
\H{elffmt} \i\c{elf32}, \i\c{elf64}, \i\c{elfx32}: \I{ELF}\I{linux, elf}\i{Executable and Linkable
Format} Object Files

View file

@ -6,7 +6,8 @@
GLOBAL variables:
optimizing -1 flags nasm 0.98 compatible operation;
optimizing optimization meta data (with level and flag info)
.level -1 flags nasm 0.98 compatible operation;
offsets usually are explicit (short/near)
no optimization passes
0 flags non-optimized assembly; forward
@ -17,7 +18,8 @@ GLOBAL variables:
the actual recommended minimum setting
optimization passes (2 or more, plus
passes 1 and 2 will be required)
.flag 0 allow all optimizations
1 disallow jump match optimization
pass0 0 flags an optimizer pass (multiple passes)
1 flags pass1 (define labels)

View file

@ -23,6 +23,9 @@ while ($ARGV[0] =~ /^-(.*)$/) {
}
}
# Ghostscript executable name. "gs" on Unix-based systems.
my $gs = 'gs';
my ($in, $out) = @ARGV;
if (!defined($out)) {
@ -70,6 +73,17 @@ sub win32_gs_help() {
$ENV{'PATH'} .= ';' . $gs[0]->{'/GS_LIB'};
$ENV{'GS_FONTPATH'} .= (defined($ENV{'GS_FONTPATH'}) ? ';' : '')
. $ENV{'windir'}.'\\fonts';
my $gsp = undef;
foreach my $p (split(/\;/, $gs[0]->{'/GS_LIB'})) {
foreach my $exe ('gswin64c.exe', 'gswin32c.exe', 'gs.exe') {
last if (defined($gsp));
my $e = File::Spec->catpath($p, $exe);
$gsp = $e if (-f $e && -x _);
}
}
$gs = $gsp if (defined($gsp));
}
# Remove output file
@ -80,13 +94,19 @@ my $r = system('acrodist', '-n', '-q', '--nosecurity', '-o', $out, $in);
exit 0 if ( !$r && -f $out );
# 2. ps2pdf (from Ghostscript)
# The -I clause helps Ghostscript pick up the Fontdir file written by findfont.ph
# GhostScript uses # rather than - to separate options and values on Windows, it seems...
#
# GhostScript uses # rather than = to separate options and values on Windows,
# it seems. Call gs directly rather than ps2pdf, because -dSAFER
# breaks font discovery on some systems, apparently.
win32_gs_help();
my $o = $win32_ok ? '#' : '-';
my $r = system('ps2pdf', "-dOptimize${o}true", "-dEmbedAllFonts${o}true",
my $o = $win32_ok ? '#' : '=';
my $r = system($gs, "-dCompatibilityLevel${o}1.4", "-q",
"-P-", "-dNOPAUSE", "-dBATCH", "-sDEVICE${o}pdfwrite",
"-sstdout${o}%stderr", "-sOutputFile${o}${out}",
"-dOptimize${o}true", "-dEmbedAllFonts${o}true",
"-dCompressPages${o}" . ($compress ? 'true' : 'false'),
"-dUseFlateCompression${o}true", $in, $out);
"-dUseFlateCompression${o}true",
"-c", ".setpdfwrite", "-f", $in);
exit 0 if ( !$r && -f $out );
# 3. pstopdf (BSD/MacOS X utility)

View file

@ -1,7 +1,7 @@
#!/usr/bin/perl
## --------------------------------------------------------------------------
##
## Copyright 1996-2017 The NASM Authors - All Rights Reserved
## Copyright 1996-2018 The NASM Authors - All Rights Reserved
## See the file AUTHORS included with the NASM distribution for
## the specific copyright holders.
##
@ -325,7 +325,7 @@ sub got_para {
$snum = 0;
$xref = "section-$cnum.$hnum";
$pflags = "head $cnum.$hnum :$xref";
die "badly formatted heading: $_\n" if !/^\\[HP]{([^\}]*)}\s*(.*)$/;
die "badly formatted heading: $_\n" if !/^\\[HP]\{([^\}]*)\}\s*(.*)$/;
$refs{$1} = "section $cnum.$hnum";
$node = "Section $cnum.$hnum";
&add_item($node, 2);

View file

@ -44,20 +44,27 @@
* An error reporting function should look like this.
*/
void printf_func(2, 3) nasm_error(int severity, const char *fmt, ...);
void printf_func(1, 2) nasm_debug(const char *fmt, ...);
void printf_func(2, 3) nasm_debugf(int flags, const char *fmt, ...);
void printf_func(1, 2) nasm_warn(const char *fmt, ...);
void printf_func(2, 3) nasm_warnf(int flags, const char *fmt, ...);
void printf_func(1, 2) nasm_nonfatal(const char *fmt, ...);
void printf_func(2, 3) nasm_nonfatalf(int flags, const char *fmt, ...);
fatal_func printf_func(1, 2) nasm_fatal(const char *fmt, ...);
fatal_func printf_func(2, 3) nasm_fatalf(int flags, const char *fmt, ...);
fatal_func printf_func(1, 2) nasm_panic(const char *fmt, ...);
fatal_func printf_func(2, 3) nasm_fatal_fl(int flags, const char *fmt, ...);
fatal_func printf_func(2, 3) nasm_panic_fl(int flags, const char *fmt, ...);
fatal_func printf_func(2, 3) nasm_panicf(int flags, const char *fmt, ...);
fatal_func nasm_panic_from_macro(const char *file, int line);
#define panic() nasm_panic_from_macro(__FILE__, __LINE__);
typedef void (*vefunc) (int severity, const char *fmt, va_list ap);
extern vefunc nasm_verror;
static inline vefunc nasm_set_verror(vefunc ve)
{
vefunc old_verror = nasm_verror;
nasm_verror = ve;
return old_verror;
vefunc old_verror = nasm_verror;
nasm_verror = ve;
return old_verror;
}
/*
@ -65,46 +72,46 @@ static inline vefunc nasm_set_verror(vefunc ve)
* argument to an efunc.
*/
#define ERR_DEBUG 0x00000000 /* put out debugging message */
#define ERR_WARNING 0x00000001 /* warn only: no further action */
#define ERR_NONFATAL 0x00000002 /* terminate assembly after phase */
#define ERR_FATAL 0x00000006 /* instantly fatal: exit with error */
#define ERR_PANIC 0x00000007 /* internal error: panic instantly
* and dump core for reference */
#define ERR_MASK 0x00000007 /* mask off the above codes */
#define ERR_NOFILE 0x00000010 /* don't give source file name/line */
#define ERR_TOPFILE 0x00000020 /* give the top input file name only */
#define ERR_USAGE 0x00000040 /* print a usage message */
#define ERR_PASS1 0x00000080 /* only print this error on pass one */
#define ERR_PASS2 0x00000100 /* only print this error on pass one */
#define ERR_DEBUG 0x00000000 /* put out debugging message */
#define ERR_WARNING 0x00000001 /* warn only: no further action */
#define ERR_NONFATAL 0x00000002 /* terminate assembly after phase */
#define ERR_FATAL 0x00000006 /* instantly fatal: exit with error */
#define ERR_PANIC 0x00000007 /* internal error: panic instantly
* and dump core for reference */
#define ERR_MASK 0x00000007 /* mask off the above codes */
#define ERR_NOFILE 0x00000010 /* don't give source file name/line */
#define ERR_TOPFILE 0x00000020 /* give the top input file name only */
#define ERR_USAGE 0x00000040 /* print a usage message */
#define ERR_PASS1 0x00000080 /* only print this error on pass one */
#define ERR_PASS2 0x00000100 /* only print this error on pass one */
#define ERR_NO_SEVERITY 0x00000200 /* suppress printing severity */
#define ERR_PP_PRECOND 0x00000400 /* for preprocessor use */
#define ERR_PP_LISTMACRO 0x00000800 /* from preproc->error_list_macros() */
#define ERR_NO_SEVERITY 0x00000200 /* suppress printing severity */
#define ERR_PP_PRECOND 0x00000400 /* for preprocessor use */
#define ERR_PP_LISTMACRO 0x00000800 /* from preproc->error_list_macros() */
/*
* These codes define specific types of suppressible warning.
*/
#define ERR_WARN_MASK 0xFFFFF000 /* the mask for this feature */
#define ERR_WARN_SHR 12 /* how far to shift right */
#define ERR_WARN_MASK 0xFFFFF000 /* the mask for this feature */
#define ERR_WARN_SHR 12 /* how far to shift right */
#define WARN(x) ((x) << ERR_WARN_SHR)
#define WARN_IDX(x) (((x) & ERR_WARN_MASK) >> ERR_WARN_SHR)
#define WARN(x) ((x) << ERR_WARN_SHR)
#define WARN_IDX(x) (((x) & ERR_WARN_MASK) >> ERR_WARN_SHR)
#define ERR_WARN_OTHER WARN( 0) /* any noncategorized warning */
#define ERR_WARN_MNP WARN( 1) /* macro-num-parameters warning */
#define ERR_WARN_MSR WARN( 2) /* macro self-reference */
#define ERR_WARN_MDP WARN( 3) /* macro default parameters check */
#define ERR_WARN_OL WARN( 4) /* orphan label (no colon, and
#define ERR_WARN_OTHER WARN( 0) /* any noncategorized warning */
#define ERR_WARN_MNP WARN( 1) /* macro-num-parameters warning */
#define ERR_WARN_MSR WARN( 2) /* macro self-reference */
#define ERR_WARN_MDP WARN( 3) /* macro default parameters check */
#define ERR_WARN_OL WARN( 4) /* orphan label (no colon, and
* alone on line) */
#define ERR_WARN_NOV WARN( 5) /* numeric overflow */
#define ERR_WARN_GNUELF WARN( 6) /* using GNU ELF extensions */
#define ERR_WARN_FL_OVERFLOW WARN( 7) /* FP overflow */
#define ERR_WARN_FL_DENORM WARN( 8) /* FP denormal */
#define ERR_WARN_FL_UNDERFLOW WARN( 9) /* FP underflow */
#define ERR_WARN_FL_TOOLONG WARN(10) /* FP too many digits */
#define ERR_WARN_USER WARN(11) /* %warning directives */
#define ERR_WARN_NOV WARN( 5) /* numeric overflow */
#define ERR_WARN_GNUELF WARN( 6) /* using GNU ELF extensions */
#define ERR_WARN_FL_OVERFLOW WARN( 7) /* FP overflow */
#define ERR_WARN_FL_DENORM WARN( 8) /* FP denormal */
#define ERR_WARN_FL_UNDERFLOW WARN( 9) /* FP underflow */
#define ERR_WARN_FL_TOOLONG WARN(10) /* FP too many digits */
#define ERR_WARN_USER WARN(11) /* %warning directives */
#define ERR_WARN_LOCK WARN(12) /* bad LOCK prefixes */
#define ERR_WARN_HLE WARN(13) /* bad HLE prefixes */
#define ERR_WARN_BND WARN(14) /* bad BND prefixes */
@ -115,25 +122,26 @@ static inline vefunc nasm_set_verror(vefunc ve)
#define ERR_WARN_NOTMY_PRAGMA WARN(19) /* pragma inapplicable */
#define ERR_WARN_UNK_WARNING WARN(20) /* unknown warning */
#define ERR_WARN_NEG_REP WARN(21) /* negative repeat count */
#define ERR_WARN_PHASE WARN(22) /* phase error in pass 1 */
/* The "all" warning acts as a global switch, it must come last */
#define ERR_WARN_ALL 22 /* Do not use WARN() here */
#define ERR_WARN_ALL 23 /* Do not use WARN() here */
struct warning {
const char *name;
const char *help;
bool enabled;
const char *name;
const char *help;
bool enabled;
};
extern const struct warning warnings[ERR_WARN_ALL+1];
/* This is a bitmask */
#define WARN_ST_ENABLED 1 /* Warning is currently enabled */
#define WARN_ST_ERROR 2 /* Treat this warning as an error */
#define WARN_ST_ENABLED 1 /* Warning is currently enabled */
#define WARN_ST_ERROR 2 /* Treat this warning as an error */
extern uint8_t warning_state[ERR_WARN_ALL];
extern uint8_t warning_state_init[ERR_WARN_ALL];
/* Process a warning option or directive */
bool set_warning_status(const char *);
bool set_warning_status(const char *value);
#endif /* NASM_ERROR_H */

View file

@ -337,7 +337,7 @@ struct preproc_ops {
* of the pass, an error reporting function, an evaluator
* function, and a listing generator to talk to.
*/
void (*reset)(const char *file, int pass, StrList **deplist);
void (*reset)(const char *file, int pass, struct strlist *deplist);
/*
* Called to fetch a line of preprocessed source. The line
@ -363,7 +363,7 @@ struct preproc_ops {
void (*pre_command)(const char *what, char *str);
/* Include path from command line */
void (*include_path)(char *path);
void (*include_path)(struct strlist *ipath);
/* Unwind the macro stack when printing an error message */
void (*error_list_macros)(int severity);
@ -373,7 +373,7 @@ extern const struct preproc_ops nasmpp;
extern const struct preproc_ops preproc_nop;
/* List of dependency files */
extern StrList *depend_list;
extern struct strlist *depend_list;
/*
* Some lexical properties of the NASM source language, included
@ -729,10 +729,11 @@ enum directive_result {
* as part of the struct pragma.
*/
struct pragma;
typedef enum directive_result (*pragma_handler)(const struct pragma *);
struct pragma_facility {
const char *name;
enum directive_result (*handler)(const struct pragma *);
pragma_handler handler;
};
/*
@ -912,9 +913,14 @@ struct ofmt {
* The offset isn't passed; and may not be stable at this point.
* The subsection number is a field available for use by the
* backend. It is initialized to NO_SEG.
*
* If "copyoffset" is set by the backend then the offset is
* copied from the previous segment, otherwise the new segment
* is treated as a new segment the normal way.
*/
int32_t (*herelabel)(const char *name, enum label_type type,
int32_t seg, int32_t *subsection);
int32_t seg, int32_t *subsection,
bool *copyoffset);
/*
* This procedure is called to modify section alignment,
@ -1244,11 +1250,25 @@ enum decorator_tokens {
* 2 = pass 2
*/
/*
* flag to disable optimizations selectively
* this is useful to turn-off certain optimizations
*/
enum optimization_disable_flag {
OPTIM_ALL_ENABLED = 0,
OPTIM_DISABLE_JMP_MATCH = 1
};
struct optimization {
int level;
int flag;
};
extern int pass0;
extern int64_t passn; /* Actual pass number */
extern bool tasm_compatible_mode;
extern int optimizing;
extern struct optimization optimizing;
extern int globalbits; /* 16, 32 or 64-bit mode */
extern int globalrel; /* default to relative addressing? */
extern int globalbnd; /* default to using bnd prefix? */

View file

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2013 The NASM Authors - All Rights Reserved
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@ -40,6 +40,7 @@
#include "compiler.h"
#include "tables.h" /* for opflags_t and nasm_reg_flags[] */
#include "regs.h"
/*
* Here we define the operand types. These are implemented as bit
@ -117,6 +118,16 @@
#define SIZE_MASK OP_GENMASK(SIZE_BITS, SIZE_SHIFT)
#define GEN_SIZE(bit) OP_GENBIT(bit, SIZE_SHIFT)
/*
* Register set count
*
* Bits: 47 - 43
*/
#define REGSET_SHIFT (43)
#define REGSET_BITS (5)
#define REGSET_MASK OP_GENMASK(REGSET_BITS, REGSET_SHIFT)
#define GEN_REGSET(bit) OP_GENBIT(bit, REGSET_SHIFT)
/*
* Bits distribution (counted from 0)
*
@ -131,6 +142,7 @@
* .......................................11111111................. subclasses
* ................................1111111......................... specials
* .....................11111111111................................ sizes
* ................11111........................................... regset count
*/
#define REGISTER GEN_OPTYPE(0) /* register number in 'basereg' */
@ -165,8 +177,17 @@
#define REG_CLASS_OPMASK GEN_REG_CLASS(8)
#define REG_CLASS_BND GEN_REG_CLASS(9)
#define is_class(class, op) (!((opflags_t)(class) & ~(opflags_t)(op)))
#define is_reg_class(class, reg) is_class((class), nasm_reg_flags[(reg)])
static inline bool is_class(opflags_t class, opflags_t op)
{
return !(class & ~op);
}
static inline bool is_reg_class(opflags_t class, opflags_t reg)
{
if (reg >= EXPR_REG_START && reg <= EXPR_REG_END)
return is_class(class, nasm_reg_flags[reg]);
return false;
}
#define IS_SREG(reg) is_reg_class(REG_SREG, (reg))
#define IS_FSGS(reg) is_reg_class(REG_FSGS, (reg))
@ -268,4 +289,11 @@
#define ZMM0 (GEN_SUBCLASS(1) | GEN_SUBCLASS(6) | ZMMREG) /* ZMM register zero */
#define ZMM_L16 ( GEN_SUBCLASS(6) | ZMMREG) /* ZMM register 0 ~ 15 */
/* Register set sizes */
#define RS2 GEN_REGSET(0)
#define RS4 GEN_REGSET(1)
#define RS8 GEN_REGSET(2)
#define RS16 GEN_REGSET(3)
#define RS32 GEN_REGSET(4)
#endif /* NASM_OPFLAGS_H */

View file

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2016 The NASM Authors - All Rights Reserved
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@ -39,17 +39,23 @@
#define NASM_STRLIST_H
#include "compiler.h"
#include <string.h>
#include "nasmlib.h"
#include "hashtbl.h"
typedef struct string_list {
struct string_list *next;
char str[1];
} StrList;
struct strlist_entry {
struct strlist_entry *next;
size_t len;
char str[1];
};
bool nasm_add_to_strlist(StrList **head, StrList *entry);
bool nasm_add_string_to_strlist(StrList **head, const char *str);
struct strlist {
struct hash_table hash;
struct strlist_entry *head;
struct strlist_entry **tailp;
};
struct strlist safe_alloc *strlist_alloc(void);
void strlist_free(struct strlist *list);
bool strlist_add(struct strlist *list, const char *str);
#endif /* NASM_STRLIST_H */

View file

@ -41,7 +41,13 @@
extern const char nasm_version[];
extern const char nasm_date[];
extern const char nasm_compile_options[];
extern const char nasm_comment[];
extern const char nasm_signature[];
extern const char *nasm_comment(void);
extern size_t nasm_comment_len(void);
extern const char *nasm_signature(void);
extern size_t nasm_signature_len(void);
extern int nasm_test_run(void);
#endif /* NASM_VER_H */

View file

@ -1,5 +1,5 @@
#!/bin/sh
PARAM="-npro -kr -i4 -ts8 -nut -sob -l80 -ss -ncs -cp1"
PARAM="-npro -kr -i8 -ts8 -sob -l80 -ss -ncs -cp1"
RES=`indent --version`
V1=`echo $RES | cut -d' ' -f3 | cut -d'.' -f1`
V2=`echo $RES | cut -d' ' -f3 | cut -d'.' -f2`

View file

@ -119,8 +119,8 @@ FILE *nasm_open_read(const char *filename, enum file_flags flags)
f = fopen(filename, (flags & NF_TEXT) ? "rt" : "rb");
if (!f && (flags & NF_FATAL))
nasm_fatal_fl(ERR_NOFILE, "unable to open input file: `%s': %s",
filename, strerror(errno));
nasm_fatalf(ERR_NOFILE, "unable to open input file: `%s': %s",
filename, strerror(errno));
return f;
}
@ -132,8 +132,8 @@ FILE *nasm_open_write(const char *filename, enum file_flags flags)
f = fopen(filename, (flags & NF_TEXT) ? "wt" : "wb");
if (!f && (flags & NF_FATAL))
nasm_fatal_fl(ERR_NOFILE, "unable to open output file: `%s': %s",
filename, strerror(errno));
nasm_fatalf(ERR_NOFILE, "unable to open output file: `%s': %s",
filename, strerror(errno));
return f;
}

View file

@ -164,7 +164,7 @@ char *nasm_catfile(const char *dir, const char *file)
#else
size_t dl = strlen(dir);
size_t fl = strlen(file);
char *p;
char *p, *pp;
bool dosep = true;
if (!dl || ismatch(separators, dir[dl-1])) {
@ -172,14 +172,14 @@ char *nasm_catfile(const char *dir, const char *file)
dosep = false;
}
p = nasm_malloc(dl + fl + dosep + 1);
p = pp = nasm_malloc(dl + fl + dosep + 1);
memcpy(p, dir, dl);
p += dl;
memcpy(pp, dir, dl);
pp += dl;
if (dosep)
*p++ = catsep;
*pp++ = catsep;
memcpy(p, file, fl+1);
memcpy(pp, file, fl+1);
return p;
#endif

View file

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2016 The NASM Authors - All Rights Reserved
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@ -32,69 +32,59 @@
* ----------------------------------------------------------------------- */
/*
* strlist.c - simple linked list of strings
* strlist.c - list of unique, ordered strings
*/
#include "compiler.h"
#include <string.h>
#include "strlist.h"
static inline StrList *nasm_str_to_strlist(const char *str)
{
size_t l = strlen(str) + 1;
StrList *sl = nasm_malloc(l + sizeof sl->next);
memcpy(sl->str, str, l);
sl->next = NULL;
return sl;
}
/*
* Append a string list entry to a string list if and only if it isn't
* already there. Return true if it was added.
* Create a string list
*/
bool nasm_add_to_strlist(StrList **head, StrList *entry)
struct strlist *strlist_alloc(void)
{
StrList *list;
if (!head)
return false;
list = *head;
while (list) {
if (!strcmp(list->str, entry->str))
return false;
head = &list->next;
list = list->next;
}
*head = entry;
entry->next = NULL;
return true;
struct strlist *list = nasm_zalloc(sizeof(*list));
hash_init(&list->hash, HASH_MEDIUM);
list->tailp = &list->head;
return list;
}
/*
* Append a string to a string list if and only if it isn't
* already there. Return true if it was added.
*/
bool nasm_add_string_to_strlist(StrList **head, const char *str)
bool strlist_add(struct strlist *list, const char *str)
{
StrList *list;
struct strlist_entry *e;
struct hash_insert hi;
size_t len;
if (!head)
return false;
if (!list)
return false;
list = *head;
while (list) {
if (!strcmp(list->str, str))
return false;
head = &list->next;
list = list->next;
}
if (hash_find(&list->hash, str, &hi))
return false;
*head = nasm_str_to_strlist(str);
return true;
len = strlen(str);
/* Structure already has char[1] as EOS */
e = nasm_zalloc(sizeof(*e) + len);
e->len = len;
memcpy(e->str, str, len + 1);
*list->tailp = e;
list->tailp = &e->next;
hash_add(&hi, e->str, (void *)e);
return true;
}
/*
* Free a string list
*/
void strlist_free(struct strlist *list)
{
if (list) {
hash_free_all(&list->hash, false);
nasm_free(list);
}
}

View file

@ -31,6 +31,9 @@
*
* ----------------------------------------------------------------------- */
#include <stdlib.h>
#include <string.h>
#include "ver.h"
#include "version.h"
@ -44,8 +47,45 @@ const char nasm_compile_options[] = ""
;
/* These are used by some backends. */
const char nasm_comment[] =
static const char __nasm_comment[] =
"The Netwide Assembler " NASM_VER;
const char nasm_signature[] =
static const char __nasm_signature[] =
"NASM " NASM_VER;
/* These are constant so we could pass regression tests */
static const char __nasm_comment_const[] ="The Netwide Assembler CONST";
static const char __nasm_signature_const[] = "NASM CONST";
int nasm_test_run(void)
{
return getenv("NASM_TEST_RUN") ? 1 : 0;
}
const char *nasm_comment(void)
{
if (!nasm_test_run())
return __nasm_comment;
return __nasm_comment_const;
}
size_t nasm_comment_len(void)
{
if (!nasm_test_run())
return strlen(__nasm_comment);
return strlen(__nasm_comment_const);
}
const char *nasm_signature(void)
{
if (!nasm_test_run())
return __nasm_signature;
return __nasm_signature_const;
}
size_t nasm_signature_len(void)
{
if (!nasm_test_run())
return strlen(__nasm_signature);
return strlen(__nasm_signature_const);
}

View file

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@ -90,6 +90,7 @@ enum dwarf_tag {
DW_TAG_variant_part = 0x33,
DW_TAG_variable = 0x34,
DW_TAG_volatile_type = 0x35,
/* DWARF 3 */
DW_TAG_dwarf_procedure = 0x36,
DW_TAG_restrict_type = 0x37,
DW_TAG_interface_type = 0x38,
@ -100,6 +101,12 @@ enum dwarf_tag {
DW_TAG_imported_unit = 0x3d,
DW_TAG_condition = 0x3f,
DW_TAG_shared_type = 0x40,
/* DWARF 4 */
DW_TAG_type_unit = 0x41,
DW_TAG_rvalue_reference_type = 0x42,
DW_TAG_template_alias = 0x43,
/* DWARF 5 */
DW_TAG_atomic_type = 0x47,
DW_TAG_lo_user = 0x4080,
DW_TAG_hi_user = 0xffff
@ -131,7 +138,12 @@ enum dwarf_form {
DW_FORM_ref4 = 0x13,
DW_FORM_ref8 = 0x14,
DW_FORM_ref_udata = 0x15,
DW_FORM_indirect = 0x16
DW_FORM_indirect = 0x16,
/* DWARF 4 */
DW_FORM_sec_offset = 0x17,
DW_FORM_exprloc = 0x18,
DW_FORM_flag_present = 0x19,
DW_FORM_ref_sig8 = 0x20
};
enum dwarf_attribute {
@ -194,6 +206,7 @@ enum dwarf_attribute {
DW_AT_variable_parameter = 0x4b,
DW_AT_virtuality = 0x4c,
DW_AT_vtable_elem_location = 0x4d,
/* DWARF 3 */
DW_AT_allocated = 0x4e,
DW_AT_associated = 0x4f,
DW_AT_data_location = 0x50,
@ -221,6 +234,15 @@ enum dwarf_attribute {
DW_AT_elemental = 0x66,
DW_AT_pure = 0x67,
DW_AT_recursive = 0x68,
/* DWARF 4 */
DW_AT_signature = 0x69,
DW_AT_main_subprogram = 0x6a,
DW_AT_data_bit_offset = 0x6b,
DW_AT_const_expr = 0x6c,
DW_AT_enum_class = 0x6d,
DW_AT_linkage_name = 0x6e,
/* DWARF 5 */
DW_AT_noreturn = 0x87,
DW_AT_lo_user = 0x2000,
DW_AT_hi_user = 0x3fff
@ -372,6 +394,7 @@ enum dwarf_op {
DW_OP_deref_size = 0x94,
DW_OP_xderef_size = 0x95,
DW_OP_nop = 0x96,
/* DWARF 3 */
DW_OP_push_object_address = 0x97,
DW_OP_call2 = 0x98,
DW_OP_call4 = 0x99,
@ -379,6 +402,9 @@ enum dwarf_op {
DW_OP_form_tls_address = 0x9b,
DW_OP_call_frame_cfa = 0x9c,
DW_OP_bit_piece = 0x9d,
/* DWARF 4 */
DW_OP_implicit_value = 0x9e,
DW_OP_stack_value = 0x9f,
DW_OP_lo_user = 0xe0,
DW_OP_hi_user = 0xff
@ -393,6 +419,7 @@ enum dwarf_base_type {
DW_ATE_signed_char = 0x06,
DW_ATE_unsigned = 0x07,
DW_ATE_unsigned_char = 0x08,
/* DWARF 3 */
DW_ATE_imaginary_float = 0x09,
DW_ATE_packed_decimal = 0x0a,
DW_ATE_numeric_string = 0x0b,
@ -400,6 +427,8 @@ enum dwarf_base_type {
DW_ATE_signed_fixed = 0x0d,
DW_ATE_unsigned_fixed = 0x0e,
DW_ATE_decimal_float = 0x0f,
/* DWARF 4 */
DW_ATE_UTF = 0x10,
DW_ATE_lo_user = 0x80,
DW_ATE_hi_user = 0xff
@ -576,7 +605,8 @@ enum dwarf_call_frame {
DW_CFA_def_cfa = 0x0c,
DW_CFA_def_cfa_register = 0x0d,
DW_CFA_def_cfa_offset = 0x0e,
DW_CFA_def_cfa_expression = 0x0f,
/* DWARF 3 */
DW_CFA_def_cfa_expression = 0x0f,
DW_CFA_expression = 0x10,
DW_CFA_offset_extended_sf = 0x11,
DW_CFA_def_cfa_sf = 0x12,

View file

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@ -42,367 +42,367 @@
#include "compiler.h"
/* Segment types */
#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_SHLIB 5
#define PT_PHDR 6
#define PT_LOOS 0x60000000
#define PT_HIOS 0x6fffffff
#define PT_LOPROC 0x70000000
#define PT_HIPROC 0x7fffffff
#define PT_GNU_EH_FRAME 0x6474e550 /* Extension, eh? */
#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_SHLIB 5
#define PT_PHDR 6
#define PT_LOOS 0x60000000
#define PT_HIOS 0x6fffffff
#define PT_LOPROC 0x70000000
#define PT_HIPROC 0x7fffffff
#define PT_GNU_EH_FRAME 0x6474e550 /* Extension, eh? */
/* ELF file types */
#define ET_NONE 0
#define ET_REL 1
#define ET_EXEC 2
#define ET_DYN 3
#define ET_CORE 4
#define ET_LOPROC 0xff00
#define ET_HIPROC 0xffff
#define ET_NONE 0
#define ET_REL 1
#define ET_EXEC 2
#define ET_DYN 3
#define ET_CORE 4
#define ET_LOPROC 0xff00
#define ET_HIPROC 0xffff
/* ELF machine types */
#define EM_NONE 0
#define EM_M32 1
#define EM_SPARC 2
#define EM_386 3
#define EM_68K 4
#define EM_88K 5
#define EM_486 6 /* Not used in Linux at least */
#define EM_860 7
#define EM_MIPS 8 /* R3k, bigendian(?) */
#define EM_MIPS_RS4_BE 10 /* R4k BE */
#define EM_PARISC 15
#define EM_SPARC32PLUS 18
#define EM_PPC 20
#define EM_PPC64 21
#define EM_S390 22
#define EM_SH 42
#define EM_SPARCV9 43 /* v9 = SPARC64 */
#define EM_H8_300H 47
#define EM_H8S 48
#define EM_IA_64 50
#define EM_X86_64 62
#define EM_CRIS 76
#define EM_V850 87
#define EM_ALPHA 0x9026 /* Interrim Alpha that stuck around */
#define EM_CYGNUS_V850 0x9080 /* Old v850 ID used by Cygnus */
#define EM_S390_OLD 0xA390 /* Obsolete interrim value for S/390 */
#define EM_NONE 0
#define EM_M32 1
#define EM_SPARC 2
#define EM_386 3
#define EM_68K 4
#define EM_88K 5
#define EM_486 6 /* Not used in Linux at least */
#define EM_860 7
#define EM_MIPS 8 /* R3k, bigendian(?) */
#define EM_MIPS_RS4_BE 10 /* R4k BE */
#define EM_PARISC 15
#define EM_SPARC32PLUS 18
#define EM_PPC 20
#define EM_PPC64 21
#define EM_S390 22
#define EM_SH 42
#define EM_SPARCV9 43 /* v9 = SPARC64 */
#define EM_H8_300H 47
#define EM_H8S 48
#define EM_IA_64 50
#define EM_X86_64 62
#define EM_CRIS 76
#define EM_V850 87
#define EM_ALPHA 0x9026 /* Interrim Alpha that stuck around */
#define EM_CYGNUS_V850 0x9080 /* Old v850 ID used by Cygnus */
#define EM_S390_OLD 0xA390 /* Obsolete interrim value for S/390 */
/* Dynamic type values */
#define DT_NULL 0
#define DT_NEEDED 1
#define DT_PLTRELSZ 2
#define DT_PLTGOT 3
#define DT_HASH 4
#define DT_STRTAB 5
#define DT_SYMTAB 6
#define DT_RELA 7
#define DT_RELASZ 8
#define DT_RELAENT 9
#define DT_STRSZ 10
#define DT_SYMENT 11
#define DT_INIT 12
#define DT_FINI 13
#define DT_SONAME 14
#define DT_RPATH 15
#define DT_SYMBOLIC 16
#define DT_REL 17
#define DT_RELSZ 18
#define DT_RELENT 19
#define DT_PLTREL 20
#define DT_DEBUG 21
#define DT_TEXTREL 22
#define DT_JMPREL 23
#define DT_LOPROC 0x70000000
#define DT_HIPROC 0x7fffffff
#define DT_NULL 0
#define DT_NEEDED 1
#define DT_PLTRELSZ 2
#define DT_PLTGOT 3
#define DT_HASH 4
#define DT_STRTAB 5
#define DT_SYMTAB 6
#define DT_RELA 7
#define DT_RELASZ 8
#define DT_RELAENT 9
#define DT_STRSZ 10
#define DT_SYMENT 11
#define DT_INIT 12
#define DT_FINI 13
#define DT_SONAME 14
#define DT_RPATH 15
#define DT_SYMBOLIC 16
#define DT_REL 17
#define DT_RELSZ 18
#define DT_RELENT 19
#define DT_PLTREL 20
#define DT_DEBUG 21
#define DT_TEXTREL 22
#define DT_JMPREL 23
#define DT_LOPROC 0x70000000
#define DT_HIPROC 0x7fffffff
/* Auxilliary table entries */
#define AT_NULL 0 /* end of vector */
#define AT_IGNORE 1 /* entry should be ignored */
#define AT_EXECFD 2 /* file descriptor of program */
#define AT_PHDR 3 /* program headers for program */
#define AT_PHENT 4 /* size of program header entry */
#define AT_PHNUM 5 /* number of program headers */
#define AT_PAGESZ 6 /* system page size */
#define AT_BASE 7 /* base address of interpreter */
#define AT_FLAGS 8 /* flags */
#define AT_ENTRY 9 /* entry point of program */
#define AT_NOTELF 10 /* program is not ELF */
#define AT_UID 11 /* real uid */
#define AT_EUID 12 /* effective uid */
#define AT_GID 13 /* real gid */
#define AT_EGID 14 /* effective gid */
#define AT_PLATFORM 15 /* string identifying CPU for optimizations */
#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
#define AT_CLKTCK 17 /* frequency at which times() increments */
#define AT_NULL 0 /* end of vector */
#define AT_IGNORE 1 /* entry should be ignored */
#define AT_EXECFD 2 /* file descriptor of program */
#define AT_PHDR 3 /* program headers for program */
#define AT_PHENT 4 /* size of program header entry */
#define AT_PHNUM 5 /* number of program headers */
#define AT_PAGESZ 6 /* system page size */
#define AT_BASE 7 /* base address of interpreter */
#define AT_FLAGS 8 /* flags */
#define AT_ENTRY 9 /* entry point of program */
#define AT_NOTELF 10 /* program is not ELF */
#define AT_UID 11 /* real uid */
#define AT_EUID 12 /* effective uid */
#define AT_GID 13 /* real gid */
#define AT_EGID 14 /* effective gid */
#define AT_PLATFORM 15 /* string identifying CPU for optimizations */
#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
#define AT_CLKTCK 17 /* frequency at which times() increments */
/* 18..22 = ? */
#define AT_SECURE 23 /* secure mode boolean */
#define AT_SECURE 23 /* secure mode boolean */
/* Program header permission flags */
#define PF_X 0x1
#define PF_W 0x2
#define PF_R 0x4
#define PF_X 0x1
#define PF_W 0x2
#define PF_R 0x4
/* Section header types */
#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
#define SHT_NUM 12
#define SHT_LOPROC 0x70000000
#define SHT_HIPROC 0x7fffffff
#define SHT_LOUSER 0x80000000
#define SHT_HIUSER 0xffffffff
#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
#define SHT_NUM 12
#define SHT_LOPROC 0x70000000
#define SHT_HIPROC 0x7fffffff
#define SHT_LOUSER 0x80000000
#define SHT_HIUSER 0xffffffff
/* Section header flags */
#define SHF_WRITE (1 << 0) /* Writable */
#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
#define SHF_EXECINSTR (1 << 2) /* Executable */
#define SHF_MERGE (1 << 4) /* Might be merged */
#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */
#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */
#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */
#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling required */
#define SHF_GROUP (1 << 9) /* Section is member of a group. */
#define SHF_TLS (1 << 10) /* Section hold thread-local data. */
#define SHF_WRITE (1 << 0) /* Writable */
#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
#define SHF_EXECINSTR (1 << 2) /* Executable */
#define SHF_MERGE (1 << 4) /* Might be merged */
#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */
#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */
#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */
#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling required */
#define SHF_GROUP (1 << 9) /* Section is member of a group */
#define SHF_TLS (1 << 10) /* Section hold thread-local data */
/* Special section numbers */
#define SHN_UNDEF 0
#define SHN_LORESERVE 0xff00
#define SHN_LOPROC 0xff00
#define SHN_HIPROC 0xff1f
#define SHN_ABS 0xfff1
#define SHN_COMMON 0xfff2
#define SHN_HIRESERVE 0xffff
#define SHN_UNDEF 0
#define SHN_LORESERVE 0xff00
#define SHN_LOPROC 0xff00
#define SHN_HIPROC 0xff1f
#define SHN_ABS 0xfff1
#define SHN_COMMON 0xfff2
#define SHN_HIRESERVE 0xffff
/* Section align flag */
#define SHA_ANY 1 /* No alignment constraint */
#define SHA_ANY 1 /* No alignment constraint */
/* Lenght of magic at the start of a file */
#define EI_NIDENT 16
#define EI_NIDENT 16
/* Magic number constants... */
#define EI_MAG0 0 /* e_ident[] indexes */
#define EI_MAG1 1
#define EI_MAG2 2
#define EI_MAG3 3
#define EI_CLASS 4
#define EI_DATA 5
#define EI_VERSION 6
#define EI_OSABI 7
#define EI_ABIVERSION 8
#define EI_NINDENT 16
#define EI_MAG0 0 /* e_ident[] indexes */
#define EI_MAG1 1
#define EI_MAG2 2
#define EI_MAG3 3
#define EI_CLASS 4
#define EI_DATA 5
#define EI_VERSION 6
#define EI_OSABI 7
#define EI_ABIVERSION 8
#define EI_NINDENT 16
#define ELFMAG0 0x7f /* EI_MAG */
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
#define ELFMAG "\177ELF"
#define SELFMAG 4
#define ELFMAG0 0x7f /* EI_MAG */
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
#define ELFMAG "\177ELF"
#define SELFMAG 4
#define ELFCLASSNONE 0 /* EI_CLASS */
#define ELFCLASS32 1
#define ELFCLASS64 2
#define ELFCLASSNUM 3
#define ELFCLASSNONE 0 /* EI_CLASS */
#define ELFCLASS32 1
#define ELFCLASS64 2
#define ELFCLASSNUM 3
#define ELFDATANONE 0 /* e_ident[EI_DATA] */
#define ELFDATA2LSB 1
#define ELFDATA2MSB 2
#define ELFDATANONE 0 /* e_ident[EI_DATA] */
#define ELFDATA2LSB 1
#define ELFDATA2MSB 2
#define EV_NONE 0 /* e_version, EI_VERSION */
#define EV_CURRENT 1
#define EV_NUM 2
#define EV_NONE 0 /* e_version, EI_VERSION */
#define EV_CURRENT 1
#define EV_NUM 2
#define ELFOSABI_NONE 0
#define ELFOSABI_LINUX 3
#define ELFOSABI_NONE 0
#define ELFOSABI_LINUX 3
/* Legal values for ST_BIND subfield of st_info (symbol binding). */
#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* Weak symbol */
#define STB_NUM 3 /* Number of defined types. */
#define STB_LOOS 10 /* Start of OS-specific */
#define STB_HIOS 12 /* End of OS-specific */
#define STB_LOPROC 13 /* Start of processor-specific */
#define STB_HIPROC 15 /* End of processor-specific */
/* Legal values for ST_BIND subfield of st_info (symbol binding) */
#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* Weak symbol */
#define STB_NUM 3 /* Number of defined types */
#define STB_LOOS 10 /* Start of OS-specific */
#define STB_HIOS 12 /* End of OS-specific */
#define STB_LOPROC 13 /* Start of processor-specific */
#define STB_HIPROC 15 /* End of processor-specific */
/* Symbol types */
#define STT_NOTYPE 0 /* Symbol type is unspecified */
#define STT_OBJECT 1 /* Symbol is a data object */
#define STT_FUNC 2 /* Symbol is a code object */
#define STT_SECTION 3 /* Symbol associated with a section */
#define STT_FILE 4 /* Symbol's name is file name */
#define STT_COMMON 5 /* Symbol is a common data object */
#define STT_TLS 6 /* Symbol is thread-local data object*/
#define STT_NUM 7 /* Number of defined types. */
#define STT_NOTYPE 0 /* Symbol type is unspecified */
#define STT_OBJECT 1 /* Symbol is a data object */
#define STT_FUNC 2 /* Symbol is a code object */
#define STT_SECTION 3 /* Symbol associated with a section */
#define STT_FILE 4 /* Symbol's name is file name */
#define STT_COMMON 5 /* Symbol is a common data object */
#define STT_TLS 6 /* Symbol is thread-local data object */
#define STT_NUM 7 /* Number of defined types */
/* Symbol visibilities */
#define STV_DEFAULT 0 /* Default symbol visibility rules */
#define STV_INTERNAL 1 /* Processor specific hidden class */
#define STV_HIDDEN 2 /* Sym unavailable in other modules */
#define STV_PROTECTED 3 /* Not preemptible, not exported */
#define STV_DEFAULT 0 /* Default symbol visibility rules */
#define STV_INTERNAL 1 /* Processor specific hidden class */
#define STV_HIDDEN 2 /* Sym unavailable in other modules */
#define STV_PROTECTED 3 /* Not preemptible, not exported */
/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field */
#define ELF32_ST_BIND(i) ((i) >> 4)
#define ELF32_ST_MKBIND(i) ((i) << 4) /* just a helper */
#define ELF32_ST_TYPE(i) ((i) & 0xf)
#define ELF32_ST_INFO(b, i) (ELF32_ST_MKBIND(b) + ELF32_ST_TYPE(i))
#define ELF32_ST_BIND(i) ((i) >> 4)
#define ELF32_ST_MKBIND(i) ((i) << 4) /* just a helper */
#define ELF32_ST_TYPE(i) ((i) & 0xf)
#define ELF32_ST_INFO(b, i) (ELF32_ST_MKBIND(b) + ELF32_ST_TYPE(i))
#define ELF64_ST_BIND(i) ELF32_ST_BIND(i)
#define ELF64_ST_MKBIND(i) ELF32_ST_MKBIND(i)
#define ELF64_ST_TYPE(i) ELF32_ST_TYPE(i)
#define ELF64_ST_INFO(b, i) ELF32_ST_INFO(b, i)
#define ELF64_ST_BIND(i) ELF32_ST_BIND(i)
#define ELF64_ST_MKBIND(i) ELF32_ST_MKBIND(i)
#define ELF64_ST_TYPE(i) ELF32_ST_TYPE(i)
#define ELF64_ST_INFO(b, i) ELF32_ST_INFO(b, i)
/*
* ELF standard typedefs (yet more proof that <stdint.h> was way overdue)
*/
typedef uint16_t Elf32_Half;
typedef int16_t Elf32_SHalf;
typedef uint32_t Elf32_Word;
typedef int32_t Elf32_Sword;
typedef uint64_t Elf32_Xword;
typedef int64_t Elf32_Sxword;
typedef uint16_t Elf32_Half;
typedef int16_t Elf32_SHalf;
typedef uint32_t Elf32_Word;
typedef int32_t Elf32_Sword;
typedef uint64_t Elf32_Xword;
typedef int64_t Elf32_Sxword;
typedef uint32_t Elf32_Off;
typedef uint32_t Elf32_Addr;
typedef uint16_t Elf32_Section;
typedef uint32_t Elf32_Off;
typedef uint32_t Elf32_Addr;
typedef uint16_t Elf32_Section;
typedef uint16_t Elf64_Half;
typedef int16_t Elf64_SHalf;
typedef uint32_t Elf64_Word;
typedef int32_t Elf64_Sword;
typedef uint64_t Elf64_Xword;
typedef int64_t Elf64_Sxword;
typedef uint16_t Elf64_Half;
typedef int16_t Elf64_SHalf;
typedef uint32_t Elf64_Word;
typedef int32_t Elf64_Sword;
typedef uint64_t Elf64_Xword;
typedef int64_t Elf64_Sxword;
typedef uint64_t Elf64_Off;
typedef uint64_t Elf64_Addr;
typedef uint16_t Elf64_Section;
typedef uint64_t Elf64_Off;
typedef uint64_t Elf64_Addr;
typedef uint16_t Elf64_Section;
/*
* Dynamic header
*/
typedef struct elf32_dyn {
Elf32_Sword d_tag;
union {
Elf32_Sword d_val;
Elf32_Addr d_ptr;
} d_un;
Elf32_Sword d_tag;
union {
Elf32_Sword d_val;
Elf32_Addr d_ptr;
} d_un;
} Elf32_Dyn;
typedef struct elf64_dyn {
Elf64_Sxword d_tag;
union {
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un;
Elf64_Sxword d_tag;
union {
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un;
} Elf64_Dyn;
/*
* Relocations
*/
#define ELF32_R_SYM(x) ((x) >> 8)
#define ELF32_R_TYPE(x) ((x) & 0xff)
#define ELF32_R_INFO(s,t) (((Elf32_Word)(s) << 8) + ELF32_R_TYPE(t))
#define ELF32_R_SYM(x) ((x) >> 8)
#define ELF32_R_TYPE(x) ((x) & 0xff)
#define ELF32_R_INFO(s,t) (((Elf32_Word)(s) << 8) + ELF32_R_TYPE(t))
typedef struct elf32_rel {
Elf32_Addr r_offset;
Elf32_Word r_info;
Elf32_Addr r_offset;
Elf32_Word r_info;
} Elf32_Rel;
typedef struct elf32_rela {
Elf32_Addr r_offset;
Elf32_Word r_info;
Elf32_Sword r_addend;
Elf32_Addr r_offset;
Elf32_Word r_info;
Elf32_Sword r_addend;
} Elf32_Rela;
enum reloc32_type {
R_386_32 = 1, /* ordinary absolute relocation */
R_386_PC32 = 2, /* PC-relative relocation */
R_386_GOT32 = 3, /* an offset into GOT */
R_386_PLT32 = 4, /* a PC-relative offset into PLT */
R_386_COPY = 5, /* ??? */
R_386_GLOB_DAT = 6, /* ??? */
R_386_JUMP_SLOT = 7, /* ??? */
R_386_RELATIVE = 8, /* ??? */
R_386_GOTOFF = 9, /* an offset from GOT base */
R_386_GOTPC = 10, /* a PC-relative offset _to_ GOT */
R_386_TLS_TPOFF = 14, /* Offset in static TLS block */
R_386_TLS_IE = 15, /* Address of GOT entry for static TLS block offset */
/* These are GNU extensions, but useful */
R_386_16 = 20, /* A 16-bit absolute relocation */
R_386_PC16 = 21, /* A 16-bit PC-relative relocation */
R_386_8 = 22, /* An 8-bit absolute relocation */
R_386_PC8 = 23 /* An 8-bit PC-relative relocation */
R_386_32 = 1, /* ordinary absolute relocation */
R_386_PC32 = 2, /* PC-relative relocation */
R_386_GOT32 = 3, /* an offset into GOT */
R_386_PLT32 = 4, /* a PC-relative offset into PLT */
R_386_COPY = 5, /* ??? */
R_386_GLOB_DAT = 6, /* ??? */
R_386_JUMP_SLOT = 7, /* ??? */
R_386_RELATIVE = 8, /* ??? */
R_386_GOTOFF = 9, /* an offset from GOT base */
R_386_GOTPC = 10, /* a PC-relative offset _to_ GOT */
R_386_TLS_TPOFF = 14, /* Offset in static TLS block */
R_386_TLS_IE = 15, /* Address of GOT entry for static TLS block offset */
/* These are GNU extensions, but useful */
R_386_16 = 20, /* A 16-bit absolute relocation */
R_386_PC16 = 21, /* A 16-bit PC-relative relocation */
R_386_8 = 22, /* An 8-bit absolute relocation */
R_386_PC8 = 23 /* An 8-bit PC-relative relocation */
};
#define ELF64_R_SYM(x) ((x) >> 32)
#define ELF64_R_TYPE(x) ((x) & 0xffffffff)
#define ELF64_R_INFO(s,t) (((Elf64_Xword)(s) << 32) + ELF64_R_TYPE(t))
#define ELF64_R_SYM(x) ((x) >> 32)
#define ELF64_R_TYPE(x) ((x) & 0xffffffff)
#define ELF64_R_INFO(s,t) (((Elf64_Xword)(s) << 32) + ELF64_R_TYPE(t))
typedef struct elf64_rel {
Elf64_Addr r_offset;
Elf64_Xword r_info;
Elf64_Addr r_offset;
Elf64_Xword r_info;
} Elf64_Rel;
typedef struct elf64_rela {
Elf64_Addr r_offset;
Elf64_Xword r_info;
Elf64_Sxword r_addend;
Elf64_Addr r_offset;
Elf64_Xword r_info;
Elf64_Sxword r_addend;
} Elf64_Rela;
enum reloc64_type {
R_X86_64_NONE = 0, /* No reloc */
R_X86_64_64 = 1, /* Direct 64 bit */
R_X86_64_PC32 = 2, /* PC relative 32 bit signed */
R_X86_64_GOT32 = 3, /* 32 bit GOT entry */
R_X86_64_PLT32 = 4, /* 32 bit PLT address */
R_X86_64_COPY = 5, /* Copy symbol at runtime */
R_X86_64_GLOB_DAT = 6, /* Create GOT entry */
R_X86_64_JUMP_SLOT = 7, /* Create PLT entry */
R_X86_64_RELATIVE = 8, /* Adjust by program base */
R_X86_64_GOTPCREL = 9, /* 32 bit signed PC relative offset to GOT */
R_X86_64_32 = 10, /* Direct 32 bit zero extended */
R_X86_64_32S = 11, /* Direct 32 bit sign extended */
R_X86_64_16 = 12, /* Direct 16 bit zero extended */
R_X86_64_PC16 = 13, /* 16 bit sign extended pc relative */
R_X86_64_8 = 14, /* Direct 8 bit sign extended */
R_X86_64_PC8 = 15, /* 8 bit sign extended pc relative */
R_X86_64_DTPMOD64 = 16, /* ID of module containing symbol */
R_X86_64_DTPOFF64 = 17, /* Offset in module's TLS block */
R_X86_64_TPOFF64 = 18, /* Offset in initial TLS block */
R_X86_64_TLSGD = 19, /* 32 bit signed PC relative offset to two GOT entries for GD symbol */
R_X86_64_TLSLD = 20, /* 32 bit signed PC relative offset to two GOT entries for LD symbol */
R_X86_64_DTPOFF32 = 21, /* Offset in TLS block */
R_X86_64_GOTTPOFF = 22, /* 32 bit signed PC relative offset to GOT entry for IE symbol */
R_X86_64_TPOFF32 = 23, /* Offset in initial TLS block */
R_X86_64_PC64 = 24, /* word64 S + A - P */
R_X86_64_GOTOFF64 = 25, /* word64 S + A - GOT */
R_X86_64_GOTPC32 = 26, /* word32 GOT + A - P */
R_X86_64_GOT64 = 27, /* word64 G + A */
R_X86_64_GOTPCREL64 = 28, /* word64 G + GOT - P + A */
R_X86_64_GOTPC64 = 29, /* word64 GOT - P + A */
R_X86_64_GOTPLT64 = 30, /* word64 G + A */
R_X86_64_PLTOFF64 = 31, /* word64 L - GOT + A */
R_X86_64_SIZE32 = 32, /* word32 Z + A */
R_X86_64_SIZE64 = 33, /* word64 Z + A */
R_X86_64_GOTPC32_TLSDESC = 34, /* word32 */
R_X86_64_TLSDESC_CALL = 35, /* none */
R_X86_64_TLSDESC = 36 /* word64?2 */
R_X86_64_NONE = 0, /* No reloc */
R_X86_64_64 = 1, /* Direct 64 bit */
R_X86_64_PC32 = 2, /* PC relative 32 bit signed */
R_X86_64_GOT32 = 3, /* 32 bit GOT entry */
R_X86_64_PLT32 = 4, /* 32 bit PLT address */
R_X86_64_COPY = 5, /* Copy symbol at runtime */
R_X86_64_GLOB_DAT = 6, /* Create GOT entry */
R_X86_64_JUMP_SLOT = 7, /* Create PLT entry */
R_X86_64_RELATIVE = 8, /* Adjust by program base */
R_X86_64_GOTPCREL = 9, /* 32 bit signed PC relative offset to GOT */
R_X86_64_32 = 10, /* Direct 32 bit zero extended */
R_X86_64_32S = 11, /* Direct 32 bit sign extended */
R_X86_64_16 = 12, /* Direct 16 bit zero extended */
R_X86_64_PC16 = 13, /* 16 bit sign extended pc relative */
R_X86_64_8 = 14, /* Direct 8 bit sign extended */
R_X86_64_PC8 = 15, /* 8 bit sign extended pc relative */
R_X86_64_DTPMOD64 = 16, /* ID of module containing symbol */
R_X86_64_DTPOFF64 = 17, /* Offset in module's TLS block */
R_X86_64_TPOFF64 = 18, /* Offset in initial TLS block */
R_X86_64_TLSGD = 19, /* 32 bit signed PC relative offset to two GOT entries for GD symbol */
R_X86_64_TLSLD = 20, /* 32 bit signed PC relative offset to two GOT entries for LD symbol */
R_X86_64_DTPOFF32 = 21, /* Offset in TLS block */
R_X86_64_GOTTPOFF = 22, /* 32 bit signed PC relative offset to GOT entry for IE symbol */
R_X86_64_TPOFF32 = 23, /* Offset in initial TLS block */
R_X86_64_PC64 = 24, /* word64 S + A - P */
R_X86_64_GOTOFF64 = 25, /* word64 S + A - GOT */
R_X86_64_GOTPC32 = 26, /* word32 GOT + A - P */
R_X86_64_GOT64 = 27, /* word64 G + A */
R_X86_64_GOTPCREL64 = 28, /* word64 G + GOT - P + A */
R_X86_64_GOTPC64 = 29, /* word64 GOT - P + A */
R_X86_64_GOTPLT64 = 30, /* word64 G + A */
R_X86_64_PLTOFF64 = 31, /* word64 L - GOT + A */
R_X86_64_SIZE32 = 32, /* word32 Z + A */
R_X86_64_SIZE64 = 33, /* word64 Z + A */
R_X86_64_GOTPC32_TLSDESC= 34, /* word32 */
R_X86_64_TLSDESC_CALL = 35, /* none */
R_X86_64_TLSDESC = 36 /* word64?2 */
};
/*
@ -410,21 +410,21 @@ enum reloc64_type {
*/
typedef struct elf32_sym {
Elf32_Word st_name;
Elf32_Addr st_value;
Elf32_Word st_size;
unsigned char st_info;
unsigned char st_other;
Elf32_Half st_shndx;
Elf32_Word st_name;
Elf32_Addr st_value;
Elf32_Word st_size;
unsigned char st_info;
unsigned char st_other;
Elf32_Half st_shndx;
} Elf32_Sym;
typedef struct elf64_sym {
Elf64_Word st_name;
unsigned char st_info;
unsigned char st_other;
Elf64_Half st_shndx;
Elf64_Addr st_value;
Elf64_Xword st_size;
Elf64_Word st_name;
unsigned char st_info;
unsigned char st_other;
Elf64_Half st_shndx;
Elf64_Addr st_value;
Elf64_Xword st_size;
} Elf64_Sym;
/*
@ -432,37 +432,37 @@ typedef struct elf64_sym {
*/
typedef struct elf32_hdr {
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;
typedef struct elf64_hdr {
unsigned char e_ident[EI_NIDENT];
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
unsigned char e_ident[EI_NIDENT];
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
} Elf64_Ehdr;
/*
@ -470,25 +470,25 @@ typedef struct elf64_hdr {
*/
typedef struct elf32_phdr {
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
typedef struct elf64_phdr {
Elf64_Word p_type;
Elf64_Word p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
Elf64_Xword p_filesz;
Elf64_Xword p_memsz;
Elf64_Xword p_align;
Elf64_Word p_type;
Elf64_Word p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
Elf64_Xword p_filesz;
Elf64_Xword p_memsz;
Elf64_Xword p_align;
} Elf64_Phdr;
/*
@ -496,44 +496,44 @@ typedef struct elf64_phdr {
*/
typedef struct elf32_shdr {
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr;
typedef struct elf64_shdr {
Elf64_Word sh_name;
Elf64_Word sh_type;
Elf64_Xword sh_flags;
Elf64_Addr sh_addr;
Elf64_Off sh_offset;
Elf64_Xword sh_size;
Elf64_Word sh_link;
Elf64_Word sh_info;
Elf64_Xword sh_addralign;
Elf64_Xword sh_entsize;
Elf64_Word sh_name;
Elf64_Word sh_type;
Elf64_Xword sh_flags;
Elf64_Addr sh_addr;
Elf64_Off sh_offset;
Elf64_Xword sh_size;
Elf64_Word sh_link;
Elf64_Word sh_info;
Elf64_Xword sh_addralign;
Elf64_Xword sh_entsize;
} Elf64_Shdr;
/*
* Note header
*/
typedef struct elf32_note {
Elf32_Word n_namesz; /* Name size */
Elf32_Word n_descsz; /* Content size */
Elf32_Word n_type; /* Content type */
Elf32_Word n_namesz; /* Name size */
Elf32_Word n_descsz; /* Content size */
Elf32_Word n_type; /* Content type */
} Elf32_Nhdr;
typedef struct elf64_note {
Elf64_Word n_namesz; /* Name size */
Elf64_Word n_descsz; /* Content size */
Elf64_Word n_type; /* Content type */
Elf64_Word n_namesz; /* Name size */
Elf64_Word n_descsz; /* Content size */
Elf64_Word n_type; /* Content type */
} Elf64_Nhdr;
#endif /* OUTPUT_ELF_H */

282
output/macho.h Normal file
View file

@ -0,0 +1,282 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
#ifndef OUTPUT_MACHO_H
#define OUTPUT_MACHO_H
#include "compiler.h"
/* Magics */
#define MH_MAGIC 0xfeedface
#define MH_MAGIC_64 0xfeedfacf
/* File types */
#define MH_OBJECT 0x1
/* CPUs */
#define CPU_ARCH_MASK 0xff000000
#define CPU_ARCH_ABI64 0x01000000
#define CPU_TYPE_X86 7
#define CPU_TYPE_I386 CPU_TYPE_X86
#define CPU_TYPE_X86_64 (CPU_TYPE_X86 | CPU_ARCH_ABI64)
#define CPU_SUBTYPE_MASK 0xff000000
#define CPU_SUBTYPE_I386_ALL 3
/* Header flags */
#define MH_SUBSECTIONS_VIA_SYMBOLS 0x00002000
/* Load commands */
#define LC_SEGMENT 0x1
#define LC_SEGMENT_64 0x19
#define LC_SYMTAB 0x2
/* Symbol type bits */
#define N_STAB 0xe0
#define N_PEXT 0x10
#define N_TYPE 0x0e
#define N_EXT 0x01
/* To mask with N_TYPE */
#define N_UNDF 0x00
#define N_ABS 0x02
#define N_INDR 0x0a
#define N_PBUD 0x0c
#define N_SECT 0x0e
/* Section ordinals */
#define NO_SECT 0x00
#define MAX_SECT 0xff
/* Section bits */
#define SECTION_TYPE 0x000000ff
#define SECTION_ATTRIBUTES 0xffffff00
#define SECTION_ATTRIBUTES_USR 0xff000000
#define SECTION_ATTRIBUTES_SYS 0x00ffff00
#define S_REGULAR 0x00
#define S_ZEROFILL 0x01
#define S_CSTRING_LITERALS 0x02
#define S_4BYTE_LITERALS 0x03
#define S_8BYTE_LITERALS 0x04
#define S_LITERAL_POINTERS 0x05
#define S_NON_LAZY_SYMBOL_POINTERS 0x06
#define S_LAZY_SYMBOL_POINTERS 0x07
#define S_SYMBOL_STUBS 0x08
#define S_MOD_INIT_FUNC_POINTERS 0x09
#define S_MOD_TERM_FUNC_POINTERS 0x0a
#define S_COALESCED 0x0b
#define S_GB_ZEROFILL 0x0c
#define S_INTERPOSING 0x0d
#define S_16BYTE_LITERALS 0x0e
#define S_DTRACE_DOF 0x0f
#define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10
#define S_THREAD_LOCAL_REGULAR 0x11
#define S_THREAD_LOCAL_ZEROFILL 0x12
#define S_THREAD_LOCAL_VARIABLES 0x13
#define S_THREAD_LOCAL_VARIABLE_POINTERS 0x14
#define S_THREAD_LOCAL_INIT_FUNCTION_POINTERS 0x15
#define S_ATTR_PURE_INSTRUCTIONS 0x80000000
#define S_ATTR_NO_TOC 0x40000000
#define S_ATTR_STRIP_STATIC_SYMS 0x20000000
#define S_ATTR_NO_DEAD_STRIP 0x10000000
#define S_ATTR_LIVE_SUPPORT 0x08000000
#define S_ATTR_SELF_MODIFYING_CODE 0x04000000
#define S_ATTR_DEBUG 0x02000000
#define S_ATTR_SOME_INSTRUCTIONS 0x00000400
#define S_ATTR_EXT_RELOC 0x00000200
#define S_ATTR_LOC_RELOC 0x00000100
#define INDIRECT_SYMBOL_LOCAL 0x80000000
#define INDIRECT_SYMBOL_ABS 0x40000000
/* Relocation info type */
#define GENERIC_RELOC_VANILLA 0
#define GENERIC_RELOC_PAIR 1
#define GENERIC_RELOC_SECTDIFF 2
#define GENERIC_RELOC_PB_LA_PTR 3
#define GENERIC_RELOC_LOCAL_SECTDIFF 4
#define GENERIC_RELOC_TLV 5
#define X86_64_RELOC_UNSIGNED 0
#define X86_64_RELOC_SIGNED 1
#define X86_64_RELOC_BRANCH 2
#define X86_64_RELOC_GOT_LOAD 3
#define X86_64_RELOC_GOT 4
#define X86_64_RELOC_SUBTRACTOR 5
#define X86_64_RELOC_SIGNED_1 6
#define X86_64_RELOC_SIGNED_2 7
#define X86_64_RELOC_SIGNED_4 8
#define X86_64_RELOC_TLV 9
/* Relocation info */
#define R_ABS 0
#define R_SCATTERED 0x80000000
/* VM permission constants */
#define VM_PROT_NONE 0x00
#define VM_PROT_READ 0x01
#define VM_PROT_WRITE 0x02
#define VM_PROT_EXECUTE 0x04
typedef struct {
uint32_t magic;
uint32_t cputype;
uint32_t cpusubtype;
uint32_t filetype;
uint32_t ncmds;
uint32_t sizeofcmds;
uint32_t flags;
} macho_header_t;
typedef struct {
uint32_t magic;
uint32_t cputype;
uint32_t cpusubtype;
uint32_t filetype;
uint32_t ncmds;
uint32_t sizeofcmds;
uint32_t flags;
uint32_t reserved;
} macho_header_64_t;
typedef struct {
uint32_t cmd;
uint32_t cmdsize;
} macho_load_command_t;
typedef struct {
uint32_t cmd;
uint32_t cmdsize;
char segname[16];
uint32_t vmaddr;
uint32_t vmsize;
uint32_t fileoff;
uint32_t filesize;
uint32_t maxprot;
uint32_t initprot;
uint32_t nsects;
uint32_t flags;
} macho_segment_command_t;
typedef struct {
uint32_t cmd;
uint32_t cmdsize;
char segname[16];
uint64_t vmaddr;
uint64_t vmsize;
uint64_t fileoff;
uint64_t filesize;
uint32_t maxprot;
uint32_t initprot;
uint32_t nsects;
uint32_t flags;
} macho_segment_command_64_t;
typedef struct {
char sectname[16];
char segname[16];
uint32_t addr;
uint32_t size;
uint32_t offset;
uint32_t align;
uint32_t reloff;
uint32_t nreloc;
uint32_t flags;
uint32_t reserved1;
uint32_t reserved2;
} macho_section_t;
typedef struct {
char sectname[16];
char segname[16];
uint64_t addr;
uint64_t size;
uint32_t offset;
uint32_t align;
uint32_t reloff;
uint32_t nreloc;
uint32_t flags;
uint32_t reserved1;
uint32_t reserved2;
uint32_t reserved3;
} macho_section_64_t;
typedef struct {
uint32_t cmd;
uint32_t cmdsize;
uint32_t symoff;
uint32_t nsyms;
uint32_t stroff;
uint32_t strsize;
} macho_symtab_command_t;
typedef struct {
int32_t r_address;
union {
struct {
uint32_t r_symbolnum: 24,
r_pcrel: 1,
r_length: 2,
r_extern: 1,
r_type: 4;
} s;
uint32_t r_raw;
} u;
} macho_relocation_info_t;
typedef struct nlist_base {
uint32_t n_strx;
uint8_t n_type;
uint8_t n_sect;
uint16_t n_desc;
} macho_nlist_base_t;
typedef struct nlist {
uint32_t n_strx;
uint8_t n_type;
uint8_t n_sect;
int16_t n_desc;
uint32_t n_value;
} macho_nlist_t;
typedef struct {
uint32_t n_strx;
uint8_t n_type;
uint8_t n_sect;
uint16_t n_desc;
uint64_t n_value;
} macho_nlist_64_t;
#endif /* OUTPUT_MACHO_H */

View file

@ -137,14 +137,17 @@ static int32_t dbg_section_names(char *name, int pass, int *bits)
}
static int32_t dbg_herelabel(const char *name, enum label_type type,
int32_t oldseg, int32_t *subsection)
int32_t oldseg, int32_t *subsection,
bool *copyoffset)
{
int32_t newseg = oldseg;
if (subsections_via_symbols && type != LBL_LOCAL) {
newseg = *subsection;
if (newseg == NO_SEG)
if (newseg == NO_SEG) {
newseg = *subsection = seg_alloc();
*copyoffset = true; /* Minic MachO for now */
}
}
fprintf(ofile, "herelabel %s type %d (seg %08x) -> %08x\n",
name, type, oldseg, newseg);

View file

@ -2996,7 +2996,7 @@ static void dwarf_generate(void)
saa_write32(pinforel, 0);
saa_write32(pinfo,0); /* DW_AT_stmt_list */
saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1);
saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1);
saa_write16(pinfo,DW_LANG_Mips_Assembler);
saa_write8(pinfo,2); /* abbrviation number LEB128u */
saa_write32(pinforel, pinfo->datalen + 4);
@ -3035,7 +3035,7 @@ static void dwarf_generate(void)
saa_write32(pinforel, 0);
saa_write32(pinfo,0); /* DW_AT_stmt_list */
saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1);
saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1);
saa_write16(pinfo,DW_LANG_Mips_Assembler);
saa_write8(pinfo,2); /* abbrviation number LEB128u */
saa_write32(pinforel, pinfo->datalen + 4);
@ -3075,7 +3075,7 @@ static void dwarf_generate(void)
saa_write64(pinforel, 0);
saa_write32(pinfo,0); /* DW_AT_stmt_list */
saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1);
saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1);
saa_write16(pinfo,DW_LANG_Mips_Assembler);
saa_write8(pinfo,2); /* abbrviation number LEB128u */
saa_write64(pinforel, pinfo->datalen + 4);

View file

@ -893,7 +893,7 @@ static void ieee_write_file(void)
/*
* Write the NASM boast comment.
*/
ieee_putascii("CO0,%02X%s.\n", strlen(nasm_comment), nasm_comment);
ieee_putascii("CO0,%02X%s.\n", nasm_comment_len(), nasm_comment());
/*
* write processor-specific information

View file

@ -56,6 +56,7 @@
#include "outlib.h"
#include "ver.h"
#include "dwarf.h"
#include "macho.h"
#if defined(OF_MACHO) || defined(OF_MACHO64)
@ -72,45 +73,8 @@
#define MACHO_SECTCMD64_SIZE 80
#define MACHO_NLIST64_SIZE 16
/* Mach-O file header values */
#define MH_MAGIC 0xfeedface
#define MH_MAGIC_64 0xfeedfacf
#define CPU_TYPE_I386 7 /* x86 platform */
#define CPU_TYPE_X86_64 0x01000007 /* x86-64 platform */
#define CPU_SUBTYPE_I386_ALL 3 /* all-x86 compatible */
#define MH_OBJECT 0x1 /* object file */
/* Mach-O header flags */
#define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000
/* Mach-O load commands */
#define LC_SEGMENT 0x1 /* 32-bit segment load cmd */
#define LC_SEGMENT_64 0x19 /* 64-bit segment load cmd */
#define LC_SYMTAB 0x2 /* symbol table load command */
/* Mach-O relocations numbers */
/* Generic relocs, used by i386 Mach-O */
#define GENERIC_RELOC_VANILLA 0 /* Generic relocation */
#define GENERIC_RELOC_TLV 5 /* Thread local */
#define X86_64_RELOC_UNSIGNED 0 /* Absolute address */
#define X86_64_RELOC_SIGNED 1 /* Signed 32-bit disp */
#define X86_64_RELOC_BRANCH 2 /* CALL/JMP with 32-bit disp */
#define X86_64_RELOC_GOT_LOAD 3 /* MOVQ of GOT entry */
#define X86_64_RELOC_GOT 4 /* Different GOT entry */
#define X86_64_RELOC_SUBTRACTOR 5 /* Subtracting two symbols */
#define X86_64_RELOC_SIGNED_1 6 /* SIGNED with -1 addend */
#define X86_64_RELOC_SIGNED_2 7 /* SIGNED with -2 addend */
#define X86_64_RELOC_SIGNED_4 8 /* SIGNED with -4 addend */
#define X86_64_RELOC_TLV 9 /* Thread local */
/* Mach-O VM permission constants */
#define VM_PROT_NONE (0x00)
#define VM_PROT_READ (0x01)
#define VM_PROT_WRITE (0x02)
#define VM_PROT_EXECUTE (0x04)
#define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
#define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
@ -175,25 +139,6 @@ struct section {
uint32_t extreloc; /* external relocations */
};
#define SECTION_TYPE 0x000000ff /* section type mask */
#define S_REGULAR (0x0) /* standard section */
#define S_ZEROFILL (0x1) /* zerofill, in-memory only */
#define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */
#define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some
machine instructions */
#define S_ATTR_EXT_RELOC 0x00000200 /* section has external relocation entries */
#define S_ATTR_LOC_RELOC 0x00000100 /* section has local relocation entries */
#define S_ATTR_DEBUG 0x02000000
#define S_ATTR_SELF_MODIFYING_CODE 0x04000000
#define S_ATTR_LIVE_SUPPORT 0x08000000
#define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */
#define S_ATTR_STRIP_STATIC_SYMS 0x20000000
#define S_ATTR_NO_TOC 0x40000000
#define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section uses pure machine instructions */
#define S_ATTR_DEBUG 0x02000000 /* debug section */
#define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
/* fake section for absolute symbols, *not* part of the section linked list */
@ -214,10 +159,6 @@ struct reloc {
type:4; /* reloc type */
};
#define R_ABS 0 /* absolute relocation */
#define R_SCATTERED 0x80000000 /* reloc entry is scattered if
** highest bit == 1 */
struct symbol {
/* nasm internal data */
struct rbtree symv[2]; /* All/global symbol rbtrees; "key" contains the
@ -234,23 +175,8 @@ struct symbol {
uint16_t desc; /* for stab debugging, 0 for us */
};
/* symbol type bits */
#define N_EXT 0x01 /* global or external symbol */
#define N_PEXT 0x10 /* private external symbol */
#define N_UNDF 0x0 /* undefined symbol | n_sect == */
#define N_ABS 0x2 /* absolute symbol | NO_SECT */
#define N_SECT 0xe /* defined symbol, n_sect holds
** section number */
#define N_TYPE 0x0e /* type bit mask */
#define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
/* special section number values */
#define NO_SECT 0 /* no section, invalid */
#define MAX_SECT 255 /* maximum number of sections */
static struct section *sects, **sectstail, **sectstab;
static struct symbol *syms, **symstail;
static uint32_t nsyms;
@ -363,7 +289,7 @@ static struct section *get_section_by_index(int32_t index)
if (index < 0 || index >= SEG_ABS || (index & 1))
return NULL;
return (struct section *)raa_read(section_by_index, index >> 1);
return raa_read_ptr(section_by_index, index >> 1);
}
struct dir_list {
@ -495,7 +421,7 @@ static int64_t add_reloc(struct section *sect, int32_t section,
r = nasm_malloc(sizeof(struct reloc));
r->addr = sect->size & ~R_SCATTERED;
r->ext = 1;
adjust = bytes;
adjust = 0;
/* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
r->length = ilog2_32(bytes);
@ -514,7 +440,6 @@ static int64_t add_reloc(struct section *sect, int32_t section,
if (section == NO_SEG) {
/* absolute (can this even happen?) */
r->ext = 0;
r->snum = NO_SECT;
} else if (fi == NO_SECT) {
/* external */
r->snum = raa_read(extsyms, section);
@ -522,7 +447,6 @@ static int64_t add_reloc(struct section *sect, int32_t section,
/* local */
r->ext = 0;
r->snum = fi;
adjust = -sect->size;
}
break;
@ -531,40 +455,27 @@ static int64_t add_reloc(struct section *sect, int32_t section,
r->type = fmt.reloc_rel;
r->pcrel = 1;
if (section == NO_SEG) {
/* absolute - seems to produce garbage no matter what */
nasm_error(ERR_NONFATAL, "Mach-O does not support relative "
"references to absolute addresses");
goto bail;
#if 0
/* This "seems" to be how it ought to work... */
struct symbol *sym = macho_find_sym(&absolute_sect, offset,
false, false);
if (!sym)
goto bail;
sect->extreloc = 1;
r->snum = NO_SECT;
adjust = -sect->size;
#endif
/* may optionally be converted below by fmt.forcesym */
r->ext = 0;
} else if (fi == NO_SECT) {
/* external */
sect->extreloc = 1;
r->snum = raa_read(extsyms, section);
if (reltype == RL_BRANCH)
r->type = X86_64_RELOC_BRANCH;
else if (r->type == GENERIC_RELOC_VANILLA)
adjust = -sect->size;
} else {
/* local */
r->ext = 0;
r->snum = fi;
adjust = -sect->size;
if (reltype == RL_BRANCH)
r->type = X86_64_RELOC_BRANCH;
}
break;
case RL_SUB:
r->pcrel = 0;
case RL_SUB: /* obsolete */
nasm_error(ERR_WARNING, "relcation with subtraction"
"becomes to be obsolete");
r->ext = 0;
r->type = X86_64_RELOC_SUBTRACTOR;
break;
@ -581,34 +492,46 @@ static int64_t add_reloc(struct section *sect, int32_t section,
goto needsym;
needsym:
r->pcrel = 1;
r->pcrel = (fmt.ptrsize == 8 ? 1 : 0);
if (section == NO_SEG) {
nasm_error(ERR_NONFATAL, "Unsupported use of use of WRT");
goto bail;
} else if (fi == NO_SECT) {
/* external */
r->snum = raa_read(extsyms, section);
} else {
/* internal - does it really need to be global? */
struct symbol *sym = macho_find_sym(s, offset, true,
reltype != RL_TLV);
if (!sym)
/* internal - GOTPCREL doesn't need to be in global */
struct symbol *sym = macho_find_sym(s, offset,
false, /* reltype != RL_TLV */
true);
if (!sym) {
nasm_error(ERR_NONFATAL, "Symbol for WRT not found");
goto bail;
}
adjust -= sym->symv[0].key;
r->snum = sym->initial_snum;
}
break;
}
/* For 64-bit Mach-O, force a symbol reference if at all possible */
if (!r->ext && r->snum != NO_SECT && fmt.forcesym) {
struct symbol *sym = macho_find_sym(s, offset, false, false);
/*
* For 64-bit Mach-O, force a symbol reference if at all possible
* Allow for r->snum == R_ABS by searching absolute_sect
*/
if (!r->ext && fmt.forcesym) {
struct symbol *sym = macho_find_sym(s ? s : &absolute_sect,
offset, false, false);
if (sym) {
adjust = bytes - sym->symv[0].key;
adjust -= sym->symv[0].key;
r->snum = sym->initial_snum;
r->ext = 1;
}
}
if (r->pcrel)
adjust += ((r->ext && fmt.ptrsize == 8) ? bytes : -(int64_t)sect->size);
/* 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
** difference either way */
@ -661,6 +584,9 @@ static void macho_output(int32_t secto, const void *data,
if (is_bss && type != OUT_RESERVE) {
nasm_error(ERR_WARNING, "attempt to initialize memory in "
"BSS section: ignored");
/* FIXME */
nasm_error(ERR_WARNING, "section size may be negative"
"with address symbols");
s->size += realsize(type, size);
return;
}
@ -698,8 +624,11 @@ static void macho_output(int32_t secto, const void *data,
"Mach-O 64-bit format does not support"
" 32-bit absolute addresses");
} else {
add_reloc(s, section, addr, RL_ABS, asize);
addr += add_reloc(s, section, addr, RL_ABS, asize);
}
} else if (wrt == macho_tlvp_sect && fmt.ptrsize != 8 &&
asize == (int) fmt.ptrsize) {
addr += add_reloc(s, section, addr, RL_TLV, asize);
} else {
nasm_error(ERR_NONFATAL, "Mach-O format does not support"
" this use of WRT");
@ -785,7 +714,7 @@ static void macho_output(int32_t secto, const void *data,
reltype = RL_GOTLOAD;
}
}
} else if (wrt == macho_tlvp_sect) {
} else if (wrt == macho_tlvp_sect && fmt.ptrsize == 8) {
reltype = RL_TLV;
} else {
nasm_error(ERR_NONFATAL, "Mach-O format does not support"
@ -805,52 +734,69 @@ static void macho_output(int32_t secto, const void *data,
}
}
/* Translation table from traditional Unix section names to Mach-O */
static const struct sectmap {
const char *nasmsect;
const char *segname;
const char *sectname;
const uint32_t flags;
} sectmap[] = {
{".text", "__TEXT", "__text",
S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS},
{".data", "__DATA", "__data", S_REGULAR},
{".rodata", "__DATA", "__const", S_REGULAR},
{".bss", "__DATA", "__bss", S_ZEROFILL},
{".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG},
{".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG},
{".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG},
{".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG},
{NULL, NULL, NULL, 0}
};
#define S_CODE (S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS)
#define NO_TYPE S_NASM_TYPE_MASK
/* Translation table from traditional Unix section names to Mach-O */
static const struct macho_known_section {
const char *nasmsect;
const char *segname;
const char *sectname;
const uint32_t flags;
} known_sections[] = {
{ ".text", "__TEXT", "__text", S_CODE },
{ ".data", "__DATA", "__data", S_REGULAR },
{ ".rodata", "__DATA", "__const", S_REGULAR },
{ ".bss", "__DATA", "__bss", S_ZEROFILL },
{ ".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG },
{ ".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG },
{ ".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG },
{ ".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG },
};
/* Section type or attribute directives */
static const struct sect_attribs {
const char *name;
uint32_t flags;
static const struct macho_known_section_attr {
const char *name;
uint32_t flags;
} sect_attribs[] = {
{ "data", S_REGULAR },
{ "code", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS },
{ "mixed", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS },
{ "bss", S_ZEROFILL },
{ "zerofill", S_ZEROFILL },
{ "no_dead_strip", NO_TYPE|S_ATTR_NO_DEAD_STRIP },
{ "live_support", NO_TYPE|S_ATTR_LIVE_SUPPORT },
{ "strip_static_syms", NO_TYPE|S_ATTR_STRIP_STATIC_SYMS },
{ "debug", NO_TYPE|S_ATTR_DEBUG },
{ "data", S_REGULAR },
{ "code", S_CODE },
{ "mixed", S_REGULAR | S_ATTR_SOME_INSTRUCTIONS },
{ "bss", S_ZEROFILL },
{ "zerofill", S_ZEROFILL },
{ "no_dead_strip", NO_TYPE | S_ATTR_NO_DEAD_STRIP },
{ "live_support", NO_TYPE | S_ATTR_LIVE_SUPPORT },
{ "strip_static_syms", NO_TYPE | S_ATTR_STRIP_STATIC_SYMS },
{ "debug", NO_TYPE | S_ATTR_DEBUG },
{ NULL, 0 }
};
static const struct macho_known_section *
lookup_known_section(const char *name, bool by_sectname)
{
size_t i;
if (name && name[0]) {
for (i = 0; i < ARRAY_SIZE(known_sections); i++) {
const char *p = by_sectname ?
known_sections[i].sectname :
known_sections[i].nasmsect;
if (!strcmp(name, p))
return &known_sections[i];
}
}
return NULL;
}
static int32_t macho_section(char *name, int pass, int *bits)
{
const struct macho_known_section *known_section;
const struct macho_known_section_attr *sa;
char *sectionAttributes;
const struct sectmap *sm;
struct section *s;
const char *section, *segment;
uint32_t flags;
const struct sect_attribs *sa;
char *currentAttribute;
char *comma;
@ -893,29 +839,23 @@ static int32_t macho_section(char *name, int pass, int *bits)
nasm_error(ERR_NONFATAL, "section name %s too long\n", section);
}
if (!strcmp(section, "__text")) {
flags = S_REGULAR | S_ATTR_SOME_INSTRUCTIONS |
S_ATTR_PURE_INSTRUCTIONS;
} else if (!strcmp(section, "__bss")) {
flags = S_ZEROFILL;
} else {
flags = S_REGULAR;
}
known_section = lookup_known_section(section, true);
if (known_section)
flags = known_section->flags;
else
flags = S_REGULAR;
} else {
for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
/* make lookup into section name translation table */
if (!strcmp(name, sm->nasmsect)) {
segment = sm->segname;
section = sm->sectname;
flags = sm->flags;
goto found;
}
}
nasm_error(ERR_NONFATAL, "unknown section name\n");
return NO_SEG;
known_section = lookup_known_section(name, false);
if (!known_section) {
nasm_error(ERR_NONFATAL, "unknown section name %s\n", name);
return NO_SEG;
}
segment = known_section->segname;
section = known_section->sectname;
flags = known_section->flags;
}
found:
/* try to find section with that name, or create it */
s = find_or_add_section(segment, section);
new_seg = is_new_section(s);
@ -1008,7 +948,8 @@ static int32_t macho_section(char *name, int pass, int *bits)
}
static int32_t macho_herelabel(const char *name, enum label_type type,
int32_t section, int32_t *subsection)
int32_t section, int32_t *subsection,
bool *copyoffset)
{
struct section *s;
int32_t subsec;
@ -1033,6 +974,7 @@ static int32_t macho_herelabel(const char *name, enum label_type type,
}
s->subsection = subsec;
*copyoffset = true; /* Maintain previous offset */
return subsec;
}
@ -1045,8 +987,8 @@ static void macho_symdef(char *name, int32_t section, int64_t offset,
#if defined(DEBUG) && DEBUG>2
nasm_error(ERR_DEBUG,
" macho_symdef: %s, sec=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
name, section, offset, is_global, special);
" macho_symdef: %s, pass0=%d, passn=%"PRId64", sec=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
name, pass0, passn, section, offset, is_global, special);
#endif
if (is_global == 3) {
@ -1109,6 +1051,9 @@ static void macho_symdef(char *name, int32_t section, int64_t offset,
special_used = true;
}
/* track the initially allocated symbol number for use in future fix-ups */
sym->initial_snum = nsyms;
if (section == NO_SEG) {
/* symbols in no section get absolute */
sym->type |= N_ABS;
@ -1123,9 +1068,6 @@ static void macho_symdef(char *name, int32_t section, int64_t offset,
/* get the in-file index of the section the symbol was defined in */
sym->sect = s ? s->fileindex : NO_SECT;
/* track the initially allocated symbol number for use in future fix-ups */
sym->initial_snum = nsyms;
if (!s) {
/* remember symbol number of references to external
** symbols, this works because every external symbol gets
@ -1874,6 +1816,9 @@ macho_pragma(const struct pragma *pragma)
if (real)
head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS;
/* Jmp-match optimization conflicts */
optimizing.flag |= OPTIM_DISABLE_JMP_MATCH;
return DIRR_OK;
case D_NO_DEAD_STRIP:
@ -2005,7 +1950,7 @@ static void macho_dbg_generate(void)
nasm_assert(p_section != NULL);
producer_str_offset = 0;
module_str_offset = dir_str_offset = saa_wcstring(p_str, nasm_signature);
module_str_offset = dir_str_offset = saa_wcstring(p_str, nasm_signature());
dir_str_offset += saa_wcstring(p_str, cur_file);
saa_wcstring(p_str, cur_dir);

View file

@ -1380,9 +1380,10 @@ static int32_t obj_segment(char *name, int pass, int *bits)
attrs++;
}
obj_idx = 1;
for (seg = seghead; seg; seg = seg->next) {
obj_idx++;
for (seg = seghead, obj_idx = 1; ; seg = seg->next, obj_idx++) {
if (!seg)
break;
if (!strcmp(seg->name, name)) {
if (attrs > 0 && pass == 1)
nasm_error(ERR_WARNING, "segment attributes specified on"
@ -1403,7 +1404,7 @@ static int32_t obj_segment(char *name, int pass, int *bits)
seg->obj_index = obj_idx;
seg->grp = NULL;
any_segs = true;
seg->name = NULL;
seg->name = nasm_strdup(name);
seg->currentpos = 0;
seg->align = 1; /* default */
seg->use32 = false; /* default */
@ -1964,7 +1965,7 @@ static void obj_write_file(void)
struct ExpDef *export;
int lname_idx;
ObjRecord *orp;
const StrList *depfile;
const struct strlist_entry *depfile;
const bool debuginfo = (dfmt == &borland_debug_form);
/*
@ -1980,14 +1981,14 @@ static void obj_write_file(void)
*/
orp->type = COMENT;
obj_rword(orp, dTRANSL);
obj_name(orp, nasm_comment);
obj_name(orp, nasm_comment());
obj_emit2(orp);
/*
* Output file dependency information
*/
if (!obj_nodepend) {
list_for_each(depfile, depend_list) {
if (!obj_nodepend && depend_list) {
list_for_each(depfile, depend_list->head) {
uint32_t ts;
ts = obj_file_timestamp(depfile->str);

View file

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2010 The NASM Authors - All Rights Reserved
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@ -42,103 +42,109 @@
/* offsets */
enum stab_offsets {
STAB_strdxoff = 0,
STAB_typeoff = 4,
STAB_otheroff = 5,
STAB_descoff = 6,
STAB_valoff = 8,
STAB_stabsize = 12
STAB_strdxoff = 0,
STAB_typeoff = 4,
STAB_otheroff = 5,
STAB_descoff = 6,
STAB_valoff = 8,
STAB_stabsize = 12
};
/* stab/non-stab types */
enum stab_types {
N_UNDF = 0x00,
N_ABS = 0x02,
N_ABS_EXT = 0x03,
N_TEXT = 0x04,
N_TEXT_EXT = 0x05,
N_DATA = 0x06,
N_DATA_EXT = 0x07,
N_BSS = 0x08,
N_BSS_EXT = 0x09,
N_FN_SEQ = 0x0c,
N_INDR = 0x0a,
N_COMM = 0x12,
N_SETA = 0x14,
N_SETA_EXT = 0x15,
N_SETT = 0x16,
N_SETT_EXT = 0x17,
N_SETD = 0x18,
N_SETD_EXT = 0x19,
N_SETB = 0x1a,
N_SETB_EXT = 0x1b,
N_SETV = 0x1c,
N_SETV_EXT = 0x1d,
N_WARNING = 0x1e,
N_FN = 0x1f,
N_GSYM = 0x20,
N_FNAME = 0x22,
N_FUN = 0x24,
N_STSYM = 0x26,
N_LCSYM = 0x28,
N_MAIN = 0x2a,
N_ROSYM = 0x2c,
N_BNSYM = 0x2e,
N_PC = 0x30,
N_NSYMS = 0x32,
N_NOMAP = 0x34,
N_OBJ = 0x38,
N_OPT = 0x3c,
N_RSYM = 0x40,
N_M2C = 0x42,
N_SLINE = 0x44,
N_DSLINE = 0x46,
N_BSLINE = 0x48,
N_BROWS = 0x48,
N_DEFD = 0x4a,
N_FLINE = 0x4c,
N_ENSYM = 0x4e,
N_EHDECL = 0x50,
N_MOD2 = 0x50,
N_CATCH = 0x54,
N_SSYM = 0x60,
N_ENDM = 0x62,
N_SO = 0x64, /* ID for main source file */
N_OSO = 0x66,
N_ALIAS = 0x6c,
N_LSYM = 0x80,
N_BINCL = 0x82,
N_SOL = 0x84, /* ID for sub-source file */
N_PSYM = 0xa0,
N_EINCL = 0xa2,
N_ENTRY = 0xa4,
N_LBRAC = 0xc0,
N_EXCL = 0xc2,
N_SCOPE = 0xc4,
N_PATCH = 0xd0,
N_RBRAC = 0xe0,
N_BCOMM = 0xe2,
N_ECOMM = 0xe4,
N_ECOML = 0xe8,
N_WITH = 0xea,
N_NBTEXT = 0xf0,
N_NBDATA = 0xf2,
N_NBBSS = 0xf4,
N_NBSTS = 0xf6,
N_NBLCS = 0xf8,
N_LENG = 0xfe
N_UNDF = 0x00, /* Undefined symbol */
N_EXT = 0x01, /* External symbol */
N_ABS = 0x02, /* Absolute symbol */
N_ABS_EXT = 0x03, /* Absolute external symbol */
N_TEXT = 0x04, /* Symbol in text segment */
N_TEXT_EXT = 0x05, /* Symbol in external text segment */
N_DATA = 0x06,
N_DATA_EXT = 0x07,
N_BSS = 0x08,
N_BSS_EXT = 0x09,
N_INDR = 0x0a,
N_FN_SEQ = 0x0c, /* N_FN from Sequent compilers */
N_WEAKU = 0x0d, /* Weak undefined symbol */
N_WEAKA = 0x0e, /* Weak absolute symbl */
N_WEAKT = 0x0f, /* Weak text symbol */
N_WEAKD = 0x10, /* Weak data symbol */
N_WEAKB = 0x11, /* Weak bss symbol */
N_COMM = 0x12, /* Common symbol */
N_SETA = 0x14, /* Absolute set element symbol */
N_SETA_EXT = 0x15,
N_SETT = 0x16, /* Text set element symbol */
N_SETT_EXT = 0x17,
N_SETD = 0x18, /* Data set element symbol */
N_SETD_EXT = 0x19,
N_SETB = 0x1a, /* BSS set element symbol */
N_SETB_EXT = 0x1b,
N_SETV = 0x1c, /* Pointer to set vector in data area */
N_SETV_EXT = 0x1d,
N_WARNING = 0x1e, /* Warning symbol */
N_FN = 0x1f, /* Filename of .o file */
N_GSYM = 0x20, /* Global variable */
N_FNAME = 0x22, /* Function name for BSD Fortran */
N_FUN = 0x24, /* Function name or text segment variable for C */
N_STSYM = 0x26, /* Data-segment variable with internal linkage */
N_LCSYM = 0x28, /* BSS-segment variable with internal linkage */
N_MAIN = 0x2a, /* Name of main routine */
N_ROSYM = 0x2c, /* Read-only data symbols */
N_BNSYM = 0x2e, /* The beginning of a relocatable function block */
N_PC = 0x30, /* Global symbol in Pascal */
N_NSYMS = 0x32, /* Number of symbols */
N_NOMAP = 0x34, /* No DST map for sym */
N_OBJ = 0x38, /* Like N_SO, but for the object file */
N_OPT = 0x3c, /* Options for the debugger */
N_RSYM = 0x40, /* Register variable */
N_M2C = 0x42, /* Modula-2 compilation unit */
N_SLINE = 0x44, /* Line number in text segment */
N_DSLINE = 0x46, /* Line number in data segment */
N_BSLINE = 0x48, /* Line number in bss segment */
N_BROWS = 0x48, /* Sun's source-code browser stabs */
N_DEFD = 0x4a, /* GNU Modula-2 definition module dependency */
N_FLINE = 0x4c, /* Function start/body/end line numbers */
N_ENSYM = 0x4e, /* This tells the end of a relocatable function */
N_EHDECL = 0x50, /* GNU C++ exception variable */
N_MOD2 = 0x50, /* Modula2 info "for imc" */
N_CATCH = 0x54, /* GNU C++ `catch' clause */
N_SSYM = 0x60, /* Structure or union element */
N_ENDM = 0x62, /* Last stab emitted for module */
N_SO = 0x64, /* ID for main source file */
N_OSO = 0x66, /* Apple: This is the stab that associated the .o file */
N_ALIAS = 0x6c, /* SunPro F77: Name of alias */
N_LSYM = 0x80, /* Automatic variable in the stack */
N_BINCL = 0x82, /* Beginning of an include file */
N_SOL = 0x84, /* ID for sub-source file */
N_PSYM = 0xa0, /* Parameter variable */
N_EINCL = 0xa2, /* End of an include file */
N_ENTRY = 0xa4, /* Alternate entry point */
N_LBRAC = 0xc0, /* Beginning of lexical block */
N_EXCL = 0xc2, /* Place holder for deleted include file */
N_SCOPE = 0xc4, /* Modula-2 scope information */
N_PATCH = 0xd0, /* Solaris2: Patch Run Time Checker */
N_RBRAC = 0xe0, /* End of a lexical block */
N_BCOMM = 0xe2, /* Begin named common block */
N_ECOMM = 0xe4, /* End named common block */
N_ECOML = 0xe8, /* Member of a common block */
N_WITH = 0xea, /* Solaris2: Pascal "with" statement */
N_NBTEXT = 0xf0,
N_NBDATA = 0xf2,
N_NBBSS = 0xf4,
N_NBSTS = 0xf6,
N_NBLCS = 0xf8,
N_LENG = 0xfe /* Second symbol entry whih a length-value for the preceding entry */
};
enum stab_source_file {
N_SO_AS = 0x01,
N_SO_C = 0x02,
N_SO_ANSI_C = 0x03,
N_SO_CC = 0x04,
N_SO_FORTRAN = 0x05,
N_SO_PASCAL = 0x06,
N_SO_FORTRAN90 = 0x07,
N_SO_OBJC = 0x32,
N_SO_OBJCPLUS = 0x33
N_SO_AS = 0x01,
N_SO_C = 0x02,
N_SO_ANSI_C = 0x03,
N_SO_CC = 0x04,
N_SO_FORTRAN = 0x05,
N_SO_PASCAL = 0x06,
N_SO_FORTRAN90 = 0x07,
N_SO_OBJC = 0x32,
N_SO_OBJCPLUS = 0x33
};
#endif /* STABS_H_ */

View file

@ -12,46 +12,46 @@ $(NASM):
$(MAKE) -C ..
%.bin: %.asm $(NASMDEP)
$(NASM) $(NASMOPT) -f bin -o $@ -MD $@.dep -l $*.lst $<
$(NASM) $(NASMOPT) -f bin -o $@ -MD $@.dep -l $@.lst $<
%.ith: %.asm $(NASMDEP)
$(NASM) $(NASMOPT) -f ith -o $@ -MD $@.dep -l $*.lst $<
$(NASM) $(NASMOPT) -f ith -o $@ -MD $@.dep -l $@.lst $<
%.srec: %.asm $(NASMDEP)
$(NASM) $(NASMOPT) -f srec -o $@ -MD $@.dep -l $*.lst $<
$(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 -o $@ -MD $@.dep -l $@.lst $<
%.o64: %.asm $(NASMDEP)
$(NASM) $(NASMOPT) -f elf64 -o $@ -MD $@.dep -l $*.lst $<
$(NASM) $(NASMOPT) -f elf64 -o $@ -MD $@.dep -l $@.lst $<
%.obj: %.asm $(NASMDEP)
$(NASM) $(NASMOPT) -f obj -o $@ -MD $@.dep -l $*.lst $<
$(NASM) $(NASMOPT) -f obj -o $@ -MD $@.dep -l $@.lst $<
%.rdf: %.asm $(NASMDEP)
$(NASM) $(NASMOPT) -f rdf -o $@ -MD $@.dep -l $*.lst $<
$(NASM) $(NASMOPT) -f rdf -o $@ -MD $@.dep -l $@.lst $<
%.od: %.obj ../misc/omfdump
../misc/omfdump $< > $@
%.coff: %.asm $(NASMDEP)
$(NASM) $(NASMOPT) -f coff -o $@ -MD $@.dep -l $*.lst $<
$(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 -o $@ -MD $@.dep -l $@.lst $<
%.win64: %.asm $(NASMDEP)
$(NASM) $(NASMOPT) -f win64 -o $@ -MD $@.dep -l $*.lst $<
$(NASM) $(NASMOPT) -f win64 -o $@ -MD $@.dep -l $@.lst $<
%.mo32: %.asm $(NASMDEP)
$(NASM) $(NASMOPT) -f macho32 -o $@ -MD $@.dep -l $*.lst $<
$(NASM) $(NASMOPT) -f macho32 -o $@ -MD $@.dep -l $@.lst $<
%.mo64: %.asm $(NASMDEP)
$(NASM) $(NASMOPT) -f macho64 -o $@ -MD $@.dep -l $*.lst $<
$(NASM) $(NASMOPT) -f macho64 -o $@ -MD $@.dep -l $@.lst $<
%.dbg: %.asm $(NASMDEP)
$(NASM) $(NASMOPT) -f dbg -o $@ -MD $@.dep -l $*.lst $<
$(NASM) $(NASMOPT) -f dbg -o $@ -MD $@.dep -l $@.lst $<
%.asm: %.pl
$(PERL) $< > $@
@ -83,7 +83,7 @@ spotless: clean
# Test for ELF32 shared libraries; assumes an x86 Linux system
#
elfso.o: elfso.asm $(NASMDEP)
$(NASM) $(NASMOPT) -f elf32 -F stabs -o $@ -MD $@.dep -l $*.lst $<
$(NASM) $(NASMOPT) -f elf32 -F stabs -o $@ -MD $@.dep -l $@.lst $<
elfso.so: elfso.o
$(LD) -m elf_i386 -shared -o $@ -MD $@.dep $<
@ -96,7 +96,7 @@ elftest: elftest.c elfso.so
# Test for ELF64 shared libraries; assumes an x86-64 Linux system
#
elf64so.o: elf64so.asm $(NASMDEP)
$(NASM) $(NASMOPT) -f elf64 -F dwarf -o $@ -MD $@.dep -l $*.lst $<
$(NASM) $(NASMOPT) -f elf64 -F dwarf -o $@ -MD $@.dep -l $@.lst $<
elf64so.so: elf64so.o
$(LD) -shared -o $@ -MD $@.dep $<

View file

@ -1,5 +1,7 @@
;Testname=bin; Arguments=-fbin -oabsolute.bin; Files=stdout stderr absolute.bin
%ifmacro org
org 7c00h
%endif
init_foo:
jmp init_bar
nop
@ -15,7 +17,7 @@ init_foo:
nop
nop
nop
init_bar:
mov [b1],dl
mov [b2],edx
@ -33,8 +35,7 @@ init_bar:
nop
nop
ret
absolute init_bar+7
b1: resb 1
b2: resd 6

25
test/ctxlocal.asm Normal file
View file

@ -0,0 +1,25 @@
;;
;; Test of context-local labels
;;
bits 64
extern everywhere ; Test of extern -> global promotion, too
extern tjosan
here:
jz .there
%push foo
jo %$mordor
hlt
%$mordor:
nop
%pop
.there:
ret
everywhere:
ret
global everywhere
tjosan:
ret

10
test/elf_visibility.asm Normal file
View file

@ -0,0 +1,10 @@
global foo
global foo_hidden:function hidden
SECTION .text align=16
foo:
foo_hidden:
foo_label:
ret

View file

@ -4,9 +4,9 @@
; Test of Mach-O subsection_by_symbol
;
%pragma output subsections_via_symbols
%pragma asm gprefix _
%pragma asm lprefix L_
%pragma macho subsections_via_symbols
%pragma macho gprefix _
%pragma macho lprefix L.
bits 32

12
test/v4.asm Normal file
View file

@ -0,0 +1,12 @@
bits 64
v4fmaddps zmm0,zmm1+3,[rax]
v4fnmaddps zmm2,zmm3,[rax]
v4fmaddss zmm4,zmm5+3,[rax]
v4fnmaddss zmm6,zmm7+3,[rax]
v4dpwssds zmm8,zmm9,[rax]
v4dpwssd zmm10,zmm11+3,[rax]
v4dpwssd zmm10+0,zmm11+3,[rax]
; v4dpwssd zmm10+1,zmm11+3,[rax]
; v4dpwssd zmm10,zmm11+4,[rax]
; v4dpwssd zmm10,zmm11+7,[rax]

View file

@ -51,6 +51,9 @@ $barrier = "#-- Everything below is generated by mkdep.pl - do not edit --#\n";
# This converts from filenames to full pathnames for our dependencies
%dep_path = {};
# List of files that cannot be found; these *must* be excluded
@must_exclude = ();
#
# Scan files for dependencies
#
@ -70,7 +73,8 @@ sub scandeps($) {
if ( $line =~ /^\s*\#\s*include\s+\"(.*)\"\s*$/ ) {
my $nf = $1;
if (!defined($dep_path{$nf})) {
die "$0: cannot determine path for dependency: $file -> $nf\n";
push(@must_exclude, $nf);
next;
}
$nf = $dep_path{$nf};
$mdeps{$nf}++;
@ -138,7 +142,7 @@ sub _insert_deps($$) {
my $selfrule = 0;
my $do_external = 0;
my $maxline = 78; # Seems like a reasonable default
my @exclude = (); # Don't exclude anything
my %exclude = (); # Don't exclude anything
my @genhdrs = ();
my $external = undef;
my $raw_output = 0;
@ -165,7 +169,7 @@ sub _insert_deps($$) {
} elsif ( $parm eq 'continuation' ) {
$cont = $val;
} elsif ( $parm eq 'exclude' ) {
@exclude = split(/\,/, $val);
$excludes{$val}++;
} elsif ( $parm eq 'include-command' ) {
$include_command = $val;
} elsif ( $parm eq 'external' ) {
@ -201,10 +205,6 @@ sub _insert_deps($$) {
}
my $e;
my %do_exclude = ();
foreach $e (@exclude) {
$do_exclude{$e} = 1;
}
foreach my $dfile ($external, sort(keys(%deps)) ) {
my $ofile;
@ -222,7 +222,7 @@ sub _insert_deps($$) {
my $len = length($ofile);
print $out $ofile;
foreach my $dep (@deps) {
unless ($do_exclude{$dep}) {
unless ($excludes{$dep}) {
my $str = convert_file($dep, $sep);
my $sl = length($str)+1;
if ( $len+$sl > $maxline-2 ) {

104
travis/README.md Normal file
View file

@ -0,0 +1,104 @@
Testing NASM
============
We use [Travis CI](https://travis-ci.org/) service to execute NASM tests,
which basically prepares the environment and runs our `nasm-t.py` script.
The script scans a testing directory for `*.json` test descriptor files
and runs test by descriptor content.
Test engine
-----------
`nasm-t.py` script is a simple test engine written by Python3 language
which allows either execute a single test or run them all in a sequence.
A typical test case processed by the following steps:
- a test descriptor get parsed to figure out which arguments
are to be provided into the NASM command line;
- invoke the NASM with arguments;
- compare generated files with precompiled templates.
`nasm-t.py` supports the following commands:
- `list`: to list all test cases
- `run`: to run test cases
- `update`: to update precompiled templates
Use `nasm-t.py -h` command to get the detailed description of every option.
Test descriptor file
--------------------
A descriptor file should provide enough information how to run the NASM
itself and which output files or streams to compare with predefined ones.
We use `JSON` format with the following fields:
- `description`: a short description of a test which is shown to
a user when tests are listed;
- `id`: descriptor internal name to use with `ref` field;
- `ref`: a reference to `id` from where settings should be
copied, it is convenient when say only `option` is different
while the rest of the fields are the same;
- `format`: NASM output format to use (`bin`,`elf` and etc);
- `source`: is a source file name to compile, this file must
be shipped together with descriptor file itself;
- `option`: an additional option passed to the command line;
- `update`: a trigger to skip updating targets when running
an update procedure;
- `target`: an array of targets which the test engine should
check once compilation finished:
- `stderr`: a file containing *stderr* stream output to check;
- `stdout`: a file containing *stdout* stream output to check;
- `output`: a file containing compiled result to check, in other
words it is a name passed as `-o` option to the compiler.
Examples
--------
A simple test where no additional options are used, simply compile
`absolute.asm` file with `bin` format for output, then compare
produced `absolute.bin` file with precompiled `absolute.bin.dest`.
```json
{
"description": "Check absolute addressing",
"format": "bin",
"source": "absolute.asm",
"target": [
{ "output": "absolute.bin" }
]
}
```
A slightly complex example: compile one source file with different optimization
options and all results must be the same. To not write three descriptors
we assign `id` to the first one and use `ref` term to copy settings.
Also, it is expected that `stderr` stream will not be empty but carry some
warnings to compare.
```json
[
{
"description": "Check 64-bit addressing (-Ox)",
"id": "addr64x",
"format": "bin",
"source": "addr64x.asm",
"option": "-Ox",
"target": [
{ "output": "addr64x.bin" },
{ "stderr": "addr64x.stderr" }
]
},
{
"description": "Check 64-bit addressing (-O1)",
"ref": "addr64x",
"option": "-O1",
"update": "false"
},
{
"description": "Check 64-bit addressing (-O0)",
"ref": "addr64x",
"option": "-O0",
"update": "false"
}
]
```

425
travis/nasm-t.py Executable file
View file

@ -0,0 +1,425 @@
#!/usr/bin/python3
import subprocess
import argparse
import difflib
import filecmp
import fnmatch
import json
import sys
import re
import os
fmtr_class = argparse.ArgumentDefaultsHelpFormatter
parser = argparse.ArgumentParser(prog = 'nasm-t.py',
formatter_class=fmtr_class)
parser.add_argument('-d', '--directory',
dest = 'dir', default = './travis/test',
help = 'Directory with tests')
parser.add_argument('--nasm',
dest = 'nasm', default = './nasm',
help = 'Nasm executable to use')
parser.add_argument('--hexdump',
dest = 'hexdump', default = '/usr/bin/hexdump',
help = 'Hexdump executable to use')
sp = parser.add_subparsers(dest = 'cmd')
for cmd in ['run']:
spp = sp.add_parser(cmd, help = 'Run test cases')
spp.add_argument('-t', '--test',
dest = 'test',
help = 'Run the selected test only',
required = False)
for cmd in ['list']:
spp = sp.add_parser(cmd, help = 'List test cases')
for cmd in ['update']:
spp = sp.add_parser(cmd, help = 'Update test cases with new compiler')
spp.add_argument('-t', '--test',
dest = 'test',
help = 'Update the selected test only',
required = False)
args = parser.parse_args()
if args.cmd == None:
parser.print_help()
sys.exit(1)
def read_stdfile(path):
with open(path, "rb") as f:
data = f.read().decode("utf-8").strip("\n")
f.close()
return data
#
# Check if descriptor has mandatory fields
def is_valid_desc(desc):
if desc == None:
return False
if 'description' not in desc:
return False
if desc['description'] == "":
return False
return True
#
# Expand ref/id in descriptors array
def expand_templates(desc_array):
desc_ids = { }
for d in desc_array:
if 'id' in d:
desc_ids[d['id']] = d
for i, d in enumerate(desc_array):
if 'ref' in d and d['ref'] in desc_ids:
ref = desc_ids[d['ref']]
own = d.copy()
desc_array[i] = ref.copy()
for k, v in own.items():
desc_array[i][k] = v
del desc_array[i]['id']
return desc_array
def prepare_desc(desc, basedir, name, path):
if not is_valid_desc(desc):
return False
#
# Put private fields
desc['_base-dir'] = basedir
desc['_json-file'] = name
desc['_json-path'] = path
desc['_test-name'] = basedir + os.sep + name[:-5]
#
# If no target provided never update
if 'target' not in desc:
desc['target'] = []
desc['update'] = 'false'
#
# Which code to expect when nasm finishes
desc['_wait'] = 0
if 'error' in desc:
if desc['error'] == 'expected':
desc['_wait'] = 1
#
# Walk over targets and generate match templates
# if were not provided yet
for d in desc['target']:
if 'output' in d and not 'match' in d:
d['match'] = d['output'] + ".t"
return True
def read_json(path):
desc = None
try:
with open(path, "rb") as f:
try:
desc = json.loads(f.read().decode("utf-8").strip("\n"))
except:
desc = None
finally:
f.close()
except:
pass
return desc
def read_desc(basedir, name):
path = basedir + os.sep + name
desc = read_json(path)
desc_array = []
if type(desc) == dict:
if prepare_desc(desc, basedir, name, path) == True:
desc_array += [desc]
elif type(desc) == list:
expand_templates(desc)
for de in desc:
if prepare_desc(de, basedir, name, path) == True:
desc_array += [de]
return desc_array
def collect_test_desc_from_file(path):
if not fnmatch.fnmatch(path, '*.json'):
path += '.json'
basedir = os.path.dirname(path)
filename = os.path.basename(path)
return read_desc(basedir, filename)
def collect_test_desc_from_dir(basedir):
desc_array = []
if os.path.isdir(basedir):
for filename in os.listdir(basedir):
if os.path.isdir(basedir + os.sep + filename):
desc_array += collect_test_desc_from_dir(basedir + os.sep + filename)
elif fnmatch.fnmatch(filename, '*.json'):
desc = read_desc(basedir, filename)
if desc == None:
continue
desc_array += desc
desc_array.sort(key=lambda x: x['_test-name'])
return desc_array
if args.cmd == 'list':
fmt_entry = '%-32s %s'
desc_array = collect_test_desc_from_dir(args.dir)
print(fmt_entry % ('Name', 'Description'))
for desc in desc_array:
print(fmt_entry % (desc['_test-name'], desc['description']))
def test_abort(test, message):
print("\t%s: %s" % (test, message))
print("=== Test %s ABORT ===" % (test))
sys.exit(1)
return False
def test_fail(test, message):
print("\t%s: %s" % (test, message))
print("=== Test %s FAIL ===" % (test))
return False
def test_skip(test, message):
print("\t%s: %s" % (test, message))
print("=== Test %s SKIP ===" % (test))
return True
def test_over(test):
print("=== Test %s ERROR OVER ===" % (test))
return True
def test_pass(test):
print("=== Test %s PASS ===" % (test))
return True
def test_updated(test):
print("=== Test %s UPDATED ===" % (test))
return True
def run_hexdump(path):
p = subprocess.Popen([args.hexdump, "-C", path],
stdout = subprocess.PIPE,
close_fds = True)
if p.wait() == 0:
return p
return None
def show_std(stdname, data):
print("\t--- %s" % (stdname))
for i in data.split("\n"):
print("\t%s" % i)
print("\t---")
def cmp_std(test, data_name, data, match):
match_data = read_stdfile(match)
if match_data == None:
return test_fail(test, "Can't read " + match)
if data != match_data:
print("\t--- %s" % (data_name))
for i in data.split("\n"):
print("\t%s" % i)
print("\t--- %s" % (match))
for i in match_data.split("\n"):
print("\t%s" % i)
diff = difflib.unified_diff(data.split("\n"), match_data.split("\n"),
fromfile = data_name, tofile = match)
for i in diff:
print("\t%s" % i.strip("\n"))
print("\t---")
return False
return True
def show_diff(test, patha, pathb):
pa = run_hexdump(patha)
pb = run_hexdump(pathb)
if pa == None or pb == None:
return test_fail(test, "Can't create dumps")
sa = pa.stdout.read().decode("utf-8").strip("\n")
sb = pb.stdout.read().decode("utf-8").strip("\n")
print("\t--- hexdump %s" % (patha))
for i in sa.split("\n"):
print("\t%s" % i)
print("\t--- hexdump %s" % (pathb))
for i in sb.split("\n"):
print("\t%s" % i)
pa.stdout.close()
pb.stdout.close()
diff = difflib.unified_diff(sa.split("\n"), sb.split("\n"),
fromfile = patha, tofile = pathb)
for i in diff:
print("\t%s" % i.strip("\n"))
print("\t---")
return True
def prepare_run_opts(desc):
opts = []
if 'format' in desc:
opts += ['-f', desc['format']]
if 'option' in desc:
opts += desc['option'].split(" ")
for t in desc['target']:
if 'output' in t:
if 'option' in t:
opts += t['option'].split(" ") + [desc['_base-dir'] + os.sep + t['output']]
else:
opts += ['-o', desc['_base-dir'] + os.sep + t['output']]
if 'stdout' in t or 'stderr' in t:
if 'option' in t:
opts += t['option'].split(" ")
if 'source' in desc:
opts += [desc['_base-dir'] + os.sep + desc['source']]
return opts
def exec_nasm(desc):
print("\tProcessing %s" % (desc['_test-name']))
opts = [args.nasm] + prepare_run_opts(desc)
nasm_env = os.environ.copy()
nasm_env['NASM_TEST_RUN'] = 'y'
desc_env = desc.get('environ')
if desc_env:
for i in desc_env:
v = i.split('=')
if len(v) == 2:
nasm_env[v[0]] = v[1]
else:
nasm_env[v[0]] = None
print("\tExecuting %s" % (" ".join(opts)))
pnasm = subprocess.Popen(opts,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
close_fds = True,
env = nasm_env)
if pnasm == None:
test_fail(desc['_test-name'], "Unable to execute test")
return None
stderr = pnasm.stderr.read(1048576).decode("utf-8").strip("\n")
stdout = pnasm.stdout.read(1048576).decode("utf-8").strip("\n")
pnasm.stdout.close()
pnasm.stderr.close()
wait_rc = pnasm.wait();
if desc['_wait'] != wait_rc:
if stdout != "":
show_std("stdout", stdout)
if stderr != "":
show_std("stderr", stderr)
test_fail(desc['_test-name'],
"Unexpected ret code: " + str(wait_rc))
return None, None, None
return pnasm, stdout, stderr
def test_run(desc):
print("=== Running %s ===" % (desc['_test-name']))
pnasm, stdout, stderr = exec_nasm(desc)
if pnasm == None:
return False
for t in desc['target']:
if 'output' in t:
output = desc['_base-dir'] + os.sep + t['output']
match = desc['_base-dir'] + os.sep + t['match']
if desc['_wait'] == 1:
continue
print("\tComparing %s %s" % (output, match))
if filecmp.cmp(match, output) == False:
show_diff(desc['_test-name'], match, output)
return test_fail(desc['_test-name'], match + " and " + output + " files are different")
elif 'stdout' in t:
print("\tComparing stdout")
match = desc['_base-dir'] + os.sep + t['stdout']
if cmp_std(desc['_test-name'], 'stdout', stdout, match) == False:
return test_fail(desc['_test-name'], "Stdout mismatch")
else:
stdout = ""
elif 'stderr' in t:
print("\tComparing stderr")
match = desc['_base-dir'] + os.sep + t['stderr']
if cmp_std(desc['_test-name'], 'stderr', stderr, match) == False:
return test_fail(desc['_test-name'], "Stderr mismatch")
else:
stderr = ""
if stdout != "":
show_std("stdout", stdout)
return test_fail(desc['_test-name'], "Stdout is not empty")
if stderr != "":
show_std("stderr", stderr)
return test_fail(desc['_test-name'], "Stderr is not empty")
return test_pass(desc['_test-name'])
#
# Compile sources and generate new targets
def test_update(desc):
print("=== Updating %s ===" % (desc['_test-name']))
if 'update' in desc and desc['update'] == 'false':
return test_skip(desc['_test-name'], "No output provided")
pnasm, stdout, stderr = exec_nasm(desc)
if pnasm == None:
return False
for t in desc['target']:
if 'output' in t:
output = desc['_base-dir'] + os.sep + t['output']
match = desc['_base-dir'] + os.sep + t['match']
print("\tMoving %s to %s" % (output, match))
os.rename(output, match)
if 'stdout' in t:
match = desc['_base-dir'] + os.sep + t['stdout']
print("\tMoving %s to %s" % ('stdout', match))
with open(match, "wb") as f:
f.write(stdout.encode("utf-8"))
f.close()
if 'stderr' in t:
match = desc['_base-dir'] + os.sep + t['stderr']
print("\tMoving %s to %s" % ('stderr', match))
with open(match, "wb") as f:
f.write(stderr.encode("utf-8"))
f.close()
return test_updated(desc['_test-name'])
if args.cmd == 'run':
desc_array = []
if args.test == None:
desc_array = collect_test_desc_from_dir(args.dir)
else:
desc_array = collect_test_desc_from_file(args.test)
if len(desc_array) == 0:
test_abort(args.test, "Can't obtain test descriptors")
for desc in desc_array:
if test_run(desc) == False:
if 'error' in desc and desc['error'] == 'over':
test_over(desc['_test-name'])
else:
test_abort(desc['_test-name'], "Error detected")
if args.cmd == 'update':
desc_array = []
if args.test == None:
desc_array = collect_test_desc_from_dir(args.dir)
else:
desc_array = collect_test_desc_from_file(args.test)
if len(desc_array) == 0:
test_abort(args.test, "Can't obtain a test descriptors")
for desc in desc_array:
if test_update(desc) == False:
if 'error' in desc and desc['error'] == 'over':
test_over(desc['_test-name'])
else:
test_abort(desc['_test-name'], "Error detected")

17
travis/t.json Normal file
View file

@ -0,0 +1,17 @@
[
{
"description": "",
"id": "",
"format": "",
"source": "",
"option": "",
"target": [
{ "output": "" }
]
},
{
"description": "",
"ref": "",
"option": ""
}
]

4
travis/test/_file_.asm Normal file
View file

@ -0,0 +1,4 @@
db __FILE__, `\r\n`
db __FILE__, `\r\n`
dw __LINE__
dw __LINE__

BIN
travis/test/_file_.bin.t Normal file

Binary file not shown.

8
travis/test/_file_.json Normal file
View file

@ -0,0 +1,8 @@
{
"description": "Check the __FILE__ preprocessor directive",
"format": "bin",
"source": "_file_.asm",
"target": [
{ "output": "_file_.bin" }
]
}

View file

@ -0,0 +1,7 @@
{
"description": "Check the NASM version",
"target": [
{ "option": "-v", "stdout": "_version.stdout" }
],
"error": "over"
}

View file

@ -0,0 +1 @@
NASM version 2.15rc0 compiled on Nov 3 2018

7
travis/test/a32offs.asm Normal file
View file

@ -0,0 +1,7 @@
bits 16
foo: a32 loop foo
bar: loop bar, ecx
bits 32
baz: a16 loop baz
qux: loop qux, cx

View file

@ -0,0 +1 @@
g<EFBFBD>g<EFBFBD>g<EFBFBD>g<EFBFBD>

18
travis/test/a32offs.json Normal file
View file

@ -0,0 +1,18 @@
[
{
"description": "Check a16/a32 address prefix (-Ox)",
"id": "a32offs",
"format": "bin",
"source": "a32offs.asm",
"option": "-Ox",
"target": [
{ "output": "a32offs.bin" }
]
},
{
"description": "Check a16/a32 address prefix (-O0)",
"ref": "a32offs",
"option": "-O0",
"update": false
}
]

38
travis/test/absolute.asm Normal file
View file

@ -0,0 +1,38 @@
org 7c00h
init_foo:
jmp init_bar
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
init_bar:
mov [b1],dl
mov [b2],edx
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
ret
absolute init_bar+7
b1: resb 1
b2: resd 6

View file

@ -0,0 +1 @@
<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|f<EFBFBD>|<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

View file

@ -0,0 +1,8 @@
{
"description": "Check absolute addressing",
"format": "bin",
"source": "absolute.asm",
"target": [
{ "output": "absolute.bin" }
]
}

15
travis/test/addr64x.asm Normal file
View file

@ -0,0 +1,15 @@
bits 64
mov rdx,[rax]
mov eax,[byte rsp+0x01]
mov eax,[byte rsp-0x01]
mov eax,[byte rsp+0xFF]
mov eax,[byte rsp-0xFF]
mov eax,[rsp+0x08]
mov eax,[rsp-0x01]
mov eax,[rsp+0xFF]
mov eax,[rsp-0xFF]
mov rax,[rsp+56]
mov [rsi],dl
mov byte [rsi],'-'
mov [rsi],al
mov byte [rsi],' '

BIN
travis/test/addr64x.bin.t Normal file

Binary file not shown.

25
travis/test/addr64x.json Normal file
View file

@ -0,0 +1,25 @@
[
{
"description": "Check 64-bit addressing (-Ox)",
"id": "addr64x",
"format": "bin",
"source": "addr64x.asm",
"option": "-Ox",
"target": [
{ "output": "addr64x.bin" },
{ "stderr": "addr64x.stderr" }
]
},
{
"description": "Check 64-bit addressing (-O1)",
"ref": "addr64x",
"option": "-O1",
"update": "false"
},
{
"description": "Check 64-bit addressing (-O0)",
"ref": "addr64x",
"option": "-O0",
"update": "false"
}
]

View file

@ -0,0 +1,4 @@
./travis/test/addr64x.asm:5: warning: byte data exceeds bounds [-w+number-overflow]
./travis/test/addr64x.asm:5: warning: byte data exceeds bounds [-w+number-overflow]
./travis/test/addr64x.asm:6: warning: byte data exceeds bounds [-w+number-overflow]
./travis/test/addr64x.asm:6: warning: byte data exceeds bounds [-w+number-overflow]

16
travis/test/align13.asm Normal file
View file

@ -0,0 +1,16 @@
; Test of non-power-of-2 alignment
bits 32
inc eax
inc eax
align 13
inc eax
inc eax
align 13
inc eax
inc eax
align 13
align 13 ;should do nothing
inc eax
inc eax

25
travis/test/align13.json Normal file
View file

@ -0,0 +1,25 @@
[
{
"description": "Test of non-power-of-2 alignment (-Ox)",
"id": "align13",
"format": "bin",
"source": "align13.asm",
"option": "-Ox -o align13.bin",
"target": [
{ "stderr": "align13.stderr" }
],
"error": "expected"
},
{
"description": "Test of non-power-of-2 alignment (-O1)",
"ref": "align13",
"option": "-O1 -o align13.bin",
"update": "false"
},
{
"description": "Test of non-power-of-2 alignment (-O0)",
"ref": "align13",
"option": "-O0 -o align13.bin",
"update": "false"
}
]

View file

@ -0,0 +1,4 @@
./travis/test/align13.asm:7: error: segment alignment `13' is not power of two
./travis/test/align13.asm:10: error: segment alignment `13' is not power of two
./travis/test/align13.asm:13: error: segment alignment `13' is not power of two
./travis/test/align13.asm:14: error: segment alignment `13' is not power of two

17
travis/test/align13s.asm Normal file
View file

@ -0,0 +1,17 @@
; Test of non-power-of-2 alignment
%use smartalign
bits 32
inc eax
inc eax
align 13
inc eax
inc eax
align 13
inc eax
inc eax
align 13
inc eax
inc eax

25
travis/test/align13s.json Normal file
View file

@ -0,0 +1,25 @@
[
{
"description": "Test of non-power-of-2 smart-alignment (-Ox)",
"id": "align13s",
"format": "bin",
"source": "align13s.asm",
"option": "-Ox -o align13s.bin",
"target": [
{ "stderr": "align13s.stderr" }
],
"error": "expected"
},
{
"description": "Test of non-power-of-2 smart-alignment (-O1)",
"ref": "align13s",
"option": "-O1 -o align13s.bin",
"update": "false"
},
{
"description": "Test of non-power-of-2 smart-alignment (-O0)",
"ref": "align13s",
"option": "-O0 -o align13s.bin",
"update": "false"
}
]

View file

@ -0,0 +1,3 @@
./travis/test/align13s.asm:9: error: segment alignment `13' is not power of two
./travis/test/align13s.asm:12: error: segment alignment `13' is not power of two
./travis/test/align13s.asm:15: error: segment alignment `13' is not power of two

View file

@ -0,0 +1,163 @@
section DOS32DATA align=16 public use32 FLAT class=DOS32DATA
global sym0000
global sym0001
global sym0002
global sym0003
global sym0004
global sym0005
global sym0006
global sym0007
global sym0008
global sym0009
global sym0010
global sym0011
global sym0012
global sym0013
global sym0014
global sym0015
global sym0016
global sym0017
global sym0018
global sym0019
global sym0020
global sym0021
global sym0022
global sym0023
global sym0024
global sym0025
global sym0026
global sym0027
global sym0028
global sym0029
global sym0030
global sym0031
global sym0032
global sym0033
global sym0034
global sym0035
global sym0036
global sym0037
global sym0038
global sym0039
global sym0040
global sym0041
global sym0042
global sym0043
global sym0044
global sym0045
global sym0046
global sym0047
global sym0048
global sym0049
global sym0050
global sym0051
global sym0052
global sym0053
global sym0054
global sym0055
global sym0056
global sym0057
global sym0058
global sym0059
global sym0060
global sym0061
global sym0062
global sym0063
global sym0064
global sym0065
global sym0066
global sym0067
global sym0068
global sym0069
global sym0070
global sym0071
global sym0072
global sym0073
global sym0074
global sym0075
global sym0076
global sym0077
global s
resb 20000h
sym0000 resd 1
sym0001 resd 1
sym0002 resd 1
sym0003 resd 1
sym0004 resd 1
sym0005 resd 1
sym0006 resd 1
sym0007 resd 1
sym0008 resd 1
sym0009 resd 1
sym0010 resd 1
sym0011 resd 1
sym0012 resd 1
sym0013 resd 1
sym0014 resd 1
sym0015 resd 1
sym0016 resd 1
sym0017 resd 1
sym0018 resd 1
sym0019 resd 1
sym0020 resd 1
sym0021 resd 1
sym0022 resd 1
sym0023 resd 1
sym0024 resd 1
sym0025 resd 1
sym0026 resd 1
sym0027 resd 1
sym0028 resd 1
sym0029 resd 1
sym0030 resd 1
sym0031 resd 1
sym0032 resd 1
sym0033 resd 1
sym0034 resd 1
sym0035 resd 1
sym0036 resd 1
sym0037 resd 1
sym0038 resd 1
sym0039 resd 1
sym0040 resd 1
sym0041 resd 1
sym0042 resd 1
sym0043 resd 1
sym0044 resd 1
sym0045 resd 1
sym0046 resd 1
sym0047 resd 1
sym0048 resd 1
sym0049 resd 1
sym0050 resd 1
sym0051 resd 1
sym0052 resd 1
sym0053 resd 1
sym0054 resd 1
sym0055 resd 1
sym0056 resd 1
sym0057 resd 1
sym0058 resd 1
sym0059 resd 1
sym0060 resd 1
sym0061 resd 1
sym0062 resd 1
sym0063 resd 1
sym0064 resd 1
sym0065 resd 1
sym0066 resd 1
sym0067 resd 1
sym0068 resd 1
sym0069 resd 1
sym0070 resd 1
sym0071 resd 1
sym0072 resd 1
sym0073 resd 1
sym0074 resd 1
sym0075 resd 1
sym0076 resd 1
sym0077 resd 1
s resd 1

View file

@ -0,0 +1,18 @@
[
{
"description": "Check global symbols in OBJ output (-Ox)",
"id": "alonesym-obj",
"format": "obj",
"source": "alonesym-obj.asm",
"option": "-Ox",
"target": [
{ "output": "alonesym-obj.obj" }
]
},
{
"description": "Check global symbols in OBJ output (-O0)",
"ref": "alonesym-obj",
"option": "-O0",
"update": false
}
]

Binary file not shown.

12
travis/test/andbyte.asm Normal file
View file

@ -0,0 +1,12 @@
bits 16
add sp, byte -0x10
add sp, -0x10
adc sp, byte -0x10
adc sp, -0x10
and sp, byte -0x10
and sp, -0x10
sbb sp, byte -0x10
sbb sp, -0x10
sub sp, byte -0x10
sub sp, -0x10

View file

@ -0,0 +1 @@
ƒִנƒִנƒװנƒװנƒהנƒהנƒ<EFBFBD>נƒ<EFBFBD>נƒלנƒלנ

17
travis/test/andbyte.json Normal file
View file

@ -0,0 +1,17 @@
[
{
"description": "Check byte operations (-Ox)",
"id": "andbyte",
"format": "bin",
"source": "andbyte.asm",
"option": "-Ox",
"target": [
{ "output": "andbyte.bin" }
]
},
{
"description": "Check byte operations",
"ref": "andbyte",
"update": false
}
]

BIN
travis/test/aoutso-o0.o.t Normal file

Binary file not shown.

BIN
travis/test/aoutso-ox.o.t Normal file

Binary file not shown.

96
travis/test/aoutso.asm Normal file
View file

@ -0,0 +1,96 @@
; test source file for assembling to NetBSD/FreeBSD a.out shared library
; build with:
; nasm -f aoutb aoutso.asm
; ld -Bshareable -o aoutso.so aoutso.o
; test with:
; cc -o aoutso aouttest.c aoutso.so
; ./aoutso
; This file should test the following:
; [1] Define and export a global text-section symbol
; [2] Define and export a global data-section symbol
; [3] Define and export a global BSS-section symbol
; [4] Define a non-global text-section symbol
; [5] Define a non-global data-section symbol
; [6] Define a non-global BSS-section symbol
; [7] Define a COMMON symbol
; [8] Define a NASM local label
; [9] Reference a NASM local label
; [10] Import an external symbol
; [11] Make a PC-relative call to an external symbol
; [12] Reference a text-section symbol in the text section
; [13] Reference a data-section symbol in the text section
; [14] Reference a BSS-section symbol in the text section
; [15] Reference a text-section symbol in the data section
; [16] Reference a data-section symbol in the data section
; [17] Reference a BSS-section symbol in the data section
BITS 32
EXTERN __GLOBAL_OFFSET_TABLE_
GLOBAL _lrotate:function ; [1]
GLOBAL _greet:function ; [1]
GLOBAL _asmstr:data _asmstr.end-_asmstr ; [2]
GLOBAL _textptr:data 4 ; [2]
GLOBAL _selfptr:data 4 ; [2]
GLOBAL _integer:data 4 ; [3]
EXTERN _printf ; [10]
COMMON _commvar 4 ; [7]
SECTION .text
; prototype: long lrotate(long x, int num);
_lrotate: ; [1]
push ebp
mov ebp,esp
mov eax,[ebp+8]
mov ecx,[ebp+12]
.label rol eax,1 ; [4] [8]
loop .label ; [9] [12]
mov esp,ebp
pop ebp
ret
; prototype: void greet(void);
_greet push ebx ; we'll use EBX for GOT, so save it
call .getgot
.getgot: pop ebx
add ebx,__GLOBAL_OFFSET_TABLE_ + $$ - .getgot wrt ..gotpc
mov eax,[ebx+_integer wrt ..got] ; [14]
mov eax,[eax]
inc eax
mov [ebx+localint wrt ..gotoff],eax ; [14]
mov eax,[ebx+_commvar wrt ..got]
push dword [eax]
mov eax,[ebx+localptr wrt ..gotoff] ; [13]
push dword [eax]
mov eax,[ebx+_integer wrt ..got] ; [1] [14]
push dword [eax]
lea eax,[ebx+_printfstr wrt ..gotoff]
push eax ; [13]
call _printf wrt ..plt ; [11]
add esp,16
pop ebx
ret
SECTION .data
; a string
_asmstr db 'hello, world', 0 ; [2]
.end
; a string for Printf
_printfstr db "integer==%d, localint==%d, commvar=%d"
db 10, 0
; some pointers
localptr dd localint ; [5] [17]
_textptr dd _greet wrt ..sym ; [15]
_selfptr dd _selfptr wrt ..sym ; [16]
SECTION .bss
; an integer
_integer resd 1 ; [3]
; a local integer
localint resd 1 ; [6]

22
travis/test/aoutso.json Normal file
View file

@ -0,0 +1,22 @@
[
{
"description": "Test NetBSD/FreeBSD a.out format (-Ox)",
"id": "aoutb",
"format": "aoutb",
"source": "aoutso.asm",
"option": "-Ox",
"target": [
{ "output": "aoutso-ox.o" },
{ "stderr": "aoutso.stderr" }
]
},
{
"description": "Test NetBSD/FreeBSD a.out format (-O0)",
"ref": "aoutb",
"option": "-O0",
"target": [
{ "output": "aoutso-o0.o" },
{ "stderr": "aoutso.stderr" }
]
}
]

View file

@ -0,0 +1 @@
./travis/test/aoutso.asm:79: warning: label alone on a line without a colon might be in error [-w+orphan-labels]

BIN
travis/test/aouttest-o0.o.t Normal file

Binary file not shown.

BIN
travis/test/aouttest-ox.o.t Normal file

Binary file not shown.

83
travis/test/aouttest.asm Normal file
View file

@ -0,0 +1,83 @@
; test source file for assembling to a.out
; build with:
; nasm -f aout aouttest.asm
; gcc -o aouttest aouttest.c aouttest.o
; (assuming your gcc is a.out)
; This file should test the following:
; [1] Define and export a global text-section symbol
; [2] Define and export a global data-section symbol
; [3] Define and export a global BSS-section symbol
; [4] Define a non-global text-section symbol
; [5] Define a non-global data-section symbol
; [6] Define a non-global BSS-section symbol
; [7] Define a COMMON symbol
; [8] Define a NASM local label
; [9] Reference a NASM local label
; [10] Import an external symbol
; [11] Make a PC-relative call to an external symbol
; [12] Reference a text-section symbol in the text section
; [13] Reference a data-section symbol in the text section
; [14] Reference a BSS-section symbol in the text section
; [15] Reference a text-section symbol in the data section
; [16] Reference a data-section symbol in the data section
; [17] Reference a BSS-section symbol in the data section
BITS 32
GLOBAL _lrotate ; [1]
GLOBAL _greet ; [1]
GLOBAL _asmstr ; [2]
GLOBAL _textptr ; [2]
GLOBAL _selfptr ; [2]
GLOBAL _integer ; [3]
EXTERN _printf ; [10]
COMMON _commvar 4 ; [7]
SECTION .text
; prototype: long lrotate(long x, int num);
_lrotate: ; [1]
push ebp
mov ebp,esp
mov eax,[ebp+8]
mov ecx,[ebp+12]
.label rol eax,1 ; [4] [8]
loop .label ; [9] [12]
mov esp,ebp
pop ebp
ret
; prototype: void greet(void);
_greet mov eax,[_integer] ; [14]
inc eax
mov [localint],eax ; [14]
push dword [_commvar]
mov eax,[localptr] ; [13]
push dword [eax]
push dword [_integer] ; [1] [14]
push dword _printfstr ; [13]
call _printf ; [11]
add esp,16
ret
SECTION .data
; a string
_asmstr db 'hello, world', 0 ; [2]
; a string for Printf
_printfstr db "integer==%d, localint==%d, commvar=%d"
db 10, 0
; some pointers
localptr dd localint ; [5] [17]
_textptr dd _greet ; [15]
_selfptr dd _selfptr ; [16]
SECTION .bss
; an integer
_integer resd 1 ; [3]
; a local integer
localint resd 1 ; [6]

20
travis/test/aouttest.json Normal file
View file

@ -0,0 +1,20 @@
[
{
"description": "Test aout format (-Ox)",
"id": "aouttest",
"format": "aout",
"source": "aouttest.asm",
"option": "-Ox",
"target": [
{ "output": "aouttest-ox.o" }
]
},
{
"description": "Test aout format (-O0)",
"ref": "aouttest",
"option": "-O0",
"target": [
{ "output": "aouttest-o0.o" }
]
}
]

43
travis/test/avx.asm Normal file
View file

@ -0,0 +1,43 @@
bits 64
blendvpd xmm2,xmm1,xmm0
vblendvpd xmm2,xmm1,xmm0,xmm0
vblendvpd xmm2,xmm1,xmm0
vblendvpd ymm2,ymm1,ymm0,ymm0
vblendvpd ymm2,ymm1,ymm0
vcvtsi2sd xmm9,xmm10,ecx
vcvtsi2sd xmm9,xmm10,rcx
vcvtsi2sd xmm9,xmm10,dword [rdi]
vcvtsi2sd xmm9,xmm10,qword [rdi]
vpextrb [rax],xmm1,0x33
vpextrw [rax],xmm1,0x33
vpextrd [rax],xmm1,0x33
vpextrq [rax],xmm1,0x33
vpextrb rax,xmm1,0x33
vpextrw rax,xmm1,0x33
vpextrd rax,xmm1,0x33
vpextrq rax,xmm1,0x33
vpextrb eax,xmm1,0x33
vpextrw eax,xmm1,0x33
vpextrd eax,xmm1,0x33
; vpextrq eax,xmm1,0x33
vcvtpd2ps xmm0,xmm1
vcvtpd2ps xmm0,oword [rsi]
vcvtpd2ps xmm0,ymm1
vcvtpd2ps xmm0,yword [rsi]
; vcvtpd2ps xmm0,[rsi]
vcvtpd2dq xmm0,xmm1
vcvtpd2dq xmm0,oword [rsi]
vcvtpd2dq xmm0,ymm1
vcvtpd2dq xmm0,yword [rsi]
; vcvtpd2dq xmm0,[rsi]
vcvttpd2dq xmm0,xmm1
vcvttpd2dq xmm0,oword [rsi]
vcvttpd2dq xmm0,ymm1
vcvttpd2dq xmm0,yword [rsi]
; vcvttpd2dq xmm0,[rsi]

BIN
travis/test/avx.bin.t Normal file

Binary file not shown.

18
travis/test/avx.json Normal file
View file

@ -0,0 +1,18 @@
[
{
"description": "Test AVX instructions (-Ox)",
"id": "avx",
"format": "bin",
"source": "avx.asm",
"option": "-Ox",
"target": [
{ "output": "avx.bin" }
]
},
{
"description": "Test AVX instructions (-O0)",
"ref": "avx",
"option": "-O0",
"update": false
}
]

527
travis/test/avx005.asm Normal file
View file

@ -0,0 +1,527 @@
%define regxmm xmm0
%define regymm ymm0
%define mem [0]
%define imm 3
%macro x 1+.nolist
%1 ; comment this line if RELAXed variants are not supported
%endmacro
VFMADDSUB132PS regxmm,regxmm,mem ; VEX_FMA,SO
VFMADDSUB132PS regxmm,regxmm,regxmm ; VEX_FMA
VFMADDSUB132PS regymm,regymm,mem ; VEX_FMA,SY
VFMADDSUB132PS regymm,regymm,regymm ; VEX_FMA
x VFMADDSUB312PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMADDSUB312PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMADDSUB312PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMADDSUB312PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFMADDSUB132PD regxmm,regxmm,mem ; VEX_FMA,SO
VFMADDSUB132PD regxmm,regxmm,regxmm ; VEX_FMA
VFMADDSUB132PD regymm,regymm,mem ; VEX_FMA,SY
VFMADDSUB132PD regymm,regymm,regymm ; VEX_FMA
x VFMADDSUB312PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMADDSUB312PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMADDSUB312PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMADDSUB312PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFMSUBADD132PS regxmm,regxmm,mem ; VEX_FMA,SO
VFMSUBADD132PS regxmm,regxmm,regxmm ; VEX_FMA
VFMSUBADD132PS regymm,regymm,mem ; VEX_FMA,SY
VFMSUBADD132PS regymm,regymm,regymm ; VEX_FMA
x VFMSUBADD312PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMSUBADD312PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMSUBADD312PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMSUBADD312PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFMSUBADD132PD regxmm,regxmm,mem ; VEX_FMA,SO
VFMSUBADD132PD regxmm,regxmm,regxmm ; VEX_FMA
VFMSUBADD132PD regymm,regymm,mem ; VEX_FMA,SY
VFMSUBADD132PD regymm,regymm,regymm ; VEX_FMA
x VFMSUBADD312PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMSUBADD312PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMSUBADD312PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMSUBADD312PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFMADD132PS regxmm,regxmm,mem ; VEX_FMA,SO
VFMADD132PS regxmm,regxmm,regxmm ; VEX_FMA
VFMADD132PS regymm,regymm,mem ; VEX_FMA,SY
VFMADD132PS regymm,regymm,regymm ; VEX_FMA
x VFMADD312PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMADD312PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMADD312PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMADD312PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFMADD132PD regxmm,regxmm,mem ; VEX_FMA,SO
VFMADD132PD regxmm,regxmm,regxmm ; VEX_FMA
VFMADD132PD regymm,regymm,mem ; VEX_FMA,SY
VFMADD132PD regymm,regymm,regymm ; VEX_FMA
x VFMADD312PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMADD312PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMADD312PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMADD312PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFMADD132SS regxmm,regxmm,mem ; VEX_FMA,SD
VFMADD132SS regxmm,regxmm,regxmm ; VEX_FMA
x VFMADD312SS regxmm,regxmm,mem ; VEX_FMA,RELAX,SD
x VFMADD312SS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFMADD132SD regxmm,regxmm,mem ; VEX_FMA,SQ
VFMADD132SD regxmm,regxmm,regxmm ; VEX_FMA
x VFMADD312SD regxmm,regxmm,mem ; VEX_FMA,RELAX,SQ
x VFMADD312SD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFMSUB132PS regxmm,regxmm,mem ; VEX_FMA,SO
VFMSUB132PS regxmm,regxmm,regxmm ; VEX_FMA
VFMSUB132PS regymm,regymm,mem ; VEX_FMA,SY
VFMSUB132PS regymm,regymm,regymm ; VEX_FMA
x VFMSUB312PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMSUB312PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMSUB312PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMSUB312PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFMSUB132PD regxmm,regxmm,mem ; VEX_FMA,SO
VFMSUB132PD regxmm,regxmm,regxmm ; VEX_FMA
VFMSUB132PD regymm,regymm,mem ; VEX_FMA,SY
VFMSUB132PD regymm,regymm,regymm ; VEX_FMA
x VFMSUB312PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMSUB312PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMSUB312PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMSUB312PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFMSUB132SS regxmm,regxmm,mem ; VEX_FMA,SD
VFMSUB132SS regxmm,regxmm,regxmm ; VEX_FMA
x VFMSUB312SS regxmm,regxmm,mem ; VEX_FMA,RELAX,SD
x VFMSUB312SS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFMSUB132SD regxmm,regxmm,mem ; VEX_FMA,SQ
VFMSUB132SD regxmm,regxmm,regxmm ; VEX_FMA
x VFMSUB312SD regxmm,regxmm,mem ; VEX_FMA,RELAX,SQ
x VFMSUB312SD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFNMADD132PS regxmm,regxmm,mem ; VEX_FMA,SO
VFNMADD132PS regxmm,regxmm,regxmm ; VEX_FMA
VFNMADD132PS regymm,regymm,mem ; VEX_FMA,SY
VFNMADD132PS regymm,regymm,regymm ; VEX_FMA
x VFNMADD312PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFNMADD312PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFNMADD312PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFNMADD312PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFNMADD132PD regxmm,regxmm,mem ; VEX_FMA,SO
VFNMADD132PD regxmm,regxmm,regxmm ; VEX_FMA
VFNMADD132PD regymm,regymm,mem ; VEX_FMA,SY
VFNMADD132PD regymm,regymm,regymm ; VEX_FMA
x VFNMADD312PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFNMADD312PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFNMADD312PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFNMADD312PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFNMADD132SS regxmm,regxmm,mem ; VEX_FMA,SD
VFNMADD132SS regxmm,regxmm,regxmm ; VEX_FMA
x VFNMADD312SS regxmm,regxmm,mem ; VEX_FMA,RELAX,SD
x VFNMADD312SS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFNMADD132SD regxmm,regxmm,mem ; VEX_FMA,SQ
VFNMADD132SD regxmm,regxmm,regxmm ; VEX_FMA
x VFNMADD312SD regxmm,regxmm,mem ; VEX_FMA,RELAX,SQ
x VFNMADD312SD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFNMSUB132PS regxmm,regxmm,mem ; VEX_FMA,SO
VFNMSUB132PS regxmm,regxmm,regxmm ; VEX_FMA
VFNMSUB132PS regymm,regymm,mem ; VEX_FMA,SY
VFNMSUB132PS regymm,regymm,regymm ; VEX_FMA
x VFNMSUB312PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFNMSUB312PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFNMSUB312PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFNMSUB312PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFNMSUB132PD regxmm,regxmm,mem ; VEX_FMA,SO
VFNMSUB132PD regxmm,regxmm,regxmm ; VEX_FMA
VFNMSUB132PD regymm,regymm,mem ; VEX_FMA,SY
VFNMSUB132PD regymm,regymm,regymm ; VEX_FMA
x VFNMSUB312PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFNMSUB312PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFNMSUB312PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFNMSUB312PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFNMSUB132SS regxmm,regxmm,mem ; VEX_FMA,SD
VFNMSUB132SS regxmm,regxmm,regxmm ; VEX_FMA
x VFNMSUB312SS regxmm,regxmm,mem ; VEX_FMA,RELAX,SD
x VFNMSUB312SS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFNMSUB132SD regxmm,regxmm,mem ; VEX_FMA,SQ
VFNMSUB132SD regxmm,regxmm,regxmm ; VEX_FMA
x VFNMSUB312SD regxmm,regxmm,mem ; VEX_FMA,RELAX,SQ
x VFNMSUB312SD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFMADDSUB213PS regxmm,regxmm,mem ; VEX_FMA,SO
VFMADDSUB213PS regxmm,regxmm,regxmm ; VEX_FMA
VFMADDSUB213PS regymm,regymm,mem ; VEX_FMA,SY
VFMADDSUB213PS regymm,regymm,regymm ; VEX_FMA
x VFMADDSUB123PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMADDSUB123PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMADDSUB123PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMADDSUB123PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFMADDSUB213PD regxmm,regxmm,mem ; VEX_FMA,SO
VFMADDSUB213PD regxmm,regxmm,regxmm ; VEX_FMA
VFMADDSUB213PD regymm,regymm,mem ; VEX_FMA,SY
VFMADDSUB213PD regymm,regymm,regymm ; VEX_FMA
x VFMADDSUB123PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMADDSUB123PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMADDSUB123PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMADDSUB123PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFMSUBADD213PS regxmm,regxmm,mem ; VEX_FMA,SO
VFMSUBADD213PS regxmm,regxmm,regxmm ; VEX_FMA
VFMSUBADD213PS regymm,regymm,mem ; VEX_FMA,SY
VFMSUBADD213PS regymm,regymm,regymm ; VEX_FMA
x VFMSUBADD123PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMSUBADD123PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMSUBADD123PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMSUBADD123PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFMSUBADD213PD regxmm,regxmm,mem ; VEX_FMA,SO
VFMSUBADD213PD regxmm,regxmm,regxmm ; VEX_FMA
VFMSUBADD213PD regymm,regymm,mem ; VEX_FMA,SY
VFMSUBADD213PD regymm,regymm,regymm ; VEX_FMA
x VFMSUBADD123PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMSUBADD123PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMSUBADD123PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMSUBADD123PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFMADD213PS regxmm,regxmm,mem ; VEX_FMA,SO
VFMADD213PS regxmm,regxmm,regxmm ; VEX_FMA
VFMADD213PS regymm,regymm,mem ; VEX_FMA,SY
VFMADD213PS regymm,regymm,regymm ; VEX_FMA
x VFMADD123PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMADD123PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMADD123PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMADD123PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFMADD213PD regxmm,regxmm,mem ; VEX_FMA,SO
VFMADD213PD regxmm,regxmm,regxmm ; VEX_FMA
VFMADD213PD regymm,regymm,mem ; VEX_FMA,SY
VFMADD213PD regymm,regymm,regymm ; VEX_FMA
x VFMADD123PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMADD123PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMADD123PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMADD123PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFMADD213SS regxmm,regxmm,mem ; VEX_FMA,SD
VFMADD213SS regxmm,regxmm,regxmm ; VEX_FMA
x VFMADD123SS regxmm,regxmm,mem ; VEX_FMA,RELAX,SD
x VFMADD123SS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFMADD213SD regxmm,regxmm,mem ; VEX_FMA,SQ
VFMADD213SD regxmm,regxmm,regxmm ; VEX_FMA
x VFMADD123SD regxmm,regxmm,mem ; VEX_FMA,RELAX,SQ
x VFMADD123SD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFMSUB213PS regxmm,regxmm,mem ; VEX_FMA,SO
VFMSUB213PS regxmm,regxmm,regxmm ; VEX_FMA
VFMSUB213PS regymm,regymm,mem ; VEX_FMA,SY
VFMSUB213PS regymm,regymm,regymm ; VEX_FMA
x VFMSUB123PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMSUB123PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMSUB123PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMSUB123PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFMSUB213PD regxmm,regxmm,mem ; VEX_FMA,SO
VFMSUB213PD regxmm,regxmm,regxmm ; VEX_FMA
VFMSUB213PD regymm,regymm,mem ; VEX_FMA,SY
VFMSUB213PD regymm,regymm,regymm ; VEX_FMA
x VFMSUB123PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMSUB123PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMSUB123PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMSUB123PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFMSUB213SS regxmm,regxmm,mem ; VEX_FMA,SD
VFMSUB213SS regxmm,regxmm,regxmm ; VEX_FMA
x VFMSUB123SS regxmm,regxmm,mem ; VEX_FMA,RELAX,SD
x VFMSUB123SS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFMSUB213SD regxmm,regxmm,mem ; VEX_FMA,SQ
VFMSUB213SD regxmm,regxmm,regxmm ; VEX_FMA
x VFMSUB123SD regxmm,regxmm,mem ; VEX_FMA,RELAX,SQ
x VFMSUB123SD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFNMADD213PS regxmm,regxmm,mem ; VEX_FMA,SO
VFNMADD213PS regxmm,regxmm,regxmm ; VEX_FMA
VFNMADD213PS regymm,regymm,mem ; VEX_FMA,SY
VFNMADD213PS regymm,regymm,regymm ; VEX_FMA
x VFNMADD123PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFNMADD123PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFNMADD123PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFNMADD123PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFNMADD213PD regxmm,regxmm,mem ; VEX_FMA,SO
VFNMADD213PD regxmm,regxmm,regxmm ; VEX_FMA
VFNMADD213PD regymm,regymm,mem ; VEX_FMA,SY
VFNMADD213PD regymm,regymm,regymm ; VEX_FMA
x VFNMADD123PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFNMADD123PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFNMADD123PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFNMADD123PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFNMADD213SS regxmm,regxmm,mem ; VEX_FMA,SD
VFNMADD213SS regxmm,regxmm,regxmm ; VEX_FMA
x VFNMADD123SS regxmm,regxmm,mem ; VEX_FMA,RELAX,SD
x VFNMADD123SS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFNMADD213SD regxmm,regxmm,mem ; VEX_FMA,SQ
VFNMADD213SD regxmm,regxmm,regxmm ; VEX_FMA
x VFNMADD123SD regxmm,regxmm,mem ; VEX_FMA,RELAX,SQ
x VFNMADD123SD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFNMSUB213PS regxmm,regxmm,mem ; VEX_FMA,SO
VFNMSUB213PS regxmm,regxmm,regxmm ; VEX_FMA
VFNMSUB213PS regymm,regymm,mem ; VEX_FMA,SY
VFNMSUB213PS regymm,regymm,regymm ; VEX_FMA
x VFNMSUB123PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFNMSUB123PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFNMSUB123PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFNMSUB123PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFNMSUB213PD regxmm,regxmm,mem ; VEX_FMA,SO
VFNMSUB213PD regxmm,regxmm,regxmm ; VEX_FMA
VFNMSUB213PD regymm,regymm,mem ; VEX_FMA,SY
VFNMSUB213PD regymm,regymm,regymm ; VEX_FMA
x VFNMSUB123PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFNMSUB123PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFNMSUB123PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFNMSUB123PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFNMSUB213SS regxmm,regxmm,mem ; VEX_FMA,SD
VFNMSUB213SS regxmm,regxmm,regxmm ; VEX_FMA
x VFNMSUB123SS regxmm,regxmm,mem ; VEX_FMA,RELAX,SD
x VFNMSUB123SS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFNMSUB213SD regxmm,regxmm,mem ; VEX_FMA,SQ
VFNMSUB213SD regxmm,regxmm,regxmm ; VEX_FMA
x VFNMSUB123SD regxmm,regxmm,mem ; VEX_FMA,RELAX,SQ
x VFNMSUB123SD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFMADDSUB231PS regxmm,regxmm,mem ; VEX_FMA,SO
VFMADDSUB231PS regxmm,regxmm,regxmm ; VEX_FMA
VFMADDSUB231PS regymm,regymm,mem ; VEX_FMA,SY
VFMADDSUB231PS regymm,regymm,regymm ; VEX_FMA
x VFMADDSUB321PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMADDSUB321PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMADDSUB321PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMADDSUB321PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFMADDSUB231PD regxmm,regxmm,mem ; VEX_FMA,SO
VFMADDSUB231PD regxmm,regxmm,regxmm ; VEX_FMA
VFMADDSUB231PD regymm,regymm,mem ; VEX_FMA,SY
VFMADDSUB231PD regymm,regymm,regymm ; VEX_FMA
x VFMADDSUB321PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMADDSUB321PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMADDSUB321PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMADDSUB321PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFMSUBADD231PS regxmm,regxmm,mem ; VEX_FMA,SO
VFMSUBADD231PS regxmm,regxmm,regxmm ; VEX_FMA
VFMSUBADD231PS regymm,regymm,mem ; VEX_FMA,SY
VFMSUBADD231PS regymm,regymm,regymm ; VEX_FMA
x VFMSUBADD321PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMSUBADD321PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMSUBADD321PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMSUBADD321PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFMSUBADD231PD regxmm,regxmm,mem ; VEX_FMA,SO
VFMSUBADD231PD regxmm,regxmm,regxmm ; VEX_FMA
VFMSUBADD231PD regymm,regymm,mem ; VEX_FMA,SY
VFMSUBADD231PD regymm,regymm,regymm ; VEX_FMA
x VFMSUBADD321PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMSUBADD321PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMSUBADD321PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMSUBADD321PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFMADD231PS regxmm,regxmm,mem ; VEX_FMA,SO
VFMADD231PS regxmm,regxmm,regxmm ; VEX_FMA
VFMADD231PS regymm,regymm,mem ; VEX_FMA,SY
VFMADD231PS regymm,regymm,regymm ; VEX_FMA
x VFMADD321PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMADD321PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMADD321PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMADD321PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFMADD231PD regxmm,regxmm,mem ; VEX_FMA,SO
VFMADD231PD regxmm,regxmm,regxmm ; VEX_FMA
VFMADD231PD regymm,regymm,mem ; VEX_FMA,SY
VFMADD231PD regymm,regymm,regymm ; VEX_FMA
x VFMADD321PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMADD321PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMADD321PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMADD321PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFMADD231SS regxmm,regxmm,mem ; VEX_FMA,SD
VFMADD231SS regxmm,regxmm,regxmm ; VEX_FMA
x VFMADD321SS regxmm,regxmm,mem ; VEX_FMA,RELAX,SD
x VFMADD321SS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFMADD231SD regxmm,regxmm,mem ; VEX_FMA,SQ
VFMADD231SD regxmm,regxmm,regxmm ; VEX_FMA
x VFMADD321SD regxmm,regxmm,mem ; VEX_FMA,RELAX,SQ
x VFMADD321SD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFMSUB231PS regxmm,regxmm,mem ; VEX_FMA,SO
VFMSUB231PS regxmm,regxmm,regxmm ; VEX_FMA
VFMSUB231PS regymm,regymm,mem ; VEX_FMA,SY
VFMSUB231PS regymm,regymm,regymm ; VEX_FMA
x VFMSUB321PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMSUB321PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMSUB321PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMSUB321PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFMSUB231PD regxmm,regxmm,mem ; VEX_FMA,SO
VFMSUB231PD regxmm,regxmm,regxmm ; VEX_FMA
VFMSUB231PD regymm,regymm,mem ; VEX_FMA,SY
VFMSUB231PD regymm,regymm,regymm ; VEX_FMA
x VFMSUB321PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFMSUB321PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFMSUB321PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFMSUB321PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFMSUB231SS regxmm,regxmm,mem ; VEX_FMA,SD
VFMSUB231SS regxmm,regxmm,regxmm ; VEX_FMA
x VFMSUB321SS regxmm,regxmm,mem ; VEX_FMA,RELAX,SD
x VFMSUB321SS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFMSUB231SD regxmm,regxmm,mem ; VEX_FMA,SQ
VFMSUB231SD regxmm,regxmm,regxmm ; VEX_FMA
x VFMSUB321SD regxmm,regxmm,mem ; VEX_FMA,RELAX,SQ
x VFMSUB321SD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFNMADD231PS regxmm,regxmm,mem ; VEX_FMA,SO
VFNMADD231PS regxmm,regxmm,regxmm ; VEX_FMA
VFNMADD231PS regymm,regymm,mem ; VEX_FMA,SY
VFNMADD231PS regymm,regymm,regymm ; VEX_FMA
x VFNMADD321PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFNMADD321PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFNMADD321PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFNMADD321PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFNMADD231PD regxmm,regxmm,mem ; VEX_FMA,SO
VFNMADD231PD regxmm,regxmm,regxmm ; VEX_FMA
VFNMADD231PD regymm,regymm,mem ; VEX_FMA,SY
VFNMADD231PD regymm,regymm,regymm ; VEX_FMA
x VFNMADD321PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFNMADD321PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFNMADD321PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFNMADD321PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFNMADD231SS regxmm,regxmm,mem ; VEX_FMA,SD
VFNMADD231SS regxmm,regxmm,regxmm ; VEX_FMA
x VFNMADD321SS regxmm,regxmm,mem ; VEX_FMA,RELAX,SD
x VFNMADD321SS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFNMADD231SD regxmm,regxmm,mem ; VEX_FMA,SQ
VFNMADD231SD regxmm,regxmm,regxmm ; VEX_FMA
x VFNMADD321SD regxmm,regxmm,mem ; VEX_FMA,RELAX,SQ
x VFNMADD321SD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFNMSUB231PS regxmm,regxmm,mem ; VEX_FMA,SO
VFNMSUB231PS regxmm,regxmm,regxmm ; VEX_FMA
VFNMSUB231PS regymm,regymm,mem ; VEX_FMA,SY
VFNMSUB231PS regymm,regymm,regymm ; VEX_FMA
x VFNMSUB321PS regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFNMSUB321PS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFNMSUB321PS regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFNMSUB321PS regymm,regymm,regymm ; VEX_FMA,RELAX
VFNMSUB231PD regxmm,regxmm,mem ; VEX_FMA,SO
VFNMSUB231PD regxmm,regxmm,regxmm ; VEX_FMA
VFNMSUB231PD regymm,regymm,mem ; VEX_FMA,SY
VFNMSUB231PD regymm,regymm,regymm ; VEX_FMA
x VFNMSUB321PD regxmm,regxmm,mem ; VEX_FMA,RELAX,SO
x VFNMSUB321PD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
x VFNMSUB321PD regymm,regymm,mem ; VEX_FMA,RELAX,SY
x VFNMSUB321PD regymm,regymm,regymm ; VEX_FMA,RELAX
VFNMSUB231SS regxmm,regxmm,mem ; VEX_FMA,SD
VFNMSUB231SS regxmm,regxmm,regxmm ; VEX_FMA
x VFNMSUB321SS regxmm,regxmm,mem ; VEX_FMA,RELAX,SD
x VFNMSUB321SS regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VFNMSUB231SD regxmm,regxmm,mem ; VEX_FMA,SQ
VFNMSUB231SD regxmm,regxmm,regxmm ; VEX_FMA
x VFNMSUB321SD regxmm,regxmm,mem ; VEX_FMA,RELAX,SQ
x VFNMSUB321SD regxmm,regxmm,regxmm ; VEX_FMA,RELAX
VPCLMULLQLQDQ regxmm,regxmm,mem ; PCLMUL,VEX_AVX,SO
VPCLMULLQLQDQ regxmm,regxmm,regxmm ; PCLMUL,VEX_AVX
VPCLMULHQLQDQ regxmm,regxmm,mem ; PCLMUL,VEX_AVX,SO
VPCLMULHQLQDQ regxmm,regxmm,regxmm ; PCLMUL,VEX_AVX
VPCLMULLQHQDQ regxmm,regxmm,mem ; PCLMUL,VEX_AVX,SO
VPCLMULLQHQDQ regxmm,regxmm,regxmm ; PCLMUL,VEX_AVX
VPCLMULHQHQDQ regxmm,regxmm,mem ; PCLMUL,VEX_AVX,SO
VPCLMULHQHQDQ regxmm,regxmm,regxmm ; PCLMUL,VEX_AVX
VPCLMULQDQ regxmm,regxmm,mem,imm ; PCLMUL,VEX_AVX,SB3,SO
VPCLMULQDQ regxmm,regxmm,regxmm,imm ; PCLMUL,VEX_AVX,SB3
; EOF

BIN
travis/test/avx005.bin.t Normal file

Binary file not shown.

12
travis/test/avx005.json Normal file
View file

@ -0,0 +1,12 @@
[
{
"description": "Test relaxed AVX instructions",
"id": "avx005",
"format": "bin",
"source": "avx005.asm",
"option": "-Ox",
"target": [
{ "output": "avx005.bin" }
]
}
]

105
travis/test/avx512cd.asm Normal file
View file

@ -0,0 +1,105 @@
; AVX-512CD testcases from gas
;------------------------
;
; This file is taken from there
; https://gnu.googlesource.com/binutils/+/master/gas/testsuite/gas/i386/x86-64-avx512cd-intel.d
; So the original author is "H.J. Lu" <hongjiu dot lu at intel dot com>
;
; Jin Kyu Song converted it for the nasm testing suite using gas2nasm.py
%macro testcase 2
%ifdef BIN
db %1
%endif
%ifdef SRC
%2
%endif
%endmacro
bits 64
testcase { 0x62, 0x02, 0x7d, 0x48, 0xc4, 0xf5 }, { vpconflictd zmm30,zmm29 }
testcase { 0x62, 0x02, 0x7d, 0x4f, 0xc4, 0xf5 }, { vpconflictd zmm30{k7},zmm29 }
testcase { 0x62, 0x02, 0x7d, 0xcf, 0xc4, 0xf5 }, { vpconflictd zmm30{k7}{z},zmm29 }
testcase { 0x62, 0x62, 0x7d, 0x48, 0xc4, 0x31 }, { vpconflictd zmm30,ZWORD [rcx] }
testcase { 0x62, 0x22, 0x7d, 0x48, 0xc4, 0xb4, 0xf0, 0x23, 0x01, 0x00, 0x00 }, { vpconflictd zmm30,ZWORD [rax+r14*8+0x123] }
testcase { 0x62, 0x62, 0x7d, 0x58, 0xc4, 0x31 }, { vpconflictd zmm30,DWORD [rcx]{1to16} }
testcase { 0x62, 0x62, 0x7d, 0x48, 0xc4, 0x72, 0x7f }, { vpconflictd zmm30,ZWORD [rdx+0x1fc0] }
testcase { 0x62, 0x62, 0x7d, 0x48, 0xc4, 0xb2, 0x00, 0x20, 0x00, 0x00 }, { vpconflictd zmm30,ZWORD [rdx+0x2000] }
testcase { 0x62, 0x62, 0x7d, 0x48, 0xc4, 0x72, 0x80 }, { vpconflictd zmm30,ZWORD [rdx-0x2000] }
testcase { 0x62, 0x62, 0x7d, 0x48, 0xc4, 0xb2, 0xc0, 0xdf, 0xff, 0xff }, { vpconflictd zmm30,ZWORD [rdx-0x2040] }
testcase { 0x62, 0x62, 0x7d, 0x58, 0xc4, 0x72, 0x7f }, { vpconflictd zmm30,DWORD [rdx+0x1fc]{1to16} }
testcase { 0x62, 0x62, 0x7d, 0x58, 0xc4, 0xb2, 0x00, 0x02, 0x00, 0x00 }, { vpconflictd zmm30,DWORD [rdx+0x200]{1to16} }
testcase { 0x62, 0x62, 0x7d, 0x58, 0xc4, 0x72, 0x80 }, { vpconflictd zmm30,DWORD [rdx-0x200]{1to16} }
testcase { 0x62, 0x62, 0x7d, 0x58, 0xc4, 0xb2, 0xfc, 0xfd, 0xff, 0xff }, { vpconflictd zmm30,DWORD [rdx-0x204]{1to16} }
testcase { 0x62, 0x02, 0xfd, 0x48, 0xc4, 0xf5 }, { vpconflictq zmm30,zmm29 }
testcase { 0x62, 0x02, 0xfd, 0x4f, 0xc4, 0xf5 }, { vpconflictq zmm30{k7},zmm29 }
testcase { 0x62, 0x02, 0xfd, 0xcf, 0xc4, 0xf5 }, { vpconflictq zmm30{k7}{z},zmm29 }
testcase { 0x62, 0x62, 0xfd, 0x48, 0xc4, 0x31 }, { vpconflictq zmm30,ZWORD [rcx] }
testcase { 0x62, 0x22, 0xfd, 0x48, 0xc4, 0xb4, 0xf0, 0x23, 0x01, 0x00, 0x00 }, { vpconflictq zmm30,ZWORD [rax+r14*8+0x123] }
testcase { 0x62, 0x62, 0xfd, 0x58, 0xc4, 0x31 }, { vpconflictq zmm30,QWORD [rcx]{1to8} }
testcase { 0x62, 0x62, 0xfd, 0x48, 0xc4, 0x72, 0x7f }, { vpconflictq zmm30,ZWORD [rdx+0x1fc0] }
testcase { 0x62, 0x62, 0xfd, 0x48, 0xc4, 0xb2, 0x00, 0x20, 0x00, 0x00 }, { vpconflictq zmm30,ZWORD [rdx+0x2000] }
testcase { 0x62, 0x62, 0xfd, 0x48, 0xc4, 0x72, 0x80 }, { vpconflictq zmm30,ZWORD [rdx-0x2000] }
testcase { 0x62, 0x62, 0xfd, 0x48, 0xc4, 0xb2, 0xc0, 0xdf, 0xff, 0xff }, { vpconflictq zmm30,ZWORD [rdx-0x2040] }
testcase { 0x62, 0x62, 0xfd, 0x58, 0xc4, 0x72, 0x7f }, { vpconflictq zmm30,QWORD [rdx+0x3f8]{1to8} }
testcase { 0x62, 0x62, 0xfd, 0x58, 0xc4, 0xb2, 0x00, 0x04, 0x00, 0x00 }, { vpconflictq zmm30,QWORD [rdx+0x400]{1to8} }
testcase { 0x62, 0x62, 0xfd, 0x58, 0xc4, 0x72, 0x80 }, { vpconflictq zmm30,QWORD [rdx-0x400]{1to8} }
testcase { 0x62, 0x62, 0xfd, 0x58, 0xc4, 0xb2, 0xf8, 0xfb, 0xff, 0xff }, { vpconflictq zmm30,QWORD [rdx-0x408]{1to8} }
testcase { 0x62, 0x02, 0x7d, 0x48, 0x44, 0xf5 }, { vplzcntd zmm30,zmm29 }
testcase { 0x62, 0x02, 0x7d, 0x4f, 0x44, 0xf5 }, { vplzcntd zmm30{k7},zmm29 }
testcase { 0x62, 0x02, 0x7d, 0xcf, 0x44, 0xf5 }, { vplzcntd zmm30{k7}{z},zmm29 }
testcase { 0x62, 0x62, 0x7d, 0x48, 0x44, 0x31 }, { vplzcntd zmm30,ZWORD [rcx] }
testcase { 0x62, 0x22, 0x7d, 0x48, 0x44, 0xb4, 0xf0, 0x23, 0x01, 0x00, 0x00 }, { vplzcntd zmm30,ZWORD [rax+r14*8+0x123] }
testcase { 0x62, 0x62, 0x7d, 0x58, 0x44, 0x31 }, { vplzcntd zmm30,DWORD [rcx]{1to16} }
testcase { 0x62, 0x62, 0x7d, 0x48, 0x44, 0x72, 0x7f }, { vplzcntd zmm30,ZWORD [rdx+0x1fc0] }
testcase { 0x62, 0x62, 0x7d, 0x48, 0x44, 0xb2, 0x00, 0x20, 0x00, 0x00 }, { vplzcntd zmm30,ZWORD [rdx+0x2000] }
testcase { 0x62, 0x62, 0x7d, 0x48, 0x44, 0x72, 0x80 }, { vplzcntd zmm30,ZWORD [rdx-0x2000] }
testcase { 0x62, 0x62, 0x7d, 0x48, 0x44, 0xb2, 0xc0, 0xdf, 0xff, 0xff }, { vplzcntd zmm30,ZWORD [rdx-0x2040] }
testcase { 0x62, 0x62, 0x7d, 0x58, 0x44, 0x72, 0x7f }, { vplzcntd zmm30,DWORD [rdx+0x1fc]{1to16} }
testcase { 0x62, 0x62, 0x7d, 0x58, 0x44, 0xb2, 0x00, 0x02, 0x00, 0x00 }, { vplzcntd zmm30,DWORD [rdx+0x200]{1to16} }
testcase { 0x62, 0x62, 0x7d, 0x58, 0x44, 0x72, 0x80 }, { vplzcntd zmm30,DWORD [rdx-0x200]{1to16} }
testcase { 0x62, 0x62, 0x7d, 0x58, 0x44, 0xb2, 0xfc, 0xfd, 0xff, 0xff }, { vplzcntd zmm30,DWORD [rdx-0x204]{1to16} }
testcase { 0x62, 0x02, 0xfd, 0x48, 0x44, 0xf5 }, { vplzcntq zmm30,zmm29 }
testcase { 0x62, 0x02, 0xfd, 0x4f, 0x44, 0xf5 }, { vplzcntq zmm30{k7},zmm29 }
testcase { 0x62, 0x02, 0xfd, 0xcf, 0x44, 0xf5 }, { vplzcntq zmm30{k7}{z},zmm29 }
testcase { 0x62, 0x62, 0xfd, 0x48, 0x44, 0x31 }, { vplzcntq zmm30,ZWORD [rcx] }
testcase { 0x62, 0x22, 0xfd, 0x48, 0x44, 0xb4, 0xf0, 0x23, 0x01, 0x00, 0x00 }, { vplzcntq zmm30,ZWORD [rax+r14*8+0x123] }
testcase { 0x62, 0x62, 0xfd, 0x58, 0x44, 0x31 }, { vplzcntq zmm30,QWORD [rcx]{1to8} }
testcase { 0x62, 0x62, 0xfd, 0x48, 0x44, 0x72, 0x7f }, { vplzcntq zmm30,ZWORD [rdx+0x1fc0] }
testcase { 0x62, 0x62, 0xfd, 0x48, 0x44, 0xb2, 0x00, 0x20, 0x00, 0x00 }, { vplzcntq zmm30,ZWORD [rdx+0x2000] }
testcase { 0x62, 0x62, 0xfd, 0x48, 0x44, 0x72, 0x80 }, { vplzcntq zmm30,ZWORD [rdx-0x2000] }
testcase { 0x62, 0x62, 0xfd, 0x48, 0x44, 0xb2, 0xc0, 0xdf, 0xff, 0xff }, { vplzcntq zmm30,ZWORD [rdx-0x2040] }
testcase { 0x62, 0x62, 0xfd, 0x58, 0x44, 0x72, 0x7f }, { vplzcntq zmm30,QWORD [rdx+0x3f8]{1to8} }
testcase { 0x62, 0x62, 0xfd, 0x58, 0x44, 0xb2, 0x00, 0x04, 0x00, 0x00 }, { vplzcntq zmm30,QWORD [rdx+0x400]{1to8} }
testcase { 0x62, 0x62, 0xfd, 0x58, 0x44, 0x72, 0x80 }, { vplzcntq zmm30,QWORD [rdx-0x400]{1to8} }
testcase { 0x62, 0x62, 0xfd, 0x58, 0x44, 0xb2, 0xf8, 0xfb, 0xff, 0xff }, { vplzcntq zmm30,QWORD [rdx-0x408]{1to8} }
testcase { 0x62, 0x92, 0x16, 0x40, 0x27, 0xec }, { vptestnmd k5,zmm29,zmm28 }
testcase { 0x62, 0x92, 0x16, 0x47, 0x27, 0xec }, { vptestnmd k5{k7},zmm29,zmm28 }
testcase { 0x62, 0xf2, 0x16, 0x40, 0x27, 0x29 }, { vptestnmd k5,zmm29,ZWORD [rcx] }
testcase { 0x62, 0xb2, 0x16, 0x40, 0x27, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00 }, { vptestnmd k5,zmm29,ZWORD [rax+r14*8+0x123] }
testcase { 0x62, 0xf2, 0x16, 0x50, 0x27, 0x29 }, { vptestnmd k5,zmm29,DWORD [rcx]{1to16} }
testcase { 0x62, 0xf2, 0x16, 0x40, 0x27, 0x6a, 0x7f }, { vptestnmd k5,zmm29,ZWORD [rdx+0x1fc0] }
testcase { 0x62, 0xf2, 0x16, 0x40, 0x27, 0xaa, 0x00, 0x20, 0x00, 0x00 }, { vptestnmd k5,zmm29,ZWORD [rdx+0x2000] }
testcase { 0x62, 0xf2, 0x16, 0x40, 0x27, 0x6a, 0x80 }, { vptestnmd k5,zmm29,ZWORD [rdx-0x2000] }
testcase { 0x62, 0xf2, 0x16, 0x40, 0x27, 0xaa, 0xc0, 0xdf, 0xff, 0xff }, { vptestnmd k5,zmm29,ZWORD [rdx-0x2040] }
testcase { 0x62, 0xf2, 0x16, 0x50, 0x27, 0x6a, 0x7f }, { vptestnmd k5,zmm29,DWORD [rdx+0x1fc]{1to16} }
testcase { 0x62, 0xf2, 0x16, 0x50, 0x27, 0xaa, 0x00, 0x02, 0x00, 0x00 }, { vptestnmd k5,zmm29,DWORD [rdx+0x200]{1to16} }
testcase { 0x62, 0xf2, 0x16, 0x50, 0x27, 0x6a, 0x80 }, { vptestnmd k5,zmm29,DWORD [rdx-0x200]{1to16} }
testcase { 0x62, 0xf2, 0x16, 0x50, 0x27, 0xaa, 0xfc, 0xfd, 0xff, 0xff }, { vptestnmd k5,zmm29,DWORD [rdx-0x204]{1to16} }
testcase { 0x62, 0x92, 0x96, 0x40, 0x27, 0xec }, { vptestnmq k5,zmm29,zmm28 }
testcase { 0x62, 0x92, 0x96, 0x47, 0x27, 0xec }, { vptestnmq k5{k7},zmm29,zmm28 }
testcase { 0x62, 0xf2, 0x96, 0x40, 0x27, 0x29 }, { vptestnmq k5,zmm29,ZWORD [rcx] }
testcase { 0x62, 0xb2, 0x96, 0x40, 0x27, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00 }, { vptestnmq k5,zmm29,ZWORD [rax+r14*8+0x123] }
testcase { 0x62, 0xf2, 0x96, 0x50, 0x27, 0x29 }, { vptestnmq k5,zmm29,QWORD [rcx]{1to8} }
testcase { 0x62, 0xf2, 0x96, 0x40, 0x27, 0x6a, 0x7f }, { vptestnmq k5,zmm29,ZWORD [rdx+0x1fc0] }
testcase { 0x62, 0xf2, 0x96, 0x40, 0x27, 0xaa, 0x00, 0x20, 0x00, 0x00 }, { vptestnmq k5,zmm29,ZWORD [rdx+0x2000] }
testcase { 0x62, 0xf2, 0x96, 0x40, 0x27, 0x6a, 0x80 }, { vptestnmq k5,zmm29,ZWORD [rdx-0x2000] }
testcase { 0x62, 0xf2, 0x96, 0x40, 0x27, 0xaa, 0xc0, 0xdf, 0xff, 0xff }, { vptestnmq k5,zmm29,ZWORD [rdx-0x2040] }
testcase { 0x62, 0xf2, 0x96, 0x50, 0x27, 0x6a, 0x7f }, { vptestnmq k5,zmm29,QWORD [rdx+0x3f8]{1to8} }
testcase { 0x62, 0xf2, 0x96, 0x50, 0x27, 0xaa, 0x00, 0x04, 0x00, 0x00 }, { vptestnmq k5,zmm29,QWORD [rdx+0x400]{1to8} }
testcase { 0x62, 0xf2, 0x96, 0x50, 0x27, 0x6a, 0x80 }, { vptestnmq k5,zmm29,QWORD [rdx-0x400]{1to8} }
testcase { 0x62, 0xf2, 0x96, 0x50, 0x27, 0xaa, 0xf8, 0xfb, 0xff, 0xff }, { vptestnmq k5,zmm29,QWORD [rdx-0x408]{1to8} }
testcase { 0x62, 0x62, 0x7e, 0x48, 0x3a, 0xf6 }, { vpbroadcastmw2d zmm30,k6 }
testcase { 0x62, 0x62, 0xfe, 0x48, 0x2a, 0xf6 }, { vpbroadcastmb2q zmm30,k6 }

BIN
travis/test/avx512cd.bin.t Normal file

Binary file not shown.

12
travis/test/avx512cd.json Normal file
View file

@ -0,0 +1,12 @@
[
{
"description": "Test AVX512CD instructions",
"id": "avx512cd",
"format": "bin",
"source": "avx512cd.asm",
"option": "-O0 -DSRC",
"target": [
{ "output": "avx512cd.bin" }
]
}
]

Some files were not shown because too many files have changed in this diff Show more