mirror of
https://github.com/netwide-assembler/nasm
synced 2026-08-26 16:23:04 -04:00
Merge branch 'master' of ssh://repo.or.cz/nasm
This commit is contained in:
commit
a0ed5b3ffa
470 changed files with 37742 additions and 1672 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -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
10
.travis.yml
Normal 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
|
||||
35
Makefile.in
35
Makefile.in
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
23
README
|
|
@ -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
19
README.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
NASM, the Netwide Assembler
|
||||
===========================
|
||||
|
||||
[](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.
|
||||
235
asm/assemble.c
235
asm/assemble.c
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -399,6 +399,7 @@ bool process_directives(char *directive)
|
|||
"in pass two");
|
||||
in_absolute = true;
|
||||
location.segment = NO_SEG;
|
||||
location.offset = absolute.offset;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
286
asm/error.c
286
asm/error.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
32
asm/float.c
32
asm/float.c
|
|
@ -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;
|
||||
|
|
|
|||
66
asm/labels.c
66
asm/labels.c
|
|
@ -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, ©offset);
|
||||
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;
|
||||
|
|
|
|||
263
asm/nasm.c
263
asm/nasm.c
|
|
@ -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, ¶m, 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, ¤tfile);
|
||||
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++) {
|
||||
|
|
|
|||
54
asm/parser.c
54
asm/parser.c
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
30
asm/pragma.c
30
asm/pragma.c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
577
asm/preproc.c
577
asm/preproc.c
File diff suppressed because it is too large
Load diff
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
206
doc/nasmdoc.src
206
doc/nasmdoc.src
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
30
doc/pspdf.pl
30
doc/pspdf.pl
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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? */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
734
output/elf.h
734
output/elf.h
|
|
@ -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
282
output/macho.h
Normal 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 */
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
188
output/stabs.h
188
output/stabs.h
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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 $<
|
||||
|
|
|
|||
|
|
@ -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
25
test/ctxlocal.asm
Normal 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
10
test/elf_visibility.asm
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
global foo
|
||||
global foo_hidden:function hidden
|
||||
|
||||
SECTION .text align=16
|
||||
|
||||
foo:
|
||||
foo_hidden:
|
||||
foo_label:
|
||||
ret
|
||||
|
||||
|
|
@ -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
12
test/v4.asm
Normal 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]
|
||||
|
|
@ -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
104
travis/README.md
Normal 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
425
travis/nasm-t.py
Executable 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
17
travis/t.json
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[
|
||||
{
|
||||
"description": "",
|
||||
"id": "",
|
||||
"format": "",
|
||||
"source": "",
|
||||
"option": "",
|
||||
"target": [
|
||||
{ "output": "" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"ref": "",
|
||||
"option": ""
|
||||
}
|
||||
]
|
||||
4
travis/test/_file_.asm
Normal file
4
travis/test/_file_.asm
Normal 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
BIN
travis/test/_file_.bin.t
Normal file
Binary file not shown.
8
travis/test/_file_.json
Normal file
8
travis/test/_file_.json
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"description": "Check the __FILE__ preprocessor directive",
|
||||
"format": "bin",
|
||||
"source": "_file_.asm",
|
||||
"target": [
|
||||
{ "output": "_file_.bin" }
|
||||
]
|
||||
}
|
||||
7
travis/test/_version.json
Normal file
7
travis/test/_version.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"description": "Check the NASM version",
|
||||
"target": [
|
||||
{ "option": "-v", "stdout": "_version.stdout" }
|
||||
],
|
||||
"error": "over"
|
||||
}
|
||||
1
travis/test/_version.stdout
Normal file
1
travis/test/_version.stdout
Normal file
|
|
@ -0,0 +1 @@
|
|||
NASM version 2.15rc0 compiled on Nov 3 2018
|
||||
7
travis/test/a32offs.asm
Normal file
7
travis/test/a32offs.asm
Normal 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
|
||||
1
travis/test/a32offs.bin.t
Normal file
1
travis/test/a32offs.bin.t
Normal file
|
|
@ -0,0 +1 @@
|
|||
g<EFBFBD>g<EFBFBD>g<EFBFBD>g<EFBFBD>
|
||||
18
travis/test/a32offs.json
Normal file
18
travis/test/a32offs.json
Normal 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
38
travis/test/absolute.asm
Normal 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
|
||||
1
travis/test/absolute.bin.t
Normal file
1
travis/test/absolute.bin.t
Normal 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>
|
||||
8
travis/test/absolute.json
Normal file
8
travis/test/absolute.json
Normal 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
15
travis/test/addr64x.asm
Normal 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
BIN
travis/test/addr64x.bin.t
Normal file
Binary file not shown.
25
travis/test/addr64x.json
Normal file
25
travis/test/addr64x.json
Normal 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"
|
||||
}
|
||||
]
|
||||
4
travis/test/addr64x.stderr
Normal file
4
travis/test/addr64x.stderr
Normal 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
16
travis/test/align13.asm
Normal 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
25
travis/test/align13.json
Normal 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"
|
||||
}
|
||||
]
|
||||
4
travis/test/align13.stderr
Normal file
4
travis/test/align13.stderr
Normal 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
17
travis/test/align13s.asm
Normal 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
25
travis/test/align13s.json
Normal 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"
|
||||
}
|
||||
]
|
||||
3
travis/test/align13s.stderr
Normal file
3
travis/test/align13s.stderr
Normal 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
|
||||
163
travis/test/alonesym-obj.asm
Normal file
163
travis/test/alonesym-obj.asm
Normal 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
|
||||
18
travis/test/alonesym-obj.json
Normal file
18
travis/test/alonesym-obj.json
Normal 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
|
||||
}
|
||||
]
|
||||
BIN
travis/test/alonesym-obj.obj.t
Normal file
BIN
travis/test/alonesym-obj.obj.t
Normal file
Binary file not shown.
12
travis/test/andbyte.asm
Normal file
12
travis/test/andbyte.asm
Normal 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
|
||||
1
travis/test/andbyte.bin.t
Normal file
1
travis/test/andbyte.bin.t
Normal file
|
|
@ -0,0 +1 @@
|
|||
ƒִנƒִנƒװנƒװנƒהנƒהנƒ<EFBFBD>נƒ<EFBFBD>נƒלנƒלנ
|
||||
17
travis/test/andbyte.json
Normal file
17
travis/test/andbyte.json
Normal 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
BIN
travis/test/aoutso-o0.o.t
Normal file
Binary file not shown.
BIN
travis/test/aoutso-ox.o.t
Normal file
BIN
travis/test/aoutso-ox.o.t
Normal file
Binary file not shown.
96
travis/test/aoutso.asm
Normal file
96
travis/test/aoutso.asm
Normal 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
22
travis/test/aoutso.json
Normal 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" }
|
||||
]
|
||||
}
|
||||
]
|
||||
1
travis/test/aoutso.stderr
Normal file
1
travis/test/aoutso.stderr
Normal 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
BIN
travis/test/aouttest-o0.o.t
Normal file
Binary file not shown.
BIN
travis/test/aouttest-ox.o.t
Normal file
BIN
travis/test/aouttest-ox.o.t
Normal file
Binary file not shown.
83
travis/test/aouttest.asm
Normal file
83
travis/test/aouttest.asm
Normal 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
20
travis/test/aouttest.json
Normal 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
43
travis/test/avx.asm
Normal 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
BIN
travis/test/avx.bin.t
Normal file
Binary file not shown.
18
travis/test/avx.json
Normal file
18
travis/test/avx.json
Normal 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
527
travis/test/avx005.asm
Normal 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
BIN
travis/test/avx005.bin.t
Normal file
Binary file not shown.
12
travis/test/avx005.json
Normal file
12
travis/test/avx005.json
Normal 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
105
travis/test/avx512cd.asm
Normal 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
BIN
travis/test/avx512cd.bin.t
Normal file
Binary file not shown.
12
travis/test/avx512cd.json
Normal file
12
travis/test/avx512cd.json
Normal 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
Loading…
Add table
Add a link
Reference in a new issue