summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Kanios <keith@kanios.net>2009-07-07 23:55:03 -0500
committerKeith Kanios <keith@kanios.net>2009-07-07 23:55:03 -0500
commitfabb245a364fbc071f4ac3ae7aaf90a190892e44 (patch)
tree2c782650c7f5640d684504a70b522016b0cb132f
parentf6131ee4954086a19c34de9c761d4618017d7b84 (diff)
downloadnasm-fabb245a364fbc071f4ac3ae7aaf90a190892e44.tar.gz
Push files missed during last commit.
-rw-r--r--headers/c33
-rw-r--r--headers/doc33
-rw-r--r--headers/mac33
-rw-r--r--headers/perl33
-rwxr-xr-xmisc/genfma.pl63
-rw-r--r--misc/omfdump.c223
-rw-r--r--nasm.nsi112
-rw-r--r--output/dwarf.h59
-rw-r--r--output/elf32.h167
-rw-r--r--output/elf64.h189
-rw-r--r--output/elfcommon.h250
-rw-r--r--output/nulldbg.c89
-rw-r--r--output/outaout.mac37
-rw-r--r--output/outas86.mac37
-rw-r--r--output/outelf.c67
-rw-r--r--output/outelf.h96
-rw-r--r--output/outform.c101
-rw-r--r--output/outform.h344
-rw-r--r--output/outlib.c56
-rw-r--r--output/outlib.h55
-rw-r--r--output/outmacho.mac37
-rw-r--r--output/outmacho32.c1382
-rw-r--r--output/outmacho64.c1528
-rw-r--r--rbtree.c119
-rw-r--r--rbtree.h52
-rw-r--r--rdoff/rdf2ihx.11
-rw-r--r--rdoff/rdf2ith.11
-rw-r--r--rdoff/rdf2srec.11
-rw-r--r--test/align13.asm16
-rw-r--r--test/align13s.asm16
-rw-r--r--test/andbyte.asm15
-rw-r--r--test/avx005.asm529
-rw-r--r--test/br2148476.asm221
-rw-r--r--test/br2222615.asm19
-rw-r--r--test/br890790.asm7
-rw-r--r--test/br890790_i.asm1
-rw-r--r--test/crc32.asm37
-rw-r--r--test/elf64so.asm118
-rw-r--r--test/elftest64.c43
-rw-r--r--test/fwdopt.asm133
-rw-r--r--test/fwdoptpp.asm150
-rw-r--r--test/gotoff64.asm25
-rw-r--r--test/ifelse.asm46
-rw-r--r--test/immwarn.asm91
-rw-r--r--test/imul.asm90
-rw-r--r--test/optimization.asm104
-rw-r--r--test/pinsr16.asm52
-rw-r--r--test/pinsr32.asm52
-rw-r--r--test/pinsr64.asm68
-rw-r--r--test/popcnt.asm32
-rw-r--r--test/ppindirect.asm42
-rw-r--r--test/pushseg.asm17
-rw-r--r--test/riprel2.asm11
-rw-r--r--test/smartalign16.asm36
-rw-r--r--test/smartalign32.asm36
-rw-r--r--test/smartalign64.asm36
-rw-r--r--test/struc.asm33
-rw-r--r--test/weirdpaste.asm29
-rw-r--r--ver.c51
59 files changed, 7354 insertions, 0 deletions
diff --git a/headers/c b/headers/c
new file mode 100644
index 00000000..31157c44
--- /dev/null
+++ b/headers/c
@@ -0,0 +1,33 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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.
+ *
+ * ----------------------------------------------------------------------- */
+
diff --git a/headers/doc b/headers/doc
new file mode 100644
index 00000000..38ab1332
--- /dev/null
+++ b/headers/doc
@@ -0,0 +1,33 @@
+\# --------------------------------------------------------------------------
+\#
+\# Copyright 1996-2009 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.
+\#
+\# --------------------------------------------------------------------------
+
diff --git a/headers/mac b/headers/mac
new file mode 100644
index 00000000..b68288f6
--- /dev/null
+++ b/headers/mac
@@ -0,0 +1,33 @@
+;; --------------------------------------------------------------------------
+;;
+;; Copyright 1996-2009 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.
+;;
+;; --------------------------------------------------------------------------
+
diff --git a/headers/perl b/headers/perl
new file mode 100644
index 00000000..23170882
--- /dev/null
+++ b/headers/perl
@@ -0,0 +1,33 @@
+## --------------------------------------------------------------------------
+##
+## Copyright 1996-2009 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.
+##
+## --------------------------------------------------------------------------
+
diff --git a/misc/genfma.pl b/misc/genfma.pl
new file mode 100755
index 00000000..2b6a65c5
--- /dev/null
+++ b/misc/genfma.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+%packed_insns = (
+ 'vfmadd' => 0x98,
+ 'vfmaddsub' => 0x96,
+ 'vfmsubadd' => 0x97,
+ 'vfmsub' => 0x9a,
+ 'vfnmadd' => 0x9c,
+ 'vfnmsub' => 0x9e
+ );
+
+%scalar_insns = (
+ 'vfmadd' => 0x99,
+ 'vfmsub' => 0x9b,
+ 'vfnmadd' => 0x9d,
+ 'vfnmsub' => 0x9f
+ );
+
+foreach $pi ( sort(keys(%packed_insns)) ) {
+ $op = $packed_insns{$pi};
+ foreach $order ('132', '213', '231') {
+ $xorder = substr($order,1,1).substr($order,0,1).substr($order,2,1);
+ foreach $o ($order, $xorder) {
+ for ($w = 0; $w < 2; $w++) {
+ $suf = $w ? 'pd' : 'ps';
+ for ($l = 128; $l <= 256; $l <<= 1) {
+ $sx = ($l == 256) ? 'SY' : 'SO';
+ $mm = ($l == 256) ? 'ymm' : 'xmm';
+ printf "%-15s %-31s %-8s%-39s %s\n",
+ "\U${pi}${o}${suf}",
+ "${mm}reg,${mm}reg,${mm}rm",
+ "[rvm:",
+ sprintf("vex.dds.%d.66.0f38.w%d %02x /r]",
+ $l, $w, $op),
+ "FMA,FUTURE,${sx}";
+ }
+ }
+ }
+ $op += 0x10;
+ }
+}
+
+foreach $si ( sort(keys(%scalar_insns)) ) {
+ $op = $scalar_insns{$si};
+ foreach $order ('132', '213', '231') {
+ $xorder = substr($order,1,1).substr($order,0,1).substr($order,2,1);
+ foreach $o ($order, $xorder) {
+ for ($w = 0; $w < 2; $w++) {
+ $suf = $w ? 'sd' : 'ss';
+ $sx = $w ? 'SQ' : 'SD';
+ $l = 128;
+ $mm = 'xmm';
+ printf "%-15s %-31s %-8s%-39s %s\n",
+ "\U${si}${o}${suf}",
+ "${mm}reg,${mm}reg,${mm}rm",
+ '[rvm:',
+ sprintf("vex.dds.%d.66.0f38.w%d %02x /r]",
+ $l, $w, $op),
+ "FMA,FUTURE,${sx}";
+ }
+ }
+ $op += 0x10;
+ }
+}
diff --git a/misc/omfdump.c b/misc/omfdump.c
new file mode 100644
index 00000000..322971e9
--- /dev/null
+++ b/misc/omfdump.c
@@ -0,0 +1,223 @@
+/*
+ * omfdump.c
+ *
+ * Very simple program to dump the contents of an OMF (OBJ) file
+ *
+ * This assumes a littleendian, unaligned-load-capable host and a
+ * C compiler which handles basic C99.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+const char *progname;
+
+static const char *record_types[256] =
+{
+ [0x80] = "THEADR",
+ [0x82] = "LHEADR",
+ [0x88] = "COMENT",
+ [0x8a] = "MODEND16",
+ [0x8b] = "MODEND32",
+ [0x8c] = "EXTDEF",
+ [0x90] = "PUBDEF16",
+ [0x91] = "PUBDEF32",
+ [0x94] = "LINNUM16",
+ [0x95] = "LINNUM32",
+ [0x96] = "LNAMES",
+ [0x98] = "SEGDEF16",
+ [0x99] = "SEGDEF32",
+ [0x9a] = "GRPDEF",
+ [0x9c] = "FIXUPP16",
+ [0x9d] = "FIXUPP32",
+ [0xa0] = "LEDATA16",
+ [0xa1] = "LEDATA32",
+ [0xa2] = "LIDATA16",
+ [0xa3] = "LIDATA32",
+ [0xb0] = "COMDEF",
+ [0xb2] = "BAKPAT16",
+ [0xb3] = "BAKPAT32",
+ [0xb4] = "LEXTDEF",
+ [0xb6] = "LPUBDEF16",
+ [0xb7] = "LPUBDEF32",
+ [0xb8] = "LCOMDEF",
+ [0xbc] = "CEXTDEF",
+ [0xc2] = "COMDAT16",
+ [0xc3] = "COMDAT32",
+ [0xc4] = "LINSYM16",
+ [0xc5] = "LINSYM32",
+ [0xc6] = "ALIAS",
+ [0xc8] = "NBKPAT16",
+ [0xc9] = "NBKPAT32",
+ [0xca] = "LLNAMES",
+ [0xcc] = "VERNUM",
+ [0xce] = "VENDEXT",
+ [0xf0] = "LIBHDR",
+ [0xf1] = "LIBEND",
+};
+
+typedef void (*dump_func)(uint8_t, const uint8_t *, size_t);
+
+static void hexdump_data(unsigned int offset, const uint8_t *data, size_t n)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < n; i += 16) {
+ printf(" %04x: ", i+offset);
+ for (j = 0; j < 16; j++) {
+ if (i+j < n)
+ printf("%02x%c", data[i+j], (j == 7) ? '-' : ' ');
+ else
+ printf(" ");
+ }
+ printf(" : ");
+ for (j = 0; j < 16; j++) {
+ if (i+j < n)
+ putchar(isprint(data[i+j]) ? data[i+j] : '.');
+ }
+ putchar('\n');
+ }
+}
+
+static void dump_unknown(uint8_t type, const uint8_t *data, size_t n)
+{
+ (void)type;
+ hexdump_data(0, data, n);
+}
+
+static void dump_coment(uint8_t type, const uint8_t *data, size_t n)
+{
+ uint8_t class;
+ static const char *coment_class[256] = {
+ [0x00] = "Translator",
+ [0x01] = "Copyright",
+ [0x81] = "Library specifier",
+ [0x9c] = "MS-DOS version",
+ [0x9d] = "Memory model",
+ [0x9e] = "DOSSEG",
+ [0x9f] = "Library search",
+ [0xa0] = "OMF extensions",
+ [0xa1] = "New OMF extension",
+ [0xa2] = "Link pass separator",
+ [0xa3] = "LIBMOD",
+ [0xa4] = "EXESTR",
+ [0xa6] = "INCERR",
+ [0xa7] = "NOPAD",
+ [0xa8] = "WKEXT",
+ [0xa9] = "LZEXT",
+ [0xda] = "Comment",
+ [0xdb] = "Compiler",
+ [0xdc] = "Date",
+ [0xdd] = "Timestamp",
+ [0xdf] = "User",
+ [0xe9] = "Dependency file",
+ [0xff] = "Command line"
+ };
+
+ if (n < 2) {
+ dump_unknown(type, data, n);
+ return;
+ }
+
+ type = data[0];
+ class = data[1];
+
+ printf(" [NP=%d NL=%d UD=%02X] %02X %s\n",
+ (type >> 7) & 1,
+ (type >> 6) & 1,
+ type & 0x3f,
+ class,
+ coment_class[class] ? coment_class[class] : "???");
+
+ hexdump_data(2, data+2, n-2);
+}
+
+static const dump_func dump_type[256] =
+{
+ [0x88] = dump_coment,
+};
+
+int dump_omf(int fd)
+{
+ struct stat st;
+ size_t len, n;
+ uint8_t type;
+ const uint8_t *p, *data;
+
+ if (fstat(fd, &st))
+ return -1;
+
+ len = st.st_size;
+
+ data = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (data == MAP_FAILED)
+ return -1;
+
+ p = data;
+ while (len >= 3) {
+ uint8_t csum;
+ int i;
+
+ type = p[0];
+ n = *(uint16_t *)(p+1);
+
+ printf("%02x %-10s %4zd bytes",
+ type,
+ record_types[type] ? record_types[type] : "???",
+ n);
+
+ if (len < n+3) {
+ printf("\n (truncated, only %zd bytes left)\n", len-3);
+ break; /* Truncated */
+ }
+
+ p += 3; /* Header doesn't count in the length */
+ n--; /* Remove checksum byte */
+
+ csum = 0;
+ for (i = -3; i < (int)n; i++)
+ csum -= p[i];
+
+ printf(", checksum %02X", p[i]);
+ if (csum == p[i])
+ printf(" (valid)\n");
+ else
+ printf(" (actual = %02X)\n", csum);
+
+ if (dump_type[type])
+ dump_type[type](type, p, n);
+ else
+ dump_unknown(type, p, n);
+
+ p += n+1;
+ len -= (n+4);
+ }
+
+ munmap((void *)data, st.st_size);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int fd;
+ int i;
+
+ progname = argv[0];
+
+ for (i = 1; i < argc; i++) {
+ fd = open(argv[i], O_RDONLY);
+ if (fd < 0 || dump_omf(fd)) {
+ perror(argv[i]);
+ return 1;
+ }
+ close(fd);
+ }
+
+ return 0;
+}
diff --git a/nasm.nsi b/nasm.nsi
new file mode 100644
index 00000000..ba6b4a25
--- /dev/null
+++ b/nasm.nsi
@@ -0,0 +1,112 @@
+#!Nsis Installer Command Script
+
+# Copyright (c) 2009, Shao Miller (shao.miller@yrdsb.edu.on.ca)
+# All rights reserved.
+#
+# 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 <copyright holder> 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.
+
+!include "version.nsh"
+!define PRODUCT_NAME "Netwide Assembler"
+!define PRODUCT_SHORT_NAME "nasm"
+!define PACKAGE_NAME "${PRODUCT_NAME} ${VERSION}"
+!define PACKAGE_SHORT_NAME "${PRODUCT_SHORT_NAME}-${VERSION}"
+
+Name "${PACKAGE_NAME}"
+OutFile "${PACKAGE_SHORT_NAME}-installer.exe"
+InstallDir "$PROGRAMFILES\NASM"
+InstallDirRegKey HKLM "SOFTWARE\${PACKAGE_SHORT_NAME}" "InstallDir"
+SetCompressor lzma
+
+XPStyle on
+
+DirText "Please select the installation folder."
+Page directory
+
+ComponentText "Select which optional components you want to install."
+Page components
+
+ShowInstDetails hide
+ShowUninstDetails hide
+Page instfiles
+
+Section "${PACKAGE_NAME}"
+ SectionIn RO
+
+ SetOutPath "$INSTDIR\."
+ File "LICENSE"
+ File "nasm.exe"
+ File "ndisasm.exe"
+ File "doc/nasmdoc.pdf"
+ File "rdoff/ldrdf.exe"
+ File "rdoff/rdf2bin.exe"
+ File "rdoff/rdf2com.exe"
+ File "rdoff/rdf2ith.exe"
+ File "rdoff/rdf2ihx.exe"
+ File "rdoff/rdf2srec.exe"
+ File "rdoff/rdfdump.exe"
+ File "rdoff/rdflib.exe"
+ File "rdoff/rdx.exe"
+ FileOpen $0 "nasmpath.bat" w
+ IfErrors skip
+ FileWrite $0 "@set path=$INSTDIR;%path%$\r$\n"
+ FileWrite $0 "@%comspec%"
+ FileClose $0
+ skip:
+SectionEnd
+
+Section "Start Menu Shortcuts"
+ CreateDirectory "$SMPROGRAMS\${PACKAGE_NAME}"
+ CreateShortCut "$SMPROGRAMS\${PACKAGE_NAME}\Uninstall ${PACKAGE_NAME}.lnk" "$INSTDIR\Uninstall ${PACKAGE_NAME}.exe" "" "$INSTDIR\Uninstall ${PACKAGE_NAME}.exe" 0
+ CreateShortCut "$SMPROGRAMS\${PACKAGE_NAME}\NASM Shell.lnk" "$INSTDIR\nasmpath.bat" "" "$INSTDIR\nasmpath.bat" 0
+ CreateShortCut "$SMPROGRAMS\${PACKAGE_NAME}\NASM Manual.lnk" "$INSTDIR\nasmdoc.pdf" "" "$INSTDIR\nasmdoc.pdf" 0
+SectionEnd
+
+Section "Desktop Icons"
+ CreateShortCut "$DESKTOP\NASM.lnk" "$INSTDIR\nasmpath.bat" "" "$INSTDIR\nasmpath.bat" 0
+SectionEnd
+
+Section "Uninstall"
+ Delete /rebootok "$DESKTOP\NASM.lnk"
+ Delete /rebootok "$SMPROGRAMS\${PACKAGE_NAME}\NASM Shell.lnk"
+ Delete /rebootok "$SMPROGRAMS\${PACKAGE_NAME}\NASM Manual.lnk"
+ Delete /rebootok "$SMPROGRAMS\${PACKAGE_NAME}\Uninstall ${PACKAGE_NAME}.lnk"
+ RMDir "$SMPROGRAMS\${PACKAGE_NAME}"
+
+ Delete /rebootok "$INSTDIR\nasmpath.bat"
+ Delete /rebootok "$INSTDIR\rdx.exe"
+ Delete /rebootok "$INSTDIR\rdflib.exe"
+ Delete /rebootok "$INSTDIR\rdfdump.exe"
+ Delete /rebootok "$INSTDIR\rdf2srec.exe"
+ Delete /rebootok "$INSTDIR\rdf2ihx.exe"
+ Delete /rebootok "$INSTDIR\rdf2ith.exe"
+ Delete /rebootok "$INSTDIR\rdf2com.exe"
+ Delete /rebootok "$INSTDIR\rdf2bin.exe"
+ Delete /rebootok "$INSTDIR\ndisasm.exe"
+ Delete /rebootok "$INSTDIR\nasmdoc.pdf"
+ Delete /rebootok "$INSTDIR\nasm.exe"
+ Delete /rebootok "$INSTDIR\ldrdf.exe"
+ Delete /rebootok "$INSTDIR\LICENSE"
+ RMDir "$INSTDIR"
+SectionEnd
+
+Section -post
+ WriteUninstaller "$INSTDIR\Uninstall ${PACKAGE_NAME}.exe"
+SectionEnd
+
diff --git a/output/dwarf.h b/output/dwarf.h
new file mode 100644
index 00000000..4994464b
--- /dev/null
+++ b/output/dwarf.h
@@ -0,0 +1,59 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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_DWARF_H
+#define OUTPUT_DWARF_H
+
+#define DW_TAG_compile_unit 0x11
+#define DW_TAG_subprogram 0x2e
+#define DW_AT_name 0x03
+#define DW_AT_stmt_list 0x10
+#define DW_AT_low_pc 0x11
+#define DW_AT_high_pc 0x12
+#define DW_AT_language 0x13
+#define DW_AT_producer 0x25
+#define DW_AT_frame_base 0x40
+#define DW_FORM_addr 0x01
+#define DW_FORM_data2 0x05
+#define DW_FORM_data4 0x06
+#define DW_FORM_string 0x08
+#define DW_LNS_extended_op 0
+#define DW_LNS_advance_pc 2
+#define DW_LNS_advance_line 3
+#define DW_LNS_set_file 4
+#define DW_LNE_end_sequence 1
+#define DW_LNE_set_address 2
+#define DW_LNE_define_file 3
+#define DW_LANG_Mips_Assembler 0x8001
+
+#endif /* OUTPUT_DWARF_H */
diff --git a/output/elf32.h b/output/elf32.h
new file mode 100644
index 00000000..b40a9ffa
--- /dev/null
+++ b/output/elf32.h
@@ -0,0 +1,167 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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_ELF32_H
+#define OUTPUT_ELF32_H
+
+#include "output/elfcommon.h"
+
+/* 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 uint32_t Elf32_Off;
+typedef uint32_t Elf32_Addr;
+typedef uint16_t Elf32_Section;
+
+/* Dynamic header */
+
+typedef struct elf32_dyn {
+ Elf32_Sword d_tag;
+ union {
+ Elf32_Sword d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+} Elf32_Dyn;
+
+/* Relocations */
+
+#define ELF32_R_SYM(x) ((x) >> 8)
+#define ELF32_R_TYPE(x) ((x) & 0xff)
+
+typedef struct elf32_rel {
+ 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_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 */
+};
+
+/* Symbol */
+
+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_Sym;
+
+/* Main file header */
+
+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;
+} Elf32_Ehdr;
+
+/* Program header */
+
+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_Phdr;
+
+/* Section header */
+
+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_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_Nhdr;
+
+/* How to extract and insert information held in the st_info field. */
+#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val) ((val) & 0xf)
+
+#endif /* OUTPUT_ELF32_H */
diff --git a/output/elf64.h b/output/elf64.h
new file mode 100644
index 00000000..efbc4f2f
--- /dev/null
+++ b/output/elf64.h
@@ -0,0 +1,189 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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_ELF64_H
+#define OUTPUT_ELF64_H
+
+#include "output/elfcommon.h"
+
+/* ELF standard typedefs (yet more proof that <stdint.h> was way overdue) */
+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;
+
+/* Dynamic header */
+
+typedef struct elf64_dyn {
+ Elf64_Sxword d_tag;
+ union {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } d_un;
+} Elf64_Dyn;
+
+/* Relocations */
+
+#define ELF64_R_SYM(x) ((x) >> 32)
+#define ELF64_R_TYPE(x) ((x) & 0xffffffff)
+
+typedef struct elf64_rel {
+ 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_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 */
+};
+
+/* Symbol */
+
+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_Sym;
+
+/* Main file header */
+
+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;
+} Elf64_Ehdr;
+
+/* Program header */
+
+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_Phdr;
+
+/* Section header */
+
+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_Shdr;
+
+/* Note header */
+typedef struct elf64_note {
+ Elf64_Word n_namesz; /* Name size */
+ Elf64_Word n_descsz; /* Content size */
+ Elf64_Word n_type; /* Content type */
+} Elf64_Nhdr;
+
+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */
+#define ELF64_ST_BIND(val) ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val)
+
+#endif /* OUTPUT_ELF64_H */
diff --git a/output/elfcommon.h b/output/elfcommon.h
new file mode 100644
index 00000000..608da9c8
--- /dev/null
+++ b/output/elfcommon.h
@@ -0,0 +1,250 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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_ELFCOMMON_H
+#define OUTPUT_ELFCOMMON_H
+
+#include "compiler.h"
+#include <inttypes.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? */
+
+/* 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
+
+/* 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 */
+
+/* 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
+
+/* 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 */
+/* 18..22 = ? */
+#define AT_SECURE 23 /* secure mode boolean */
+
+/* Program header permission flags */
+#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
+
+/* 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. */
+
+/* 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
+
+/* Lenght of magic at the start of a file */
+#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_PAD 8
+
+#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 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 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 */
+
+/* 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. */
+
+/* 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 */
+
+#endif /* OUTPUT_ELFCOMMON_H */
diff --git a/output/nulldbg.c b/output/nulldbg.c
new file mode 100644
index 00000000..54a45802
--- /dev/null
+++ b/output/nulldbg.c
@@ -0,0 +1,89 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include "nasm.h"
+#include "nasmlib.h"
+
+void null_debug_init(struct ofmt *of, void *id, FILE * fp, efunc error)
+{
+ (void)of;
+ (void)id;
+ (void)fp;
+ (void)error;
+}
+void null_debug_linenum(const char *filename, int32_t linenumber, int32_t segto)
+{
+ (void)filename;
+ (void)linenumber;
+ (void)segto;
+}
+void null_debug_deflabel(char *name, int32_t segment, int64_t offset,
+ int is_global, char *special)
+{
+ (void)name;
+ (void)segment;
+ (void)offset;
+ (void)is_global;
+ (void)special;
+}
+void null_debug_routine(const char *directive, const char *params)
+{
+ (void)directive;
+ (void)params;
+}
+void null_debug_typevalue(int32_t type)
+{
+ (void)type;
+}
+void null_debug_output(int type, void *param)
+{
+ (void)type;
+ (void)param;
+}
+void null_debug_cleanup(void)
+{
+}
+
+struct dfmt null_debug_form = {
+ "Null debug format",
+ "null",
+ null_debug_init,
+ null_debug_linenum,
+ null_debug_deflabel,
+ null_debug_routine,
+ null_debug_typevalue,
+ null_debug_output,
+ null_debug_cleanup
+};
+
+struct dfmt *null_debug_arr[2] = { &null_debug_form, NULL };
diff --git a/output/outaout.mac b/output/outaout.mac
new file mode 100644
index 00000000..cd23852d
--- /dev/null
+++ b/output/outaout.mac
@@ -0,0 +1,37 @@
+;; --------------------------------------------------------------------------
+;;
+;; Copyright 1996-2009 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.
+;;
+;; --------------------------------------------------------------------------
+
+OUT: aout aoutb
+%define __SECT__ [section .text]
+%macro __NASM_CDecl__ 1
+%endmacro
diff --git a/output/outas86.mac b/output/outas86.mac
new file mode 100644
index 00000000..f0bd2e41
--- /dev/null
+++ b/output/outas86.mac
@@ -0,0 +1,37 @@
+;; --------------------------------------------------------------------------
+;;
+;; Copyright 1996-2009 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.
+;;
+;; --------------------------------------------------------------------------
+
+OUT: as86
+%define __SECT__ [section .text]
+%macro __NASM_CDecl__ 1
+%endmacro
diff --git a/output/outelf.c b/output/outelf.c
new file mode 100644
index 00000000..a8654403
--- /dev/null
+++ b/output/outelf.c
@@ -0,0 +1,67 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Common code for outelf32 and outelf64
+ */
+
+#include "compiler.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "nasm.h"
+#include "output/outform.h"
+
+#include "output/elfcommon.h"
+#include "output/dwarf.h"
+#include "output/outelf.h"
+
+#if defined(OF_ELF32) || defined(OF_ELF64)
+
+const struct elf_known_section elf_known_sections[] = {
+ { ".text", SHT_PROGBITS, SHF_ALLOC|SHF_EXECINSTR, 16 },
+ { ".rodata", SHT_PROGBITS, SHF_ALLOC, 4 },
+ { ".lrodata", SHT_PROGBITS, SHF_ALLOC, 4 },
+ { ".data", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4 },
+ { ".ldata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4 },
+ { ".bss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4 },
+ { ".lbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4 },
+ { ".tdata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4 },
+ { ".tbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4 },
+ { ".comment", SHT_PROGBITS, 0, 1 },
+ { NULL, SHT_PROGBITS, SHF_ALLOC, 1 } /* default */
+};
+
+#endif /* defined(OF_ELF32) || defined(OF_ELF64) */
diff --git a/output/outelf.h b/output/outelf.h
new file mode 100644
index 00000000..a5bbd563
--- /dev/null
+++ b/output/outelf.h
@@ -0,0 +1,96 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Internal definitions common to outelf32 and outelf64
+ */
+#ifndef OUTPUT_OUTELF_H
+#define OUTPUT_OUTELF_H
+
+#define SYM_GLOBAL 0x10
+
+#define GLOBAL_TEMP_BASE 0x40000000 /* bigger than any sane symbol index */
+
+#define SEG_ALIGN 16 /* alignment of sections in file */
+#define SEG_ALIGN_1 (SEG_ALIGN-1)
+
+/* this stuff is needed for the stabs debugging format */
+#define N_SO 0x64 /* ID for main source file */
+#define N_SOL 0x84 /* ID for sub-source file */
+#define N_BINCL 0x82
+#define N_EINCL 0xA2
+#define N_SLINE 0x44
+#define TY_STABSSYMLIN 0x40 /* ouch */
+
+/* this stuff is needed for the dwarf debugging format */
+#define TY_DEBUGSYMLIN 0x40 /* internal call to debug_out */
+
+/* Known sections with nonstandard defaults */
+struct elf_known_section {
+ const char *name; /* Name of section */
+ int type; /* Section type (SHT_) */
+ uint32_t flags; /* Section flags (SHF_) */
+ uint32_t align; /* Section alignment */
+};
+extern const struct elf_known_section elf_known_sections[];
+
+/*
+ * Special ELF sections (after the real sections but before debugging ones)
+ */
+#define sec_shstrtab (nsects + 1)
+#define sec_symtab (nsects + 2)
+#define sec_strtab (nsects + 3)
+#define sec_numspecial 3
+
+/*
+ * Debugging ELF sections (last in the file)
+ */
+
+/* stabs */
+#define sec_stab (nsections-3)
+#define sec_stabstr (nsections-2)
+#define sec_rel_stab (nsections-1)
+
+/* dwarf */
+#define sec_debug_aranges (nsections-10)
+#define sec_rela_debug_aranges (nsections-9)
+#define sec_debug_pubnames (nsections-8)
+#define sec_debug_info (nsections-7)
+#define sec_rela_debug_info (nsections-6)
+#define sec_debug_abbrev (nsections-5)
+#define sec_debug_line (nsections-4)
+#define sec_rela_debug_line (nsections-3)
+#define sec_debug_frame (nsections-2)
+#define sec_debug_loc (nsections-1)
+
+#endif /* OUTPUT_OUTELF_H */
diff --git a/output/outform.c b/output/outform.c
new file mode 100644
index 00000000..f8cdca87
--- /dev/null
+++ b/output/outform.c
@@ -0,0 +1,101 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * outform.c manages a list of output formats, and associates
+ * them with their relevant drivers. Also has a
+ * routine to find the correct driver given a name
+ * for it
+ */
+
+#include "compiler.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+#define BUILD_DRIVERS_ARRAY
+#include "output/outform.h"
+
+static int ndrivers = 0;
+
+struct ofmt *ofmt_find(char *name)
+{ /* find driver */
+ int i;
+
+ for (i = 0; i < ndrivers; i++)
+ if (!strcmp(name, drivers[i]->shortname))
+ return drivers[i];
+
+ return NULL;
+}
+struct dfmt *dfmt_find(struct ofmt *ofmt, char *name)
+{ /* find driver */
+ struct dfmt **dfmt = ofmt->debug_formats;
+ while (*dfmt) {
+ if (!strcmp(name, (*dfmt)->shortname))
+ return (*dfmt);
+ dfmt++;
+ }
+ return NULL;
+}
+
+void ofmt_list(struct ofmt *deffmt, FILE * fp)
+{
+ int i;
+ for (i = 0; i < ndrivers; i++)
+ fprintf(fp, " %c %-10s%s\n",
+ drivers[i] == deffmt ? '*' : ' ',
+ drivers[i]->shortname, drivers[i]->fullname);
+}
+void dfmt_list(struct ofmt *ofmt, FILE * fp)
+{
+ struct dfmt **drivers = ofmt->debug_formats;
+ while (*drivers) {
+ fprintf(fp, " %c %-10s%s\n",
+ drivers[0] == ofmt->current_dfmt ? '*' : ' ',
+ drivers[0]->shortname, drivers[0]->fullname);
+ drivers++;
+ }
+}
+struct ofmt *ofmt_register(efunc error)
+{
+ for (ndrivers = 0; drivers[ndrivers] != NULL; ndrivers++) ;
+
+ if (ndrivers == 0) {
+ error(ERR_PANIC | ERR_NOFILE,
+ "No output drivers given at compile time");
+ }
+
+ return (&OF_DEFAULT);
+}
diff --git a/output/outform.h b/output/outform.h
new file mode 100644
index 00000000..3dfbc9c7
--- /dev/null
+++ b/output/outform.h
@@ -0,0 +1,344 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * outform.h header file for binding output format drivers to the
+ * remainder of the code in the Netwide Assembler
+ */
+
+/*
+ * This header file allows configuration of which output formats
+ * get compiled into the NASM binary. You can configure by defining
+ * various preprocessor symbols beginning with "OF_", either on the
+ * compiler command line or at the top of this file.
+ *
+ * OF_ONLY -- only include specified object formats
+ * OF_name -- ensure that output format 'name' is included
+ * OF_NO_name -- remove output format 'name'
+ * OF_DOS -- ensure that 'obj', 'bin' & 'win32' are included.
+ * OF_UNIX -- ensure that 'aout', 'aoutb', 'coff', 'elf32' 'elf64' are in.
+ * OF_OTHERS -- ensure that 'bin', 'as86' & 'rdf' are in.
+ * OF_ALL -- ensure that all formats are included.
+ * note that this doesn't include 'dbg', which is
+ * only really useful if you're doing development
+ * work on NASM. Define OF_DBG if you want this.
+ *
+ * OF_DEFAULT=of_name -- ensure that 'name' is the default format.
+ *
+ * eg: -DOF_UNIX -DOF_ELF32 -DOF_DEFAULT=of_elf32 would be a suitable config
+ * for an average linux system.
+ *
+ * Default config = -DOF_ALL -DOF_DEFAULT=of_bin
+ *
+ * You probably only want to set these options while compiling 'nasm.c'. */
+
+#ifndef NASM_OUTFORM_H
+#define NASM_OUTFORM_H
+
+#include "nasm.h"
+
+/* -------------- USER MODIFIABLE PART ---------------- */
+
+/*
+ * Insert #defines here in accordance with the configuration
+ * instructions above.
+ *
+ * E.g.
+ *
+ * #define OF_ONLY
+ * #define OF_OBJ
+ * #define OF_BIN
+ *
+ * for a 16-bit DOS assembler with no extraneous formats.
+ */
+
+/* ------------ END USER MODIFIABLE PART -------------- */
+
+/* ====configurable info begins here==== */
+/* formats configurable:
+ * bin,obj,elf32,elf64,aout,aoutb,coff,win32,as86,rdf2,macho */
+
+/* process options... */
+
+#ifndef OF_ONLY
+#ifndef OF_ALL
+#define OF_ALL /* default is to have all formats */
+#endif
+#endif
+
+#ifdef OF_ALL /* set all formats on... */
+#ifndef OF_BIN
+#define OF_BIN
+#endif
+#ifndef OF_OBJ
+#define OF_OBJ
+#endif
+#ifndef OF_ELF32
+#define OF_ELF32
+#endif
+#ifndef OF_ELF64
+#define OF_ELF64
+#endif
+#ifndef OF_COFF
+#define OF_COFF
+#endif
+#ifndef OF_AOUT
+#define OF_AOUT
+#endif
+#ifndef OF_AOUTB
+#define OF_AOUTB
+#endif
+#ifndef OF_WIN32
+#define OF_WIN32
+#endif
+#ifndef OF_WIN64
+#define OF_WIN64
+#endif
+#ifndef OF_AS86
+#define OF_AS86
+#endif
+#ifndef OF_RDF2
+#define OF_RDF2
+#endif
+#ifndef OF_IEEE
+#define OF_IEEE
+#endif
+#ifndef OF_MACHO32
+#define OF_MACHO32
+#endif
+#ifndef OF_MACHO64
+#define OF_MACHO64
+#endif
+#ifndef OF_DBG
+#define OF_DBG
+#endif
+#endif /* OF_ALL */
+
+/* turn on groups of formats specified.... */
+#ifdef OF_DOS
+#ifndef OF_OBJ
+#define OF_OBJ
+#endif
+#ifndef OF_BIN
+#define OF_BIN
+#endif
+#ifndef OF_COFF
+#define OF_COFF /* COFF is used by DJGPP */
+#endif
+#ifndef OF_WIN32
+#define OF_WIN32
+#endif
+#ifndef OF_WIN64
+#define OF_WIN64
+#endif
+#endif
+
+#ifdef OF_UNIX
+#ifndef OF_AOUT
+#define OF_AOUT
+#endif
+#ifndef OF_AOUTB
+#define OF_AOUTB
+#endif
+#ifndef OF_COFF
+#define OF_COFF
+#endif
+#ifndef OF_ELF32
+#define OF_ELF32
+#endif
+#ifndef OF_ELF64
+#define OF_ELF64
+#endif
+#endif
+
+#ifdef OF_OTHERS
+#ifndef OF_BIN
+#define OF_BIN
+#endif
+#ifndef OF_AS86
+#define OF_AS86
+#endif
+#ifndef OF_RDF2
+#define OF_RDF2
+#endif
+#ifndef OF_IEEE
+#define OF_IEEE
+#endif
+#ifndef OF_MACHO32
+#define OF_MACHO32
+#endif
+#ifndef OF_MACHO64
+#define OF_MACHO64
+#endif
+#endif
+
+/* finally... override any format specifically specified to be off */
+#ifdef OF_NO_BIN
+#undef OF_BIN
+#endif
+#ifdef OF_NO_OBJ
+#undef OF_OBJ
+#endif
+#ifdef OF_NO_ELF32
+#undef OF_ELF32
+#endif
+#ifdef OF_NO_ELF64
+#undef OF_ELF64
+#endif
+#ifdef OF_NO_AOUT
+#undef OF_AOUT
+#endif
+#ifdef OF_NO_AOUTB
+#undef OF_AOUTB
+#endif
+#ifdef OF_NO_COFF
+#undef OF_COFF
+#endif
+#ifdef OF_NO_WIN32
+#undef OF_WIN32
+#endif
+#ifdef OF_NO_WIN64
+#undef OF_WIN64
+#endif
+#ifdef OF_NO_AS86
+#undef OF_AS86
+#endif
+#ifdef OF_NO_RDF2
+#undef OF_RDF
+#endif
+#ifdef OF_NO_IEEE
+#undef OF_IEEE
+#endif
+#ifdef OF_NO_MACHO32
+#undef OF_MACHO32
+#endif
+#ifdef OF_NO_MACHO64
+#undef OF_MACHO64
+#endif
+#ifdef OF_NO_DBG
+#undef OF_DBG
+#endif
+
+#ifndef OF_DEFAULT
+#define OF_DEFAULT of_bin
+#endif
+
+#ifdef BUILD_DRIVERS_ARRAY /* only if included from outform.c */
+
+/* pull in the externs for the different formats, then make the *drivers
+ * array based on the above defines */
+
+extern struct ofmt of_bin;
+extern struct ofmt of_ith;
+extern struct ofmt of_srec;
+extern struct ofmt of_aout;
+extern struct ofmt of_aoutb;
+extern struct ofmt of_coff;
+extern struct ofmt of_elf32;
+extern struct ofmt of_elf;
+extern struct ofmt of_elf64;
+extern struct ofmt of_as86;
+extern struct ofmt of_obj;
+extern struct ofmt of_win32;
+extern struct ofmt of_win64;
+extern struct ofmt of_rdf2;
+extern struct ofmt of_ieee;
+extern struct ofmt of_macho32;
+extern struct ofmt of_macho;
+extern struct ofmt of_macho64;
+extern struct ofmt of_dbg;
+
+struct ofmt *drivers[] = {
+#ifdef OF_BIN
+ &of_bin,
+ &of_ith,
+ &of_srec,
+#endif
+#ifdef OF_AOUT
+ &of_aout,
+#endif
+#ifdef OF_AOUTB
+ &of_aoutb,
+#endif
+#ifdef OF_COFF
+ &of_coff,
+#endif
+#ifdef OF_ELF32
+ &of_elf32,
+ &of_elf,
+#endif
+#ifdef OF_ELF64
+ &of_elf64,
+#endif
+#ifdef OF_AS86
+ &of_as86,
+#endif
+#ifdef OF_OBJ
+ &of_obj,
+#endif
+#ifdef OF_WIN32
+ &of_win32,
+#endif
+#ifdef OF_WIN64
+ &of_win64,
+#endif
+#ifdef OF_RDF2
+ &of_rdf2,
+#endif
+#ifdef OF_IEEE
+ &of_ieee,
+#endif
+#ifdef OF_MACHO32
+ &of_macho32,
+ &of_macho,
+#endif
+#ifdef OF_MACHO64
+ &of_macho64,
+#endif
+#ifdef OF_DBG
+ &of_dbg,
+#endif
+
+ NULL
+};
+
+#endif /* BUILD_DRIVERS_ARRAY */
+
+struct ofmt *ofmt_find(char *);
+struct dfmt *dfmt_find(struct ofmt *, char *);
+void ofmt_list(struct ofmt *, FILE *);
+void dfmt_list(struct ofmt *ofmt, FILE * fp);
+struct ofmt *ofmt_register(efunc error);
+extern struct dfmt null_debug_form;
+
+#endif /* NASM_OUTFORM_H */
diff --git a/output/outlib.c b/output/outlib.c
new file mode 100644
index 00000000..56ac6cd5
--- /dev/null
+++ b/output/outlib.c
@@ -0,0 +1,56 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * libout.c
+ *
+ * Common routines for the output backends.
+ */
+
+#include "compiler.h"
+#include "nasm.h"
+#include "output/outlib.h"
+
+uint64_t realsize(enum out_type type, uint64_t size)
+{
+ switch (type) {
+ case OUT_REL2ADR:
+ return 2;
+ case OUT_REL4ADR:
+ return 4;
+ case OUT_REL8ADR:
+ return 8;
+ default:
+ return size;
+ }
+}
diff --git a/output/outlib.h b/output/outlib.h
new file mode 100644
index 00000000..964da5c8
--- /dev/null
+++ b/output/outlib.h
@@ -0,0 +1,55 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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 NASM_OUTLIB_H
+#define NASM_OUTLIB_H
+
+#include "nasm.h"
+
+uint64_t realsize(enum out_type type, uint64_t size);
+
+/* Do-nothing versions of all the debug routines */
+struct ofmt;
+void null_debug_init(struct ofmt *of, void *id, FILE * fp, efunc error);
+void null_debug_linenum(const char *filename, int32_t linenumber,
+ int32_t segto);
+void null_debug_deflabel(char *name, int32_t segment, int64_t offset,
+ int is_global, char *special);
+void null_debug_routine(const char *directive, const char *params);
+void null_debug_typevalue(int32_t type);
+void null_debug_output(int type, void *param);
+void null_debug_cleanup(void);
+extern struct dfmt *null_debug_arr[2];
+
+#endif /* NASM_OUTLIB_H */
+
diff --git a/output/outmacho.mac b/output/outmacho.mac
new file mode 100644
index 00000000..f1cdf180
--- /dev/null
+++ b/output/outmacho.mac
@@ -0,0 +1,37 @@
+;; --------------------------------------------------------------------------
+;;
+;; Copyright 1996-2009 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.
+;;
+;; --------------------------------------------------------------------------
+
+OUT: macho macho32 macho64
+%define __SECT__ [section .text]
+%macro __NASM_CDecl__ 1
+%endmacro
diff --git a/output/outmacho32.c b/output/outmacho32.c
new file mode 100644
index 00000000..c9e43659
--- /dev/null
+++ b/output/outmacho32.c
@@ -0,0 +1,1382 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * outmacho.c output routines for the Netwide Assembler to produce
+ * NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files
+ */
+
+/* Most of this file is, like Mach-O itself, based on a.out. For more
+ * guidelines see outaout.c. */
+
+#include "compiler.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+#include "nasm.h"
+#include "nasmlib.h"
+#include "saa.h"
+#include "raa.h"
+#include "output/outform.h"
+#include "output/outlib.h"
+
+#if defined(OF_MACHO32)
+
+/* Mach-O in-file header structure sizes */
+#define MACHO_HEADER_SIZE (28)
+#define MACHO_SEGCMD_SIZE (56)
+#define MACHO_SECTCMD_SIZE (68)
+#define MACHO_SYMCMD_SIZE (24)
+#define MACHO_NLIST_SIZE (12)
+#define MACHO_RELINFO_SIZE (8)
+
+/* Mach-O file header values */
+#define MH_MAGIC (0xfeedface)
+#define CPU_TYPE_I386 (7) /* x86 platform */
+#define CPU_SUBTYPE_I386_ALL (3) /* all-x86 compatible */
+#define MH_OBJECT (0x1) /* object file */
+
+#define LC_SEGMENT (0x1) /* segment load command */
+#define LC_SYMTAB (0x2) /* symbol table load command */
+
+#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)
+
+struct section {
+ /* nasm internal data */
+ struct section *next;
+ struct SAA *data;
+ int32_t index;
+ struct reloc *relocs;
+ int align;
+
+ /* data that goes into the file */
+ char sectname[16]; /* what this section is called */
+ char segname[16]; /* segment this section will be in */
+ uint32_t addr; /* in-memory address (subject to alignment) */
+ uint32_t size; /* in-memory and -file size */
+ uint32_t nreloc; /* relocation entry count */
+ uint32_t flags; /* type and attributes (masked) */
+};
+
+#define SECTION_TYPE 0x000000ff /* section type mask */
+
+#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 */
+
+
+static struct sectmap {
+ const char *nasmsect;
+ const char *segname;
+ const char *sectname;
+ const int32_t flags;
+} sectmap[] = {
+ {".text", "__TEXT", "__text", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS},
+ {".data", "__DATA", "__data", S_REGULAR},
+ {".rodata", "__DATA", "__const", S_REGULAR},
+ {".bss", "__DATA", "__bss", S_ZEROFILL},
+ {NULL, NULL, NULL, 0}
+};
+
+struct reloc {
+ /* nasm internal data */
+ struct reloc *next;
+
+ /* data that goes into the file */
+ int32_t addr; /* op's offset in section */
+ unsigned int snum:24, /* contains symbol index if
+ ** ext otherwise in-file
+ ** section number */
+ pcrel:1, /* relative relocation */
+ length:2, /* 0=byte, 1=word, 2=int32_t */
+ ext:1, /* external symbol referenced */
+ type:4; /* reloc type, 0 for us */
+};
+
+#define R_ABS 0 /* absolute relocation */
+#define R_SCATTERED 0x80000000 /* reloc entry is scattered if
+ ** highest bit == 1 */
+
+struct symbol {
+ /* nasm internal data */
+ struct symbol *next; /* next symbol in the list */
+ char *name; /* name of this symbol */
+ int32_t initial_snum; /* symbol number used above in
+ reloc */
+ int32_t snum; /* true snum for reloc */
+
+ /* data that goes into the file */
+ int32_t strx; /* string table index */
+ uint8_t type; /* symbol type */
+ uint8_t sect; /* NO_SECT or section number */
+ int16_t desc; /* for stab debugging, 0 for us */
+ uint32_t value; /* offset of symbol in section */
+};
+
+/* symbol type bits */
+#define N_EXT 0x01 /* global or 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;
+static struct symbol *syms, **symstail;
+static uint32_t nsyms;
+
+/* These variables are set by macho_layout_symbols() to organize
+ the symbol table and string table in order the dynamic linker
+ expects. They are then used in macho_write() to put out the
+ symbols and strings in that order.
+
+ The order of the symbol table is:
+ local symbols
+ defined external symbols (sorted by name)
+ undefined external symbols (sorted by name)
+
+ The order of the string table is:
+ strings for external symbols
+ strings for local symbols
+ */
+static uint32_t ilocalsym = 0;
+static uint32_t iextdefsym = 0;
+static uint32_t iundefsym = 0;
+static uint32_t nlocalsym;
+static uint32_t nextdefsym;
+static uint32_t nundefsym;
+static struct symbol **extdefsyms = NULL;
+static struct symbol **undefsyms = NULL;
+
+static struct RAA *extsyms;
+static struct SAA *strs;
+static uint32_t strslen;
+
+static FILE *machofp;
+static efunc error;
+static evalfunc evaluate;
+
+extern struct ofmt of_macho;
+
+/* Global file information. This should be cleaned up into either
+ a structure or as function arguments. */
+uint32_t head_ncmds = 0;
+uint32_t head_sizeofcmds = 0;
+uint32_t seg_filesize = 0;
+uint32_t seg_vmsize = 0;
+uint32_t seg_nsects = 0;
+uint32_t rel_padcnt = 0;
+
+
+#define xstrncpy(xdst, xsrc) \
+ memset(xdst, '\0', sizeof(xdst)); /* zero out whole buffer */ \
+ strncpy(xdst, xsrc, sizeof(xdst)); /* copy over string */ \
+ xdst[sizeof(xdst) - 1] = '\0'; /* proper null-termination */
+
+#define align(x, y) \
+ (((x) + (y) - 1) & ~((y) - 1)) /* align x to multiple of y */
+
+#define alignint32_t(x) \
+ align(x, sizeof(int32_t)) /* align x to int32_t boundary */
+
+static void debug_reloc (struct reloc *);
+static void debug_section_relocs (struct section *) _unused;
+
+static int exact_log2 (uint32_t align)
+{
+ if (align == 0) {
+ return 0;
+ } else if (align & (align-1)) {
+ return -1; /* Not a power of 2 */
+ } else {
+#ifdef HAVE_GNUC_4
+ return __builtin_ctzl (align);
+#else
+ uint32_t result = 0;
+
+ /* We know exactly one bit is set at this point. */
+ if (align & 0xffff0000)
+ result |= 16;
+ if (align & 0xff00ff00)
+ result |= 8;
+ if (align & 0xf0f0f0f0)
+ result |= 4;
+ if (align & 0xcccccccc)
+ result |= 2;
+ if (align & 0xaaaaaaaa)
+ result |= 1;
+
+ return result;
+#endif
+ }
+}
+
+static struct section *get_section_by_name(const char *segname,
+ const char *sectname)
+{
+ struct section *s;
+
+ for (s = sects; s != NULL; s = s->next)
+ if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
+ break;
+
+ return s;
+}
+
+static struct section *get_section_by_index(const int32_t index)
+{
+ struct section *s;
+
+ for (s = sects; s != NULL; s = s->next)
+ if (index == s->index)
+ break;
+
+ return s;
+}
+
+static int32_t get_section_index_by_name(const char *segname,
+ const char *sectname)
+{
+ struct section *s;
+
+ for (s = sects; s != NULL; s = s->next)
+ if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
+ return s->index;
+
+ return -1;
+}
+
+static char *get_section_name_by_index(const int32_t index)
+{
+ struct section *s;
+
+ for (s = sects; s != NULL; s = s->next)
+ if (index == s->index)
+ return s->sectname;
+
+ return NULL;
+}
+
+static uint8_t get_section_fileindex_by_index(const int32_t index)
+{
+ struct section *s;
+ uint8_t i = 1;
+
+ for (s = sects; s != NULL && i < MAX_SECT; s = s->next, ++i)
+ if (index == s->index)
+ return i;
+
+ if (i == MAX_SECT)
+ error(ERR_WARNING,
+ "too many sections (>255) - clipped by fileindex");
+
+ return NO_SECT;
+}
+
+static void macho_init(FILE * fp, efunc errfunc, ldfunc ldef,
+ evalfunc eval)
+{
+ char zero = 0;
+
+ machofp = fp;
+ error = errfunc;
+ evaluate = eval;
+
+ (void)ldef; /* placate optimisers */
+
+ sects = NULL;
+ sectstail = &sects;
+
+ syms = NULL;
+ symstail = &syms;
+ nsyms = 0;
+ nlocalsym = 0;
+ nextdefsym = 0;
+ nundefsym = 0;
+
+ extsyms = raa_init();
+ strs = saa_init(1L);
+
+ /* string table starts with a zero byte - don't ask why */
+ saa_wbytes(strs, &zero, sizeof(char));
+ strslen = 1;
+}
+
+static int macho_setinfo(enum geninfo type, char **val)
+{
+ (void)type;
+ (void)val;
+ return 0;
+}
+
+static void sect_write(struct section *sect,
+ const uint8_t *data, uint32_t len)
+{
+ saa_wbytes(sect->data, data, len);
+ sect->size += len;
+}
+
+static void add_reloc(struct section *sect, int32_t section,
+ int pcrel, int bytes)
+{
+ struct reloc *r;
+ int32_t fi;
+
+ /* NeXT as puts relocs in reversed order (address-wise) into the
+ ** files, so we do the same, doesn't seem to make much of a
+ ** difference either way */
+ r = nasm_malloc(sizeof(struct reloc));
+ r->next = sect->relocs;
+ sect->relocs = r;
+
+ /* the current end of the section will be the symbol's address for
+ ** now, might have to be fixed by macho_fixup_relocs() later on. make
+ ** sure we don't make the symbol scattered by setting the highest
+ ** bit by accident */
+ r->addr = sect->size & ~R_SCATTERED;
+ r->ext = 0;
+ r->pcrel = pcrel;
+
+ /* match byte count 1, 2, 4 to length codes 0, 1, 2 respectively */
+ r->length = bytes >> 1;
+
+ /* vanilla relocation (GENERIC_RELOC_VANILLA) */
+ r->type = 0;
+
+ if (section == NO_SEG) {
+ /* absolute local symbol if no section index given */
+ r->snum = R_ABS;
+ } else {
+ fi = get_section_fileindex_by_index(section);
+
+ if (fi == NO_SECT) {
+ /* external symbol if no section with that index known,
+ ** symbol number was saved in macho_symdef() */
+ r->snum = raa_read(extsyms, section);
+ r->ext = 1;
+ } else {
+ /* local symbol in section fi */
+ r->snum = fi;
+ }
+ }
+
+ ++sect->nreloc;
+}
+
+static void macho_output(int32_t secto, const void *data,
+ enum out_type type, uint64_t size,
+ int32_t section, int32_t wrt)
+{
+ struct section *s, *sbss;
+ int32_t addr;
+ uint8_t mydata[4], *p;
+
+ if (wrt != NO_SEG) {
+ wrt = NO_SEG;
+ error(ERR_NONFATAL, "WRT not supported by Mach-O output format");
+ /* continue to do _something_ */
+ }
+
+ if (secto == NO_SEG) {
+ if (type != OUT_RESERVE)
+ error(ERR_NONFATAL, "attempt to assemble code in "
+ "[ABSOLUTE] space");
+
+ return;
+ }
+
+ s = get_section_by_index(secto);
+
+ if (s == NULL) {
+ error(ERR_WARNING, "attempt to assemble code in"
+ " section %d: defaulting to `.text'", secto);
+ s = get_section_by_name("__TEXT", "__text");
+
+ /* should never happen */
+ if (s == NULL)
+ error(ERR_PANIC, "text section not found");
+ }
+
+ sbss = get_section_by_name("__DATA", "__bss");
+
+ if (s == sbss && type != OUT_RESERVE) {
+ error(ERR_WARNING, "attempt to initialize memory in the"
+ " BSS section: ignored");
+ s->size += realsize(type, size);
+ return;
+ }
+
+ switch (type) {
+ case OUT_RESERVE:
+ if (s != sbss) {
+ error(ERR_WARNING, "uninitialized space declared in"
+ " %s section: zeroing",
+ get_section_name_by_index(secto));
+
+ sect_write(s, NULL, size);
+ } else
+ s->size += size;
+
+ break;
+
+ case OUT_RAWDATA:
+ if (section != NO_SEG)
+ error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
+
+ sect_write(s, data, size);
+ break;
+
+ case OUT_ADDRESS:
+ addr = *(int64_t *)data;
+
+ if (section != NO_SEG) {
+ if (section % 2) {
+ error(ERR_NONFATAL, "Mach-O format does not support"
+ " section base references");
+ } else
+ add_reloc(s, section, 0, size);
+ }
+
+ p = mydata;
+ WRITEADDR(p, addr, size);
+ sect_write(s, mydata, size);
+ break;
+
+ case OUT_REL2ADR:
+ if (section == secto)
+ error(ERR_PANIC, "intra-section OUT_REL2ADR");
+
+ if (section != NO_SEG && section % 2) {
+ error(ERR_NONFATAL, "Mach-O format does not support"
+ " section base references");
+ } else
+ add_reloc(s, section, 1, 2);
+
+ p = mydata;
+ WRITESHORT(p, *(int32_t *)data - (size + s->size));
+ sect_write(s, mydata, 2L);
+ break;
+
+ case OUT_REL4ADR:
+ if (section == secto)
+ error(ERR_PANIC, "intra-section OUT_REL4ADR");
+
+ if (section != NO_SEG && section % 2) {
+ error(ERR_NONFATAL, "Mach-O format does not support"
+ " section base references");
+ } else
+ add_reloc(s, section, 1, 4);
+
+ p = mydata;
+ WRITELONG(p, *(int32_t *)data - (size + s->size));
+ sect_write(s, mydata, 4L);
+ break;
+
+ default:
+ error(ERR_PANIC, "unknown output type?");
+ break;
+ }
+}
+
+static int32_t macho_section(char *name, int pass, int *bits)
+{
+ int32_t index, originalIndex;
+ char *sectionAttributes;
+ struct sectmap *sm;
+ struct section *s;
+
+ (void)pass;
+
+ /* Default to 32 bits. */
+ if (!name) {
+ *bits = 32;
+ name = ".text";
+ sectionAttributes = NULL;
+ } else {
+ sectionAttributes = name;
+ name = nasm_strsep(&sectionAttributes, " \t");
+ }
+
+ for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
+ /* make lookup into section name translation table */
+ if (!strcmp(name, sm->nasmsect)) {
+ char *currentAttribute;
+
+ /* try to find section with that name */
+ originalIndex = index = get_section_index_by_name(sm->segname,
+ sm->sectname);
+
+ /* create it if it doesn't exist yet */
+ if (index == -1) {
+ s = *sectstail = nasm_malloc(sizeof(struct section));
+ s->next = NULL;
+ sectstail = &s->next;
+
+ s->data = saa_init(1L);
+ s->index = seg_alloc();
+ s->relocs = NULL;
+ s->align = -1;
+
+ xstrncpy(s->segname, sm->segname);
+ xstrncpy(s->sectname, sm->sectname);
+ s->size = 0;
+ s->nreloc = 0;
+ s->flags = sm->flags;
+
+ index = s->index;
+ } else {
+ s = get_section_by_index(index);
+ }
+
+ while ((NULL != sectionAttributes)
+ && (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
+ if (0 != *currentAttribute) {
+ if (!nasm_strnicmp("align=", currentAttribute, 6)) {
+ char *end;
+ int newAlignment, value;
+
+ value = strtoul(currentAttribute + 6, (char**)&end, 0);
+ newAlignment = exact_log2(value);
+
+ if (0 != *end) {
+ error(ERR_PANIC,
+ "unknown or missing alignment value \"%s\" "
+ "specified for section \"%s\"",
+ currentAttribute + 6,
+ name);
+ return NO_SEG;
+ } else if (0 > newAlignment) {
+ error(ERR_PANIC,
+ "alignment of %d (for section \"%s\") is not "
+ "a power of two",
+ value,
+ name);
+ return NO_SEG;
+ }
+
+ if ((-1 != originalIndex)
+ && (s->align != newAlignment)
+ && (s->align != -1)) {
+ error(ERR_PANIC,
+ "section \"%s\" has already been specified "
+ "with alignment %d, conflicts with new "
+ "alignment of %d",
+ name,
+ (1 << s->align),
+ value);
+ return NO_SEG;
+ }
+
+ s->align = newAlignment;
+ } else if (!nasm_stricmp("data", currentAttribute)) {
+ /* Do nothing; 'data' is implicit */
+ } else {
+ error(ERR_PANIC,
+ "unknown section attribute %s for section %s",
+ currentAttribute,
+ name);
+ return NO_SEG;
+ }
+ }
+ }
+
+ return index;
+ }
+ }
+
+ error(ERR_PANIC, "invalid section name %s", name);
+ return NO_SEG;
+}
+
+static void macho_symdef(char *name, int32_t section, int64_t offset,
+ int is_global, char *special)
+{
+ struct symbol *sym;
+
+ if (special) {
+ error(ERR_NONFATAL, "The Mach-O output format does "
+ "not support any special symbol types");
+ return;
+ }
+
+ if (is_global == 3) {
+ error(ERR_NONFATAL, "The Mach-O format does not "
+ "(yet) support forward reference fixups.");
+ return;
+ }
+
+ sym = *symstail = nasm_malloc(sizeof(struct symbol));
+ sym->next = NULL;
+ symstail = &sym->next;
+
+ sym->name = name;
+ sym->strx = strslen;
+ sym->type = 0;
+ sym->desc = 0;
+ sym->value = offset;
+ sym->initial_snum = -1;
+
+ /* external and common symbols get N_EXT */
+ if (is_global != 0)
+ sym->type |= N_EXT;
+
+ if (section == NO_SEG) {
+ /* symbols in no section get absolute */
+ sym->type |= N_ABS;
+ sym->sect = NO_SECT;
+ } else {
+ sym->type |= N_SECT;
+
+ /* get the in-file index of the section the symbol was defined in */
+ sym->sect = get_section_fileindex_by_index(section);
+
+ if (sym->sect == NO_SECT) {
+ /* remember symbol number of references to external
+ ** symbols, this works because every external symbol gets
+ ** its own section number allocated internally by nasm and
+ ** can so be used as a key */
+ extsyms = raa_write(extsyms, section, nsyms);
+ sym->initial_snum = nsyms;
+
+ switch (is_global) {
+ case 1:
+ case 2:
+ /* there isn't actually a difference between global
+ ** and common symbols, both even have their size in
+ ** sym->value */
+ sym->type = N_EXT;
+ break;
+
+ default:
+ /* give an error on unfound section if it's not an
+ ** external or common symbol (assemble_file() does a
+ ** seg_alloc() on every call for them) */
+ error(ERR_PANIC, "in-file index for section %d not found",
+ section);
+ }
+ }
+ }
+
+ ++nsyms;
+}
+
+static int32_t macho_segbase(int32_t section)
+{
+ return section;
+}
+
+static int macho_directive(char *directive, char *value, int pass)
+{
+ (void)directive;
+ (void)value;
+ (void)pass;
+ return 0;
+}
+
+static void macho_filename(char *inname, char *outname, efunc error)
+{
+ standard_extension(inname, outname, ".o", error);
+}
+
+extern macros_t macho_stdmac[];
+
+/* Comparison function for qsort symbol layout. */
+static int layout_compare (const struct symbol **s1,
+ const struct symbol **s2)
+{
+ return (strcmp ((*s1)->name, (*s2)->name));
+}
+
+/* The native assembler does a few things in a similar function
+
+ * Remove temporary labels
+ * Sort symbols according to local, external, undefined (by name)
+ * Order the string table
+
+ We do not remove temporary labels right now.
+
+ numsyms is the total number of symbols we have. strtabsize is the
+ number entries in the string table. */
+
+static void macho_layout_symbols (uint32_t *numsyms,
+ uint32_t *strtabsize)
+{
+ struct symbol *sym, **symp;
+ uint32_t i,j;
+
+ *numsyms = 0;
+ *strtabsize = sizeof (char);
+
+ symp = &syms;
+
+ while ((sym = *symp)) {
+ /* Undefined symbols are now external. */
+ if (sym->type == N_UNDF)
+ sym->type |= N_EXT;
+
+ if ((sym->type & N_EXT) == 0) {
+ sym->snum = *numsyms;
+ *numsyms = *numsyms + 1;
+ nlocalsym++;
+ }
+ else {
+ if ((sym->type & N_TYPE) != N_UNDF)
+ nextdefsym++;
+ else
+ nundefsym++;
+
+ /* If we handle debug info we'll want
+ to check for it here instead of just
+ adding the symbol to the string table. */
+ sym->strx = *strtabsize;
+ saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
+ *strtabsize += strlen(sym->name) + 1;
+ }
+ symp = &(sym->next);
+ }
+
+ /* Next, sort the symbols. Most of this code is a direct translation from
+ the Apple cctools symbol layout. We need to keep compatibility with that. */
+ /* Set the indexes for symbol groups into the symbol table */
+ ilocalsym = 0;
+ iextdefsym = nlocalsym;
+ iundefsym = nlocalsym + nextdefsym;
+
+ /* allocate arrays for sorting externals by name */
+ extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
+ undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
+
+ i = 0;
+ j = 0;
+
+ symp = &syms;
+
+ while ((sym = *symp)) {
+
+ if((sym->type & N_EXT) == 0) {
+ sym->strx = *strtabsize;
+ saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
+ *strtabsize += strlen(sym->name) + 1;
+ }
+ else {
+ if((sym->type & N_TYPE) != N_UNDF)
+ extdefsyms[i++] = sym;
+ else
+ undefsyms[j++] = sym;
+ }
+ symp = &(sym->next);
+ }
+
+ qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
+ (int (*)(const void *, const void *))layout_compare);
+ qsort(undefsyms, nundefsym, sizeof(struct symbol *),
+ (int (*)(const void *, const void *))layout_compare);
+
+ for(i = 0; i < nextdefsym; i++) {
+ extdefsyms[i]->snum = *numsyms;
+ *numsyms += 1;
+ }
+ for(j = 0; j < nundefsym; j++) {
+ undefsyms[j]->snum = *numsyms;
+ *numsyms += 1;
+ }
+}
+
+/* Calculate some values we'll need for writing later. */
+
+static void macho_calculate_sizes (void)
+{
+ struct section *s;
+
+ /* count sections and calculate in-memory and in-file offsets */
+ for (s = sects; s != NULL; s = s->next) {
+ uint32_t pad = 0;
+
+ /* zerofill sections aren't actually written to the file */
+ if ((s->flags & SECTION_TYPE) != S_ZEROFILL)
+ seg_filesize += s->size;
+
+ /* recalculate segment address based on alignment and vm size */
+ s->addr = seg_vmsize;
+ /* we need section alignment to calculate final section address */
+ if (s->align == -1)
+ s->align = DEFAULT_SECTION_ALIGNMENT;
+ if(s->align) {
+ uint32_t newaddr = align(s->addr, 1 << s->align);
+ pad = newaddr - s->addr;
+ s->addr = newaddr;
+ }
+
+ seg_vmsize += s->size + pad;
+ ++seg_nsects;
+ }
+
+ /* calculate size of all headers, load commands and sections to
+ ** get a pointer to the start of all the raw data */
+ if (seg_nsects > 0) {
+ ++head_ncmds;
+ head_sizeofcmds +=
+ MACHO_SEGCMD_SIZE + seg_nsects * MACHO_SECTCMD_SIZE;
+ }
+
+ if (nsyms > 0) {
+ ++head_ncmds;
+ head_sizeofcmds += MACHO_SYMCMD_SIZE;
+ }
+}
+
+/* Write out the header information for the file. */
+
+static void macho_write_header (void)
+{
+ fwriteint32_t(MH_MAGIC, machofp); /* magic */
+ fwriteint32_t(CPU_TYPE_I386, machofp); /* CPU type */
+ fwriteint32_t(CPU_SUBTYPE_I386_ALL, machofp); /* CPU subtype */
+ fwriteint32_t(MH_OBJECT, machofp); /* Mach-O file type */
+ fwriteint32_t(head_ncmds, machofp); /* number of load commands */
+ fwriteint32_t(head_sizeofcmds, machofp); /* size of load commands */
+ fwriteint32_t(0, machofp); /* no flags */
+}
+
+/* Write out the segment load command at offset. */
+
+static uint32_t macho_write_segment (uint32_t offset)
+{
+ uint32_t rel_base = alignint32_t (offset + seg_filesize);
+ uint32_t s_reloff = 0;
+ struct section *s;
+
+ fwriteint32_t(LC_SEGMENT, machofp); /* cmd == LC_SEGMENT */
+
+ /* size of load command including section load commands */
+ fwriteint32_t(MACHO_SEGCMD_SIZE + seg_nsects *
+ MACHO_SECTCMD_SIZE, machofp);
+
+ /* in an MH_OBJECT file all sections are in one unnamed (name
+ ** all zeros) segment */
+ fwritezero(16, machofp);
+ fwriteint32_t(0, machofp); /* in-memory offset */
+ fwriteint32_t(seg_vmsize, machofp); /* in-memory size */
+ fwriteint32_t(offset, machofp); /* in-file offset to data */
+ fwriteint32_t(seg_filesize, machofp); /* in-file size */
+ fwriteint32_t(VM_PROT_DEFAULT, machofp); /* maximum vm protection */
+ fwriteint32_t(VM_PROT_DEFAULT, machofp); /* initial vm protection */
+ fwriteint32_t(seg_nsects, machofp); /* number of sections */
+ fwriteint32_t(0, machofp); /* no flags */
+
+ /* emit section headers */
+ for (s = sects; s != NULL; s = s->next) {
+ fwrite(s->sectname, sizeof(s->sectname), 1, machofp);
+ fwrite(s->segname, sizeof(s->segname), 1, machofp);
+ fwriteint32_t(s->addr, machofp);
+ fwriteint32_t(s->size, machofp);
+
+ /* dummy data for zerofill sections or proper values */
+ if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
+ fwriteint32_t(offset, machofp);
+ /* Write out section alignment, as a power of two.
+ e.g. 32-bit word alignment would be 2 (2^^2 = 4). */
+ if (s->align == -1)
+ s->align = DEFAULT_SECTION_ALIGNMENT;
+ fwriteint32_t(s->align, machofp);
+ /* To be compatible with cctools as we emit
+ a zero reloff if we have no relocations. */
+ fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, machofp);
+ fwriteint32_t(s->nreloc, machofp);
+
+ offset += s->size;
+ s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
+ } else {
+ fwriteint32_t(0, machofp);
+ fwriteint32_t(0, machofp);
+ fwriteint32_t(0, machofp);
+ fwriteint32_t(0, machofp);
+ }
+
+ fwriteint32_t(s->flags, machofp); /* flags */
+ fwriteint32_t(0, machofp); /* reserved */
+ fwriteint32_t(0, machofp); /* reserved */
+ }
+
+ rel_padcnt = rel_base - offset;
+ offset = rel_base + s_reloff;
+
+ return offset;
+}
+
+/* For a given chain of relocs r, write out the entire relocation
+ chain to the object file. */
+
+static void macho_write_relocs (struct reloc *r)
+{
+ while (r) {
+ uint32_t word2;
+
+ fwriteint32_t(r->addr, machofp); /* reloc offset */
+
+ word2 = r->snum;
+ word2 |= r->pcrel << 24;
+ word2 |= r->length << 25;
+ word2 |= r->ext << 27;
+ word2 |= r->type << 28;
+ fwriteint32_t(word2, machofp); /* reloc data */
+
+ r = r->next;
+ }
+}
+
+/* Write out the section data. */
+static void macho_write_section (void)
+{
+ struct section *s, *s2;
+ struct reloc *r;
+ uint8_t fi, *p, *q, blk[4];
+ int32_t l;
+
+ for (s = sects; s != NULL; s = s->next) {
+ if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
+ continue;
+
+ /* no padding needs to be done to the sections */
+
+ /* Like a.out Mach-O references things in the data or bss
+ * sections by addresses which are actually relative to the
+ * start of the _text_ section, in the _file_. See outaout.c
+ * for more information. */
+ saa_rewind(s->data);
+ for (r = s->relocs; r != NULL; r = r->next) {
+ saa_fread(s->data, r->addr, blk, (int32_t)r->length << 1);
+ p = q = blk;
+ l = *p++;
+
+ /* get offset based on relocation type */
+ if (r->length > 0) {
+ l += ((int32_t)*p++) << 8;
+
+ if (r->length == 2) {
+ l += ((int32_t)*p++) << 16;
+ l += ((int32_t)*p++) << 24;
+ }
+ }
+
+ /* If the relocation is internal add to the current section
+ offset. Otherwise the only value we need is the symbol
+ offset which we already have. The linker takes care
+ of the rest of the address. */
+ if (!r->ext) {
+ /* generate final address by section address and offset */
+ for (s2 = sects, fi = 1;
+ s2 != NULL; s2 = s2->next, fi++) {
+ if (fi == r->snum) {
+ l += s2->addr;
+ break;
+ }
+ }
+ }
+
+ /* write new offset back */
+ if (r->length == 2)
+ WRITELONG(q, l);
+ else if (r->length == 1)
+ WRITESHORT(q, l);
+ else
+ *q++ = l & 0xFF;
+
+ saa_fwrite(s->data, r->addr, blk, (int32_t)r->length << 1);
+ }
+
+ /* dump the section data to file */
+ saa_fpwrite(s->data, machofp);
+ }
+
+ /* pad last section up to reloc entries on int32_t boundary */
+ fwritezero(rel_padcnt, machofp);
+
+ /* emit relocation entries */
+ for (s = sects; s != NULL; s = s->next)
+ macho_write_relocs (s->relocs);
+}
+
+/* Write out the symbol table. We should already have sorted this
+ before now. */
+static void macho_write_symtab (void)
+{
+ struct symbol *sym;
+ struct section *s;
+ int32_t fi;
+ uint32_t i;
+
+ /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
+
+ for (sym = syms; sym != NULL; sym = sym->next) {
+ if ((sym->type & N_EXT) == 0) {
+ fwriteint32_t(sym->strx, machofp); /* string table entry number */
+ fwrite(&sym->type, 1, 1, machofp); /* symbol type */
+ fwrite(&sym->sect, 1, 1, machofp); /* section */
+ fwriteint16_t(sym->desc, machofp); /* description */
+
+ /* Fix up the symbol value now that we know the final section
+ sizes. */
+ if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
+ for (s = sects, fi = 1;
+ s != NULL && fi < sym->sect; s = s->next, ++fi)
+ sym->value += s->size;
+ }
+
+ fwriteint32_t(sym->value, machofp); /* value (i.e. offset) */
+ }
+ }
+
+ for (i = 0; i < nextdefsym; i++) {
+ sym = extdefsyms[i];
+ fwriteint32_t(sym->strx, machofp);
+ fwrite(&sym->type, 1, 1, machofp); /* symbol type */
+ fwrite(&sym->sect, 1, 1, machofp); /* section */
+ fwriteint16_t(sym->desc, machofp); /* description */
+
+ /* Fix up the symbol value now that we know the final section
+ sizes. */
+ if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
+ for (s = sects, fi = 1;
+ s != NULL && fi < sym->sect; s = s->next, ++fi)
+ sym->value += s->size;
+ }
+
+ fwriteint32_t(sym->value, machofp); /* value (i.e. offset) */
+ }
+
+ for (i = 0; i < nundefsym; i++) {
+ sym = undefsyms[i];
+ fwriteint32_t(sym->strx, machofp);
+ fwrite(&sym->type, 1, 1, machofp); /* symbol type */
+ fwrite(&sym->sect, 1, 1, machofp); /* section */
+ fwriteint16_t(sym->desc, machofp); /* description */
+
+ /* Fix up the symbol value now that we know the final section
+ sizes. */
+ if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
+ for (s = sects, fi = 1;
+ s != NULL && fi < sym->sect; s = s->next, ++fi)
+ sym->value += s->size;
+ }
+
+ fwriteint32_t(sym->value, machofp); /* value (i.e. offset) */
+ }
+}
+
+/* Fixup the snum in the relocation entries, we should be
+ doing this only for externally undefined symbols. */
+static void macho_fixup_relocs (struct reloc *r)
+{
+ struct symbol *sym;
+ uint32_t i;
+
+ while (r != NULL) {
+ if (r->ext) {
+ for (i = 0; i < nundefsym; i++) {
+ sym = undefsyms[i];
+ if (sym->initial_snum == r->snum) {
+ r->snum = sym->snum;
+ break;
+ }
+ }
+ }
+ r = r->next;
+ }
+}
+
+/* Write out the object file. */
+
+static void macho_write (void)
+{
+ uint32_t offset = 0;
+
+ /* mach-o object file structure:
+ **
+ ** mach header
+ ** uint32_t magic
+ ** int cpu type
+ ** int cpu subtype
+ ** uint32_t mach file type
+ ** uint32_t number of load commands
+ ** uint32_t size of all load commands
+ ** (includes section struct size of segment command)
+ ** uint32_t flags
+ **
+ ** segment command
+ ** uint32_t command type == LC_SEGMENT
+ ** uint32_t size of load command
+ ** (including section load commands)
+ ** char[16] segment name
+ ** uint32_t in-memory offset
+ ** uint32_t in-memory size
+ ** uint32_t in-file offset to data area
+ ** uint32_t in-file size
+ ** (in-memory size excluding zerofill sections)
+ ** int maximum vm protection
+ ** int initial vm protection
+ ** uint32_t number of sections
+ ** uint32_t flags
+ **
+ ** section commands
+ ** char[16] section name
+ ** char[16] segment name
+ ** uint32_t in-memory offset
+ ** uint32_t in-memory size
+ ** uint32_t in-file offset
+ ** uint32_t alignment
+ ** (irrelevant in MH_OBJECT)
+ ** uint32_t in-file offset of relocation entires
+ ** uint32_t number of relocations
+ ** uint32_t flags
+ ** uint32_t reserved
+ ** uint32_t reserved
+ **
+ ** symbol table command
+ ** uint32_t command type == LC_SYMTAB
+ ** uint32_t size of load command
+ ** uint32_t symbol table offset
+ ** uint32_t number of symbol table entries
+ ** uint32_t string table offset
+ ** uint32_t string table size
+ **
+ ** raw section data
+ **
+ ** padding to int32_t boundary
+ **
+ ** relocation data (struct reloc)
+ ** int32_t offset
+ ** uint data (symbolnum, pcrel, length, extern, type)
+ **
+ ** symbol table data (struct nlist)
+ ** int32_t string table entry number
+ ** uint8_t type
+ ** (extern, absolute, defined in section)
+ ** uint8_t section
+ ** (0 for global symbols, section number of definition (>= 1, <=
+ ** 254) for local symbols, size of variable for common symbols
+ ** [type == extern])
+ ** int16_t description
+ ** (for stab debugging format)
+ ** uint32_t value (i.e. file offset) of symbol or stab offset
+ **
+ ** string table data
+ ** list of null-terminated strings
+ */
+
+ /* Emit the Mach-O header. */
+ macho_write_header();
+
+ offset = MACHO_HEADER_SIZE + head_sizeofcmds;
+
+ /* emit the segment load command */
+ if (seg_nsects > 0)
+ offset = macho_write_segment (offset);
+ else
+ error(ERR_WARNING, "no sections?");
+
+ if (nsyms > 0) {
+ /* write out symbol command */
+ fwriteint32_t(LC_SYMTAB, machofp); /* cmd == LC_SYMTAB */
+ fwriteint32_t(MACHO_SYMCMD_SIZE, machofp); /* size of load command */
+ fwriteint32_t(offset, machofp); /* symbol table offset */
+ fwriteint32_t(nsyms, machofp); /* number of symbol
+ ** table entries */
+
+ offset += nsyms * MACHO_NLIST_SIZE;
+ fwriteint32_t(offset, machofp); /* string table offset */
+ fwriteint32_t(strslen, machofp); /* string table size */
+ }
+
+ /* emit section data */
+ if (seg_nsects > 0)
+ macho_write_section ();
+
+ /* emit symbol table if we have symbols */
+ if (nsyms > 0)
+ macho_write_symtab ();
+
+ /* we don't need to pad here since MACHO_NLIST_SIZE == 12 */
+
+ /* emit string table */
+ saa_fpwrite(strs, machofp);
+}
+/* We do quite a bit here, starting with finalizing all of the data
+ for the object file, writing, and then freeing all of the data from
+ the file. */
+
+static void macho_cleanup(int debuginfo)
+{
+ struct section *s;
+ struct reloc *r;
+ struct symbol *sym;
+
+ (void)debuginfo;
+
+ /* Sort all symbols. */
+ macho_layout_symbols (&nsyms, &strslen);
+
+ /* Fixup relocation entries */
+ for (s = sects; s != NULL; s = s->next) {
+ macho_fixup_relocs (s->relocs);
+ }
+
+ /* First calculate and finalize needed values. */
+ macho_calculate_sizes();
+ macho_write();
+
+ /* done - yay! */
+ fclose(machofp);
+
+ /* free up everything */
+ while (sects->next) {
+ s = sects;
+ sects = sects->next;
+
+ saa_free(s->data);
+ while (s->relocs != NULL) {
+ r = s->relocs;
+ s->relocs = s->relocs->next;
+ nasm_free(r);
+ }
+
+ nasm_free(s);
+ }
+
+ saa_free(strs);
+ raa_free(extsyms);
+
+ if (syms) {
+ while (syms->next) {
+ sym = syms;
+ syms = syms->next;
+
+ nasm_free (sym);
+ }
+}
+}
+
+/* Debugging routines. */
+static void debug_reloc (struct reloc *r)
+{
+ fprintf (stdout, "reloc:\n");
+ fprintf (stdout, "\taddr: %"PRId32"\n", r->addr);
+ fprintf (stdout, "\tsnum: %d\n", r->snum);
+ fprintf (stdout, "\tpcrel: %d\n", r->pcrel);
+ fprintf (stdout, "\tlength: %d\n", r->length);
+ fprintf (stdout, "\text: %d\n", r->ext);
+ fprintf (stdout, "\ttype: %d\n", r->type);
+}
+
+static void debug_section_relocs (struct section *s)
+{
+ struct reloc *r = s->relocs;
+
+ fprintf (stdout, "relocs for section %s:\n\n", s->sectname);
+
+ while (r != NULL) {
+ debug_reloc (r);
+ r = r->next;
+ }
+}
+
+struct ofmt of_macho32 = {
+ "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
+ "macho32",
+ 0,
+ null_debug_arr,
+ &null_debug_form,
+ macho_stdmac,
+ macho_init,
+ macho_setinfo,
+ macho_output,
+ macho_symdef,
+ macho_section,
+ macho_segbase,
+ macho_directive,
+ macho_filename,
+ macho_cleanup
+};
+
+struct ofmt of_macho = {
+ "MACHO (short name for MACHO32)",
+ "macho",
+ 0,
+ null_debug_arr,
+ &null_debug_form,
+ macho_stdmac,
+ macho_init,
+ macho_setinfo,
+ macho_output,
+ macho_symdef,
+ macho_section,
+ macho_segbase,
+ macho_directive,
+ macho_filename,
+ macho_cleanup
+};
+
+#endif
+
+/*
+ * Local Variables:
+ * mode:c
+ * c-basic-offset:4
+ * End:
+ *
+ * end of file */
diff --git a/output/outmacho64.c b/output/outmacho64.c
new file mode 100644
index 00000000..0a8b77b9
--- /dev/null
+++ b/output/outmacho64.c
@@ -0,0 +1,1528 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * outmacho64.c output routines for the Netwide Assembler to produce
+ * NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files
+ */
+
+/* Most of this file is, like Mach-O itself, based on a.out. For more
+ * guidelines see outaout.c. */
+
+#include "compiler.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+#include "nasm.h"
+#include "nasmlib.h"
+#include "saa.h"
+#include "raa.h"
+#include "output/outform.h"
+#include "output/outlib.h"
+
+#if defined(OF_MACHO64)
+
+/* Mach-O in-file header structure sizes */
+#define MACHO_HEADER64_SIZE (32)
+#define MACHO_SEGCMD64_SIZE (72)
+#define MACHO_SECTCMD64_SIZE (80)
+#define MACHO_SYMCMD_SIZE (24)
+#define MACHO_NLIST64_SIZE (16)
+#define MACHO_RELINFO64_SIZE (8)
+
+/* Mach-O file header values */
+#define MH_MAGIC_64 (0xfeedfacf)
+#define CPU_TYPE_X86_64 (0x01000007) /* x86-64 platform */
+#define CPU_SUBTYPE_I386_ALL (3) /* all-x86 compatible */
+#define MH_OBJECT (0x1) /* object file */
+
+#define LC_SEGMENT_64 (0x19) /* segment load command */
+#define LC_SYMTAB (0x2) /* symbol table load command */
+
+#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)
+
+struct section {
+ /* nasm internal data */
+ struct section *next;
+ struct SAA *data;
+ int32_t index;
+ struct reloc *relocs;
+ int align;
+
+ /* data that goes into the file */
+ char sectname[16]; /* what this section is called */
+ char segname[16]; /* segment this section will be in */
+ uint64_t addr; /* in-memory address (subject to alignment) */
+ uint64_t size; /* in-memory and -file size */
+ uint32_t nreloc; /* relocation entry count */
+ uint32_t flags; /* type and attributes (masked) */
+ 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_PURE_INSTRUCTIONS 0x80000000 /* section uses pure
+ machine instructions */
+
+static struct sectmap {
+ const char *nasmsect;
+ const char *segname;
+ const char *sectname;
+ const int32_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},
+ {NULL, NULL, NULL, 0}
+};
+
+struct reloc {
+ /* nasm internal data */
+ struct reloc *next;
+
+ /* data that goes into the file */
+ int32_t addr; /* op's offset in section */
+ uint32_t snum:24, /* contains symbol index if
+ ** ext otherwise in-file
+ ** section number */
+ pcrel:1, /* relative relocation */
+ length:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
+ ext:1, /* external symbol referenced */
+ 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 symbol *next; /* next symbol in the list */
+ char *name; /* name of this symbol */
+ int32_t initial_snum; /* symbol number used above in
+ reloc */
+ int32_t snum; /* true snum for reloc */
+
+ /* data that goes into the file */
+ uint32_t strx; /* string table index */
+ uint8_t type; /* symbol type */
+ uint8_t sect; /* NO_SECT or section number */
+ uint16_t desc; /* for stab debugging, 0 for us */
+ uint64_t value; /* offset of symbol in section */
+};
+
+/* symbol type bits */
+#define N_EXT 0x01 /* global or 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;
+static struct symbol *syms, **symstail;
+static uint32_t nsyms;
+
+/* These variables are set by macho_layout_symbols() to organize
+ the symbol table and string table in order the dynamic linker
+ expects. They are then used in macho_write() to put out the
+ symbols and strings in that order.
+
+ The order of the symbol table is:
+ local symbols
+ defined external symbols (sorted by name)
+ undefined external symbols (sorted by name)
+
+ The order of the string table is:
+ strings for external symbols
+ strings for local symbols
+ */
+static uint32_t ilocalsym = 0;
+static uint32_t iextdefsym = 0;
+static uint32_t iundefsym = 0;
+static uint32_t nlocalsym;
+static uint32_t nextdefsym;
+static uint32_t nundefsym;
+static struct symbol **extdefsyms = NULL;
+static struct symbol **undefsyms = NULL;
+
+static struct RAA *extsyms;
+static struct SAA *strs;
+static uint32_t strslen;
+
+static FILE *machofp;
+static efunc error;
+static evalfunc evaluate;
+
+extern struct ofmt of_macho64;
+
+/* Global file information. This should be cleaned up into either
+ a structure or as function arguments. */
+uint32_t head_ncmds64 = 0;
+uint32_t head_sizeofcmds64 = 0;
+uint64_t seg_filesize64 = 0;
+uint64_t seg_vmsize64 = 0;
+uint32_t seg_nsects64 = 0;
+uint64_t rel_padcnt64 = 0;
+
+
+#define xstrncpy(xdst, xsrc) \
+ memset(xdst, '\0', sizeof(xdst)); /* zero out whole buffer */ \
+ strncpy(xdst, xsrc, sizeof(xdst)); /* copy over string */ \
+ xdst[sizeof(xdst) - 1] = '\0'; /* proper null-termination */
+
+#define align(x, y) \
+ (((x) + (y) - 1) & ~((y) - 1)) /* align x to multiple of y */
+
+#define alignint32_t(x) \
+ align(x, sizeof(int32_t)) /* align x to int32_t boundary */
+
+#define alignint64_t(x) \
+ align(x, sizeof(int64_t)) /* align x to int64_t boundary */
+
+static void debug_reloc (struct reloc *);
+static void debug_section_relocs (struct section *) _unused;
+
+static int exact_log2 (uint32_t align)
+{
+ if (align == 0) {
+ return 0;
+ } else if (align & (align-1)) {
+ return -1; /* Not a power of 2 */
+ } else {
+#ifdef HAVE_GNUC_4
+ return __builtin_ctzl (align);
+#else
+ uint32_t result = 0;
+
+ /* We know exactly one bit is set at this point. */
+ if (align & 0xffff0000)
+ result |= 16;
+ if (align & 0xff00ff00)
+ result |= 8;
+ if (align & 0xf0f0f0f0)
+ result |= 4;
+ if (align & 0xcccccccc)
+ result |= 2;
+ if (align & 0xaaaaaaaa)
+ result |= 1;
+
+ return result;
+#endif
+ }
+}
+
+static struct section *get_section_by_name(const char *segname,
+ const char *sectname)
+{
+ struct section *s;
+
+ for (s = sects; s != NULL; s = s->next)
+ if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
+ break;
+
+ return s;
+}
+
+static struct section *get_section_by_index(const int32_t index)
+{
+ struct section *s;
+
+ for (s = sects; s != NULL; s = s->next)
+ if (index == s->index)
+ break;
+
+ return s;
+}
+
+static int32_t get_section_index_by_name(const char *segname,
+ const char *sectname)
+{
+ struct section *s;
+
+ for (s = sects; s != NULL; s = s->next)
+ if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
+ return s->index;
+
+ return -1;
+}
+
+static char *get_section_name_by_index(const int32_t index)
+{
+ struct section *s;
+
+ for (s = sects; s != NULL; s = s->next)
+ if (index == s->index)
+ return s->sectname;
+
+ return NULL;
+}
+
+static uint8_t get_section_fileindex_by_index(const int32_t index)
+{
+ struct section *s;
+ uint8_t i = 1;
+
+ for (s = sects; s != NULL && i < MAX_SECT; s = s->next, ++i)
+ if (index == s->index)
+ return i;
+
+ if (i == MAX_SECT)
+ error(ERR_WARNING,
+ "too many sections (>255) - clipped by fileindex");
+
+ return NO_SECT;
+}
+
+static struct symbol *get_closest_section_symbol_by_offset(uint8_t fileindex, int64_t offset)
+{
+ struct symbol *sym;
+
+ for (sym = syms; sym != NULL; sym = sym->next) {
+ if ((sym->sect != NO_SECT) &&
+ (sym->sect == fileindex) &&
+ ((int64_t)sym->value >= offset))
+ return sym;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Special section numbers which are used to define Mach-O special
+ * symbols, which can be used with WRT to provide PIC relocation
+ * types.
+ */
+static int32_t macho_gotpcrel_sect;
+
+static void macho_init(FILE * fp, efunc errfunc, ldfunc ldef,
+ evalfunc eval)
+{
+ char zero = 0;
+
+ maxbits = 64;
+ machofp = fp;
+ error = errfunc;
+ evaluate = eval;
+
+ (void)ldef; /* placate optimizers */
+
+ sects = NULL;
+ sectstail = &sects;
+
+ syms = NULL;
+ symstail = &syms;
+ nsyms = 0;
+ nlocalsym = 0;
+ nextdefsym = 0;
+ nundefsym = 0;
+
+ extsyms = raa_init();
+ strs = saa_init(1L);
+
+ /* string table starts with a zero byte - don't ask why */
+ saa_wbytes(strs, &zero, sizeof(char));
+ strslen = 1;
+
+ /* add special symbol for ..gotpcrel */
+ macho_gotpcrel_sect = seg_alloc();
+ macho_gotpcrel_sect ++;
+// ldef("..gotpcrel", macho_gotpcrel_sect, 0L, NULL, false, false, &of_macho64, error);
+}
+
+static int macho_setinfo(enum geninfo type, char **val)
+{
+ (void)type;
+ (void)val;
+ return 0;
+}
+
+static void sect_write(struct section *sect,
+ const uint8_t *data, uint32_t len)
+{
+ saa_wbytes(sect->data, data, len);
+ sect->size += len;
+}
+
+static int32_t add_reloc(struct section *sect, int32_t section,
+ int pcrel, int bytes, int64_t reloff)
+{
+ struct reloc *r;
+ struct symbol *sym;
+ int32_t fi;
+ int32_t adjustment = 0;
+
+ /* 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 */
+ r = nasm_malloc(sizeof(struct reloc));
+ r->next = sect->relocs;
+ sect->relocs = r;
+
+ /* the current end of the section will be the symbol's address for
+ ** now, might have to be fixed by macho_fixup_relocs() later on. make
+ ** sure we don't make the symbol scattered by setting the highest
+ ** bit by accident */
+ r->addr = sect->size & ~R_SCATTERED;
+ r->ext = 1;
+ r->pcrel = (pcrel ? 1 : 0);
+
+ /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
+ switch(bytes){
+ case 1:
+ r->length = 0;
+ break;
+ case 2:
+ r->length = 1;
+ break;
+ case 4:
+ r->length = 2;
+ break;
+ case 8:
+ r->length = 3;
+ break;
+ default:
+ break;
+ }
+
+ /* set default relocation values */
+ r->type = 0; // X86_64_RELOC_UNSIGNED
+ r->snum = R_ABS; // Absolute Symbol (indicates no relocation)
+
+ /* absolute relocation */
+ if (pcrel == 0) {
+
+ /* intra-section */
+ if (section == NO_SEG) {
+ // r->snum = R_ABS; // Set above
+
+ /* inter-section */
+ } else {
+ fi = get_section_fileindex_by_index(section);
+
+ /* external */
+ if (fi == NO_SECT) {
+ r->snum = raa_read(extsyms, section);
+
+ /* local */
+ } else {
+ sym = get_closest_section_symbol_by_offset(fi, reloff);
+ r->snum = sym->initial_snum;
+ adjustment = sym->value;
+ }
+ }
+
+ /* relative relocation */
+ } else if (pcrel == 1) {
+
+ /* intra-section */
+ if (section == NO_SEG) {
+ r->type = 1; // X86_64_RELOC_SIGNED
+
+ /* inter-section */
+ } else {
+ r->type = 2; // X86_64_RELOC_BRANCH
+ fi = get_section_fileindex_by_index(section);
+
+ /* external */
+ if (fi == NO_SECT) {
+ sect->extreloc = 1;
+ r->snum = raa_read(extsyms, section);
+
+ /* local */
+ } else {
+ sym = get_closest_section_symbol_by_offset(fi, reloff);
+ r->snum = sym->initial_snum;
+ adjustment = sym->value;
+ }
+ }
+
+ /* subtractor */
+ } else if (pcrel == 2) {
+ r->pcrel = 0;
+ r->type = 5; // X86_64_RELOC_SUBTRACTOR
+// r->snum = macho_gotpcrel_sect;
+
+ /* gotpcrel */
+ } else if (pcrel == 3) {
+ r->type = 4; // X86_64_RELOC_GOT
+ } else if (pcrel == 4) {
+ r->type = 3; // X86_64_RELOC_GOT_LOAD
+ }
+
+ ++sect->nreloc;
+
+ return adjustment;
+}
+
+static void macho_output(int32_t secto, const void *data,
+ enum out_type type, uint64_t size,
+ int32_t section, int32_t wrt)
+{
+ struct section *s, *sbss;
+ int64_t addr;
+ uint8_t mydata[16], *p;
+
+ if (secto == NO_SEG) {
+ if (type != OUT_RESERVE)
+ error(ERR_NONFATAL, "attempt to assemble code in "
+ "[ABSOLUTE] space");
+
+ return;
+ }
+
+ s = get_section_by_index(secto);
+
+ if (s == NULL) {
+ error(ERR_WARNING, "attempt to assemble code in"
+ " section %d: defaulting to `.text'", secto);
+ s = get_section_by_name("__TEXT", "__text");
+
+ /* should never happen */
+ if (s == NULL)
+ error(ERR_PANIC, "text section not found");
+ }
+
+ sbss = get_section_by_name("__DATA", "__bss");
+
+ if (s == sbss && type != OUT_RESERVE) {
+ error(ERR_WARNING, "attempt to initialize memory in the"
+ " BSS section: ignored");
+ s->size += realsize(type, size);
+ return;
+ }
+
+ switch (type) {
+ case OUT_RESERVE:
+ if (s != sbss) {
+ error(ERR_WARNING, "uninitialized space declared in"
+ " %s section: zeroing",
+ get_section_name_by_index(secto));
+
+ sect_write(s, NULL, size);
+ } else
+ s->size += size;
+
+ break;
+
+ case OUT_RAWDATA:
+ if (section != NO_SEG)
+ error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
+
+ sect_write(s, data, size);
+ break;
+
+ case OUT_ADDRESS:
+ addr = *(int64_t *)data;
+ if (section != NO_SEG) {
+ if (section % 2) {
+ error(ERR_NONFATAL, "Mach-O format does not support"
+ " section base references");
+ } else {
+ if (wrt == NO_SEG) {
+ if (size < 8) {
+ error(ERR_NONFATAL, "Mach-O 64-bit format does not support"
+ " 32-bit absolute addresses");
+ /*
+ Seemingly, Mach-O's X86_64_RELOC_SUBTRACTOR would require
+ pre-determined knowledge of where the image base would be,
+ making it impractical for use in intermediate object files
+ */
+ } else {
+ addr -= add_reloc(s, section, 0, size, addr);
+ }
+ } else if (wrt == macho_gotpcrel_sect) {
+ addr += s->size;
+ add_reloc(s, section, 3, size, addr); // X86_64_RELOC_GOT
+ } else {
+ error(ERR_NONFATAL, "Mach-O format does not support"
+ " this use of WRT");
+ }
+ }
+ }
+
+ p = mydata;
+ WRITEADDR(p, addr, size);
+ sect_write(s, mydata, size);
+ break;
+
+ case OUT_REL2ADR:
+ p = mydata;
+ WRITESHORT(p, *(int64_t *)data);
+
+ if (section == secto)
+ error(ERR_PANIC, "intra-section OUT_REL2ADR");
+
+ if (section != NO_SEG && section % 2) {
+ error(ERR_NONFATAL, "Mach-O format does not support"
+ " section base references");
+ } else {
+ if (wrt == NO_SEG) {
+ *mydata -= add_reloc(s, section, 2, 2, (int64_t)*mydata);
+ *mydata -= add_reloc(s, section, 0, 2, (int64_t)*mydata);
+ } else {
+ error(ERR_NONFATAL, "Unsupported non-32-bit"
+ " Macho-O relocation [2]");
+ }
+ }
+
+ sect_write(s, mydata, 2L);
+ break;
+
+ case OUT_REL4ADR:
+ p = mydata;
+ WRITELONG(p, *(int64_t *)data);
+
+ if (section == secto)
+ error(ERR_PANIC, "intra-section OUT_REL4ADR");
+
+ if (section != NO_SEG && section % 2) {
+ error(ERR_NONFATAL, "Mach-O format does not support"
+ " section base references");
+ } else {
+ if (wrt == NO_SEG) {
+ *mydata -= add_reloc(s, section, 1, 4, (int64_t)*mydata); // X86_64_RELOC_UNSIGNED/SIGNED/BRANCH
+ } else if (wrt == macho_gotpcrel_sect) {
+ error(ERR_NONFATAL, "Mach-O format cannot produce PC-"
+ "relative GOT references");
+ } else {
+ error(ERR_NONFATAL, "Mach-O format does not support"
+ " this use of WRT");
+ wrt = NO_SEG; /* we can at least _try_ to continue */
+ }
+ }
+
+ sect_write(s, mydata, 4L);
+ break;
+
+ default:
+ error(ERR_PANIC, "unknown output type?");
+ break;
+ }
+}
+
+static int32_t macho_section(char *name, int pass, int *bits)
+{
+ int32_t index, originalIndex;
+ char *sectionAttributes;
+ struct sectmap *sm;
+ struct section *s;
+
+ (void)pass;
+
+ /* Default to 64 bits. */
+ if (!name) {
+ *bits = 64;
+ name = ".text";
+ sectionAttributes = NULL;
+ } else {
+ sectionAttributes = name;
+ name = nasm_strsep(&sectionAttributes, " \t");
+ }
+
+ for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
+ /* make lookup into section name translation table */
+ if (!strcmp(name, sm->nasmsect)) {
+ char *currentAttribute;
+
+ /* try to find section with that name */
+ originalIndex = index = get_section_index_by_name(sm->segname,
+ sm->sectname);
+
+ /* create it if it doesn't exist yet */
+ if (index == -1) {
+ s = *sectstail = nasm_malloc(sizeof(struct section));
+ s->next = NULL;
+ sectstail = &s->next;
+
+ s->data = saa_init(1L);
+ s->index = seg_alloc();
+ s->relocs = NULL;
+ s->align = -1;
+
+ xstrncpy(s->segname, sm->segname);
+ xstrncpy(s->sectname, sm->sectname);
+ s->size = 0;
+ s->nreloc = 0;
+ s->flags = sm->flags;
+
+ index = s->index;
+ } else {
+ s = get_section_by_index(index);
+ }
+
+ while ((NULL != sectionAttributes)
+ && (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
+ if (0 != *currentAttribute) {
+ if (!nasm_strnicmp("align=", currentAttribute, 6)) {
+ char *end;
+ int newAlignment, value;
+
+ value = strtoul(currentAttribute + 6, (char**)&end, 0);
+ newAlignment = exact_log2(value);
+
+ if (0 != *end) {
+ error(ERR_PANIC,
+ "unknown or missing alignment value \"%s\" "
+ "specified for section \"%s\"",
+ currentAttribute + 6,
+ name);
+ return NO_SEG;
+ } else if (0 > newAlignment) {
+ error(ERR_PANIC,
+ "alignment of %d (for section \"%s\") is not "
+ "a power of two",
+ value,
+ name);
+ return NO_SEG;
+ }
+
+ if ((-1 != originalIndex)
+ && (s->align != newAlignment)
+ && (s->align != -1)) {
+ error(ERR_PANIC,
+ "section \"%s\" has already been specified "
+ "with alignment %d, conflicts with new "
+ "alignment of %d",
+ name,
+ (1 << s->align),
+ value);
+ return NO_SEG;
+ }
+
+ s->align = newAlignment;
+ } else if (!nasm_stricmp("data", currentAttribute)) {
+ /* Do nothing; 'data' is implicit */
+ } else {
+ error(ERR_PANIC,
+ "unknown section attribute %s for section %s",
+ currentAttribute,
+ name);
+ return NO_SEG;
+ }
+ }
+ }
+
+ return index;
+ }
+ }
+
+ error(ERR_PANIC, "invalid section name %s", name);
+ return NO_SEG;
+}
+
+static void macho_symdef(char *name, int32_t section, int64_t offset,
+ int is_global, char *special)
+{
+ struct symbol *sym;
+
+ if (special) {
+ error(ERR_NONFATAL, "The Mach-O output format does "
+ "not support any special symbol types");
+ return;
+ }
+
+ if (is_global == 3) {
+ error(ERR_NONFATAL, "The Mach-O format does not "
+ "(yet) support forward reference fixups.");
+ return;
+ }
+
+ sym = *symstail = nasm_malloc(sizeof(struct symbol));
+ sym->next = NULL;
+ symstail = &sym->next;
+
+ sym->name = name;
+ sym->strx = strslen;
+ sym->type = 0;
+ sym->desc = 0;
+ sym->value = offset;
+ sym->initial_snum = -1;
+
+ if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
+ /*
+ * This is a NASM special symbol. We never allow it into
+ * the Macho-O symbol table, even if it's a valid one. If it
+ * _isn't_ a valid one, we should barf immediately.
+ */
+ if (strcmp(name, "..gotpcrel"))
+ error(ERR_NONFATAL, "unrecognized special symbol `%s'", name);
+ return;
+ }
+
+ /* external and common symbols get N_EXT */
+ if (is_global != 0) {
+ sym->type |= N_EXT;
+ }
+
+ if (section == NO_SEG) {
+ /* symbols in no section get absolute */
+ sym->type |= N_ABS;
+ sym->sect = NO_SECT;
+ } else {
+ sym->type |= N_SECT;
+
+ /* get the in-file index of the section the symbol was defined in */
+ sym->sect = get_section_fileindex_by_index(section);
+
+ /* track the initially allocated symbol number for use in future fix-ups */
+ sym->initial_snum = nsyms;
+
+ if (sym->sect == NO_SECT) {
+
+ /* remember symbol number of references to external
+ ** symbols, this works because every external symbol gets
+ ** its own section number allocated internally by nasm and
+ ** can so be used as a key */
+ extsyms = raa_write(extsyms, section, nsyms);
+
+ switch (is_global) {
+ case 1:
+ case 2:
+ /* there isn't actually a difference between global
+ ** and common symbols, both even have their size in
+ ** sym->value */
+ sym->type = N_EXT;
+ break;
+
+ default:
+ /* give an error on unfound section if it's not an
+ ** external or common symbol (assemble_file() does a
+ ** seg_alloc() on every call for them) */
+ error(ERR_PANIC, "in-file index for section %d not found",
+ section);
+ }
+ }
+ }
+ ++nsyms;
+}
+
+static int32_t macho_segbase(int32_t section)
+{
+ return section;
+}
+
+static int macho_directive(char *directive, char *value, int pass)
+{
+ (void)directive;
+ (void)value;
+ (void)pass;
+ return 0;
+}
+
+static void macho_filename(char *inname, char *outname, efunc error)
+{
+ standard_extension(inname, outname, ".o", error);
+}
+
+extern macros_t macho_stdmac[];
+
+/* Comparison function for qsort symbol layout. */
+static int layout_compare (const struct symbol **s1,
+ const struct symbol **s2)
+{
+ return (strcmp ((*s1)->name, (*s2)->name));
+}
+
+/* The native assembler does a few things in a similar function
+
+ * Remove temporary labels
+ * Sort symbols according to local, external, undefined (by name)
+ * Order the string table
+
+ We do not remove temporary labels right now.
+
+ numsyms is the total number of symbols we have. strtabsize is the
+ number entries in the string table. */
+
+static void macho_layout_symbols (uint32_t *numsyms,
+ uint32_t *strtabsize)
+{
+ struct symbol *sym, **symp;
+ uint32_t i,j;
+
+ *numsyms = 0;
+ *strtabsize = sizeof (char);
+
+ symp = &syms;
+
+ while ((sym = *symp)) {
+ /* Undefined symbols are now external. */
+ if (sym->type == N_UNDF)
+ sym->type |= N_EXT;
+
+ if ((sym->type & N_EXT) == 0) {
+ sym->snum = *numsyms;
+ *numsyms = *numsyms + 1;
+ nlocalsym++;
+ }
+ else {
+ if ((sym->type & N_TYPE) != N_UNDF) {
+ nextdefsym++;
+ } else {
+ nundefsym++;
+ }
+
+ /* If we handle debug info we'll want
+ to check for it here instead of just
+ adding the symbol to the string table. */
+ sym->strx = *strtabsize;
+ saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
+ *strtabsize += strlen(sym->name) + 1;
+ }
+ symp = &(sym->next);
+ }
+
+ /* Next, sort the symbols. Most of this code is a direct translation from
+ the Apple cctools symbol layout. We need to keep compatibility with that. */
+ /* Set the indexes for symbol groups into the symbol table */
+ ilocalsym = 0;
+ iextdefsym = nlocalsym;
+ iundefsym = nlocalsym + nextdefsym;
+
+ /* allocate arrays for sorting externals by name */
+ extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
+ undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
+
+ i = 0;
+ j = 0;
+
+ symp = &syms;
+
+ while ((sym = *symp)) {
+
+ if((sym->type & N_EXT) == 0) {
+ sym->strx = *strtabsize;
+ saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
+ *strtabsize += strlen(sym->name) + 1;
+ }
+ else {
+ if((sym->type & N_TYPE) != N_UNDF) {
+ extdefsyms[i++] = sym;
+ } else {
+ undefsyms[j++] = sym;
+ }
+ }
+ symp = &(sym->next);
+ }
+
+ qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
+ (int (*)(const void *, const void *))layout_compare);
+ qsort(undefsyms, nundefsym, sizeof(struct symbol *),
+ (int (*)(const void *, const void *))layout_compare);
+
+ for(i = 0; i < nextdefsym; i++) {
+ extdefsyms[i]->snum = *numsyms;
+ *numsyms += 1;
+ }
+ for(j = 0; j < nundefsym; j++) {
+ undefsyms[j]->snum = *numsyms;
+ *numsyms += 1;
+ }
+}
+
+/* Calculate some values we'll need for writing later. */
+
+static void macho_calculate_sizes (void)
+{
+ struct section *s;
+
+ /* count sections and calculate in-memory and in-file offsets */
+ for (s = sects; s != NULL; s = s->next) {
+ uint64_t pad = 0;
+
+ /* zerofill sections aren't actually written to the file */
+ if ((s->flags & SECTION_TYPE) != S_ZEROFILL)
+ seg_filesize64 += s->size;
+
+ /* recalculate segment address based on alignment and vm size */
+ s->addr = seg_vmsize64;
+ /* we need section alignment to calculate final section address */
+ if (s->align == -1)
+ s->align = DEFAULT_SECTION_ALIGNMENT;
+ if(s->align) {
+ uint64_t newaddr = align(s->addr, 1 << s->align);
+ pad = newaddr - s->addr;
+ s->addr = newaddr;
+ }
+
+ seg_vmsize64 += s->size + pad;
+ ++seg_nsects64;
+ }
+
+ /* calculate size of all headers, load commands and sections to
+ ** get a pointer to the start of all the raw data */
+ if (seg_nsects64 > 0) {
+ ++head_ncmds64;
+ head_sizeofcmds64 +=
+ MACHO_SEGCMD64_SIZE + seg_nsects64 * MACHO_SECTCMD64_SIZE;
+ }
+
+ if (nsyms > 0) {
+ ++head_ncmds64;
+ head_sizeofcmds64 += MACHO_SYMCMD_SIZE;
+ }
+}
+
+/* Write out the header information for the file. */
+
+static void macho_write_header (void)
+{
+ fwriteint32_t(MH_MAGIC_64, machofp); /* magic */
+ fwriteint32_t(CPU_TYPE_X86_64, machofp); /* CPU type */
+ fwriteint32_t(CPU_SUBTYPE_I386_ALL, machofp); /* CPU subtype */
+ fwriteint32_t(MH_OBJECT, machofp); /* Mach-O file type */
+ fwriteint32_t(head_ncmds64, machofp); /* number of load commands */
+ fwriteint32_t(head_sizeofcmds64, machofp); /* size of load commands */
+ fwriteint32_t(0, machofp); /* no flags */
+ fwriteint32_t(0, machofp); /* reserved for future use */
+}
+
+/* Write out the segment load command at offset. */
+
+static uint32_t macho_write_segment (uint64_t offset)
+{
+ uint64_t rel_base = alignint64_t (offset + seg_filesize64);
+ uint32_t s_reloff = 0;
+ struct section *s;
+
+ fwriteint32_t(LC_SEGMENT_64, machofp); /* cmd == LC_SEGMENT_64 */
+
+ /* size of load command including section load commands */
+ fwriteint32_t(MACHO_SEGCMD64_SIZE + seg_nsects64 *
+ MACHO_SECTCMD64_SIZE, machofp);
+
+ /* in an MH_OBJECT file all sections are in one unnamed (name
+ ** all zeros) segment */
+ fwritezero(16, machofp);
+ fwriteint64_t(0, machofp); /* in-memory offset */
+ fwriteint64_t(seg_vmsize64, machofp); /* in-memory size */
+ fwriteint64_t(offset, machofp); /* in-file offset to data */
+ fwriteint64_t(seg_filesize64, machofp); /* in-file size */
+ fwriteint32_t(VM_PROT_DEFAULT, machofp); /* maximum vm protection */
+ fwriteint32_t(VM_PROT_DEFAULT, machofp); /* initial vm protection */
+ fwriteint32_t(seg_nsects64, machofp); /* number of sections */
+ fwriteint32_t(0, machofp); /* no flags */
+
+ /* emit section headers */
+ for (s = sects; s != NULL; s = s->next) {
+ fwrite(s->sectname, sizeof(s->sectname), 1, machofp);
+ fwrite(s->segname, sizeof(s->segname), 1, machofp);
+ fwriteint64_t(s->addr, machofp);
+ fwriteint64_t(s->size, machofp);
+
+ /* dummy data for zerofill sections or proper values */
+ if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
+ fwriteint32_t(offset, machofp);
+ /* Write out section alignment, as a power of two.
+ e.g. 32-bit word alignment would be 2 (2^2 = 4). */
+ if (s->align == -1)
+ s->align = DEFAULT_SECTION_ALIGNMENT;
+ fwriteint32_t(s->align, machofp);
+ /* To be compatible with cctools as we emit
+ a zero reloff if we have no relocations. */
+ fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, machofp);
+ fwriteint32_t(s->nreloc, machofp);
+
+ offset += s->size;
+ s_reloff += s->nreloc * MACHO_RELINFO64_SIZE;
+ } else {
+ fwriteint32_t(0, machofp);
+ fwriteint32_t(0, machofp);
+ fwriteint32_t(0, machofp);
+ fwriteint32_t(0, machofp);
+ }
+
+ if (s->nreloc) {
+ s->flags |= S_ATTR_LOC_RELOC;
+ if (s->extreloc)
+ s->flags |= S_ATTR_EXT_RELOC;
+ }
+
+ fwriteint32_t(s->flags, machofp); /* flags */
+ fwriteint32_t(0, machofp); /* reserved */
+ fwriteint32_t(0, machofp); /* reserved */
+
+ fwriteint32_t(0, machofp); /* align */
+ }
+
+ rel_padcnt64 = rel_base - offset;
+ offset = rel_base + s_reloff;
+
+ return offset;
+}
+
+/* For a given chain of relocs r, write out the entire relocation
+ chain to the object file. */
+
+static void macho_write_relocs (struct reloc *r)
+{
+ while (r) {
+ uint32_t word2;
+
+ fwriteint32_t(r->addr, machofp); /* reloc offset */
+
+ word2 = r->snum;
+ word2 |= r->pcrel << 24;
+ word2 |= r->length << 25;
+ word2 |= r->ext << 27;
+ word2 |= r->type << 28;
+ fwriteint32_t(word2, machofp); /* reloc data */
+ r = r->next;
+ }
+}
+
+/* Write out the section data. */
+static void macho_write_section (void)
+{
+ struct section *s, *s2;
+ struct reloc *r;
+ uint8_t fi, *p, *q, blk[8];
+ int32_t len;
+ int64_t l;
+
+ for (s = sects; s != NULL; s = s->next) {
+ if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
+ continue;
+
+ /* no padding needs to be done to the sections */
+
+ /* Like a.out Mach-O references things in the data or bss
+ * sections by addresses which are actually relative to the
+ * start of the _text_ section, in the _file_. See outaout.c
+ * for more information. */
+ saa_rewind(s->data);
+ for (r = s->relocs; r != NULL; r = r->next) {
+ len = (int32_t)r->length << 1;
+ if(len > 4) len = 8;
+ saa_fread(s->data, r->addr, blk, len);
+ p = q = blk;
+ l = *p++;
+
+ /* get offset based on relocation type */
+ if (r->length > 0) {
+ l += ((int64_t)*p++) << 8;
+
+ if (r->length > 1) {
+ l += ((int64_t)*p++) << 16;
+ l += ((int64_t)*p++) << 24;
+ }
+
+ if (r->length > 2) {
+ l += ((int64_t)*p++) << 32;
+ l += ((int64_t)*p++) << 40;
+ l += ((int64_t)*p++) << 48;
+ l += ((int64_t)*p++) << 56;
+ }
+
+
+ }
+
+ /* If the relocation is internal add to the current section
+ offset. Otherwise the only value we need is the symbol
+ offset which we already have. The linker takes care
+ of the rest of the address. */
+ if (!r->ext) {
+ /* generate final address by section address and offset */
+ for (s2 = sects, fi = 1;
+ s2 != NULL; s2 = s2->next, fi++) {
+ if (fi == r->snum) {
+ l += s2->addr;
+ break;
+ }
+ }
+ }
+
+ /* write new offset back */
+ if (r->length == 3)
+ WRITEDLONG(q, l);
+ else if (r->length == 2)
+ WRITELONG(q, l);
+ else if (r->length == 1)
+ WRITESHORT(q, l);
+ else
+ *q++ = l & 0xFF;
+
+ saa_fwrite(s->data, r->addr, blk, len);
+ }
+
+ /* dump the section data to file */
+ saa_fpwrite(s->data, machofp);
+ }
+
+ /* pad last section up to reloc entries on int64_t boundary */
+ fwritezero(rel_padcnt64, machofp);
+
+ /* emit relocation entries */
+ for (s = sects; s != NULL; s = s->next)
+ macho_write_relocs (s->relocs);
+}
+
+/* Write out the symbol table. We should already have sorted this
+ before now. */
+static void macho_write_symtab (void)
+{
+ struct symbol *sym;
+ struct section *s;
+ int64_t fi;
+ uint64_t i;
+
+ /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
+
+ for (sym = syms; sym != NULL; sym = sym->next) {
+ if ((sym->type & N_EXT) == 0) {
+ fwriteint32_t(sym->strx, machofp); /* string table entry number */
+ fwrite(&sym->type, 1, 1, machofp); /* symbol type */
+ fwrite(&sym->sect, 1, 1, machofp); /* section */
+ fwriteint16_t(sym->desc, machofp); /* description */
+
+ /* Fix up the symbol value now that we know the final section
+ sizes. */
+ if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
+ for (s = sects, fi = 1;
+ s != NULL && fi < sym->sect; s = s->next, ++fi)
+ sym->value += s->size;
+ }
+
+ fwriteint64_t(sym->value, machofp); /* value (i.e. offset) */
+ }
+ }
+
+ for (i = 0; i < nextdefsym; i++) {
+ sym = extdefsyms[i];
+ fwriteint32_t(sym->strx, machofp);
+ fwrite(&sym->type, 1, 1, machofp); /* symbol type */
+ fwrite(&sym->sect, 1, 1, machofp); /* section */
+ fwriteint16_t(sym->desc, machofp); /* description */
+
+ /* Fix up the symbol value now that we know the final section
+ sizes. */
+ if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
+ for (s = sects, fi = 1;
+ s != NULL && fi < sym->sect; s = s->next, ++fi)
+ sym->value += s->size;
+ }
+
+ fwriteint64_t(sym->value, machofp); /* value (i.e. offset) */
+ }
+
+ for (i = 0; i < nundefsym; i++) {
+ sym = undefsyms[i];
+ fwriteint32_t(sym->strx, machofp);
+ fwrite(&sym->type, 1, 1, machofp); /* symbol type */
+ fwrite(&sym->sect, 1, 1, machofp); /* section */
+ fwriteint16_t(sym->desc, machofp); /* description */
+
+ // Fix up the symbol value now that we know the final section sizes.
+ if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
+ for (s = sects, fi = 1;
+ s != NULL && fi < sym->sect; s = s->next, ++fi)
+ sym->value += s->size;
+ }
+
+ fwriteint64_t(sym->value, machofp); // value (i.e. offset)
+ }
+
+}
+
+/* Fixup the snum in the relocation entries, we should be
+ doing this only for externally referenced symbols. */
+static void macho_fixup_relocs (struct reloc *r)
+{
+ struct symbol *sym;
+
+ while (r != NULL) {
+ if (r->ext) {
+ for (sym = syms; sym != NULL; sym = sym->next) {
+ if (sym->initial_snum == r->snum) {
+ r->snum = sym->snum;
+ break;
+ }
+ }
+ }
+ r = r->next;
+ }
+}
+
+/* Write out the object file. */
+
+static void macho_write (void)
+{
+ uint64_t offset = 0;
+
+ /* mach-o object file structure:
+ **
+ ** mach header
+ ** uint32_t magic
+ ** int cpu type
+ ** int cpu subtype
+ ** uint32_t mach file type
+ ** uint32_t number of load commands
+ ** uint32_t size of all load commands
+ ** (includes section struct size of segment command)
+ ** uint32_t flags
+ **
+ ** segment command
+ ** uint32_t command type == LC_SEGMENT_64
+ ** uint32_t size of load command
+ ** (including section load commands)
+ ** char[16] segment name
+ ** uint64_t in-memory offset
+ ** uint64_t in-memory size
+ ** uint64_t in-file offset to data area
+ ** uint64_t in-file size
+ ** (in-memory size excluding zerofill sections)
+ ** int maximum vm protection
+ ** int initial vm protection
+ ** uint32_t number of sections
+ ** uint32_t flags
+ **
+ ** section commands
+ ** char[16] section name
+ ** char[16] segment name
+ ** uint64_t in-memory offset
+ ** uint64_t in-memory size
+ ** uint32_t in-file offset
+ ** uint32_t alignment
+ ** (irrelevant in MH_OBJECT)
+ ** uint32_t in-file offset of relocation entires
+ ** uint32_t number of relocations
+ ** uint32_t flags
+ ** uint32_t reserved
+ ** uint32_t reserved
+ **
+ ** symbol table command
+ ** uint32_t command type == LC_SYMTAB
+ ** uint32_t size of load command
+ ** uint32_t symbol table offset
+ ** uint32_t number of symbol table entries
+ ** uint32_t string table offset
+ ** uint32_t string table size
+ **
+ ** raw section data
+ **
+ ** padding to int64_t boundary
+ **
+ ** relocation data (struct reloc)
+ ** int32_t offset
+ ** uint data (symbolnum, pcrel, length, extern, type)
+ **
+ ** symbol table data (struct nlist)
+ ** int32_t string table entry number
+ ** uint8_t type
+ ** (extern, absolute, defined in section)
+ ** uint8_t section
+ ** (0 for global symbols, section number of definition (>= 1, <=
+ ** 254) for local symbols, size of variable for common symbols
+ ** [type == extern])
+ ** int16_t description
+ ** (for stab debugging format)
+ ** uint64_t value (i.e. file offset) of symbol or stab offset
+ **
+ ** string table data
+ ** list of null-terminated strings
+ */
+
+ /* Emit the Mach-O header. */
+ macho_write_header();
+
+ offset = MACHO_HEADER64_SIZE + head_sizeofcmds64;
+
+ /* emit the segment load command */
+ if (seg_nsects64 > 0)
+ offset = macho_write_segment (offset);
+ else
+ error(ERR_WARNING, "no sections?");
+
+ if (nsyms > 0) {
+ /* write out symbol command */
+ fwriteint32_t(LC_SYMTAB, machofp); /* cmd == LC_SYMTAB */
+ fwriteint32_t(MACHO_SYMCMD_SIZE, machofp); /* size of load command */
+ fwriteint32_t(offset, machofp); /* symbol table offset */
+ fwriteint32_t(nsyms, machofp); /* number of symbol
+ ** table entries */
+
+ offset += nsyms * MACHO_NLIST64_SIZE;
+ fwriteint32_t(offset, machofp); /* string table offset */
+ fwriteint32_t(strslen, machofp); /* string table size */
+ }
+
+ /* emit section data */
+ if (seg_nsects64 > 0)
+ macho_write_section ();
+
+ /* emit symbol table if we have symbols */
+ if (nsyms > 0)
+ macho_write_symtab ();
+
+ /* we don't need to pad here since MACHO_NLIST64_SIZE == 16 */
+
+ /* emit string table */
+ saa_fpwrite(strs, machofp);
+}
+/* We do quite a bit here, starting with finalizing all of the data
+ for the object file, writing, and then freeing all of the data from
+ the file. */
+
+static void macho_cleanup(int debuginfo)
+{
+ struct section *s;
+ struct reloc *r;
+ struct symbol *sym;
+
+ (void)debuginfo;
+
+ /* Sort all symbols. */
+ macho_layout_symbols (&nsyms, &strslen);
+
+ /* Fixup relocation entries */
+ for (s = sects; s != NULL; s = s->next) {
+ macho_fixup_relocs (s->relocs);
+ }
+
+ /* First calculate and finalize needed values. */
+ macho_calculate_sizes();
+ macho_write();
+
+ /* done - yay! */
+ fclose(machofp);
+
+ /* free up everything */
+ while (sects->next) {
+ s = sects;
+ sects = sects->next;
+
+ saa_free(s->data);
+ while (s->relocs != NULL) {
+ r = s->relocs;
+ s->relocs = s->relocs->next;
+ nasm_free(r);
+ }
+
+ nasm_free(s);
+ }
+
+ saa_free(strs);
+ raa_free(extsyms);
+
+ if (syms) {
+ while (syms->next) {
+ sym = syms;
+ syms = syms->next;
+
+ nasm_free (sym);
+ }
+}
+}
+
+/* Debugging routines. */
+static void debug_reloc (struct reloc *r)
+{
+ fprintf (stdout, "reloc:\n");
+ fprintf (stdout, "\taddr: %"PRId32"\n", r->addr);
+ fprintf (stdout, "\tsnum: %d\n", r->snum);
+ fprintf (stdout, "\tpcrel: %d\n", r->pcrel);
+ fprintf (stdout, "\tlength: %d\n", r->length);
+ fprintf (stdout, "\text: %d\n", r->ext);
+ fprintf (stdout, "\ttype: %d\n", r->type);
+}
+
+static void debug_section_relocs (struct section *s)
+{
+ struct reloc *r = s->relocs;
+
+ fprintf (stdout, "relocs for section %s:\n\n", s->sectname);
+
+ while (r != NULL) {
+ debug_reloc (r);
+ r = r->next;
+ }
+}
+
+struct ofmt of_macho64 = {
+ "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
+ "macho64",
+ 0,
+ null_debug_arr,
+ &null_debug_form,
+ macho_stdmac,
+ macho_init,
+ macho_setinfo,
+ macho_output,
+ macho_symdef,
+ macho_section,
+ macho_segbase,
+ macho_directive,
+ macho_filename,
+ macho_cleanup
+};
+
+#endif
+
+/*
+ * Local Variables:
+ * mode:c
+ * c-basic-offset:4
+ * End:
+ *
+ * end of file */
diff --git a/rbtree.c b/rbtree.c
new file mode 100644
index 00000000..5af6067d
--- /dev/null
+++ b/rbtree.c
@@ -0,0 +1,119 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * rbtree.c
+ *
+ * Simple implementation of a left-leaning red-black tree with 64-bit
+ * integer keys. The search operation will return the highest node <=
+ * the key; only search and insert are supported, but additional
+ * standard llrbtree operations can be coded up at will.
+ *
+ * See http://www.cs.princeton.edu/~rs/talks/LLRB/RedBlack.pdf for
+ * information about left-leaning red-black trees.
+ */
+
+#include "rbtree.h"
+
+struct rbtree *rb_search(struct rbtree *tree, uint64_t key)
+{
+ struct rbtree *best = NULL;
+
+ while (tree) {
+ if (tree->key == key)
+ return tree;
+ else if (tree->key > key)
+ tree = tree->left;
+ else {
+ best = tree;
+ tree = tree->right;
+ }
+ }
+ return best;
+}
+
+static bool is_red(struct rbtree *h)
+{
+ return h && h->red;
+}
+
+static struct rbtree *rotate_left(struct rbtree *h)
+{
+ struct rbtree *x = h->right;
+ h->right = x->left;
+ x->left = h;
+ x->red = x->left->red;
+ x->left->red = true;
+ return x;
+}
+
+static struct rbtree *rotate_right(struct rbtree *h)
+{
+ struct rbtree *x = h->left;
+ h->left = x->right;
+ x->right = h;
+ x->red = x->right->red;
+ x->right->red = true;
+ return x;
+}
+
+static void color_flip(struct rbtree *h)
+{
+ h->red = !h->red;
+ h->left->red = !h->left->red;
+ h->right->red = !h->right->red;
+}
+
+struct rbtree *rb_insert(struct rbtree *tree, struct rbtree *node)
+{
+ if (!tree) {
+ node->red = true;
+ return node;
+ }
+
+ if (is_red(tree->left) && is_red(tree->right))
+ color_flip(tree);
+
+ if (node->key < tree->key)
+ tree->left = rb_insert(tree->left, node);
+ else
+ tree->right = rb_insert(tree->right, node);
+
+ if (is_red(tree->right))
+ tree = rotate_left(tree);
+
+ if (is_red(tree->left) && is_red(tree->left->left))
+ tree = rotate_right(tree);
+
+ return tree;
+}
diff --git a/rbtree.h b/rbtree.h
new file mode 100644
index 00000000..ef34789f
--- /dev/null
+++ b/rbtree.h
@@ -0,0 +1,52 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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 NASM_RBTREE_H
+#define NASM_RBTREE_H
+
+#include "compiler.h"
+#include <inttypes.h>
+
+/* This structure should be embedded in a larger data structure;
+ the final output from rb_search() can then be converted back
+ to the larger data structure via container_of(). */
+struct rbtree {
+ uint64_t key;
+ struct rbtree *left, *right;
+ bool red;
+};
+
+struct rbtree *rb_insert(struct rbtree *, struct rbtree *);
+struct rbtree *rb_search(struct rbtree *, uint64_t);
+
+#endif /* NASM_RBTREE_H */
diff --git a/rdoff/rdf2ihx.1 b/rdoff/rdf2ihx.1
new file mode 100644
index 00000000..43b33071
--- /dev/null
+++ b/rdoff/rdf2ihx.1
@@ -0,0 +1 @@
+.so man1/rdf2bin.1
diff --git a/rdoff/rdf2ith.1 b/rdoff/rdf2ith.1
new file mode 100644
index 00000000..43b33071
--- /dev/null
+++ b/rdoff/rdf2ith.1
@@ -0,0 +1 @@
+.so man1/rdf2bin.1
diff --git a/rdoff/rdf2srec.1 b/rdoff/rdf2srec.1
new file mode 100644
index 00000000..43b33071
--- /dev/null
+++ b/rdoff/rdf2srec.1
@@ -0,0 +1 @@
+.so man1/rdf2bin.1
diff --git a/test/align13.asm b/test/align13.asm
new file mode 100644
index 00000000..556373fc
--- /dev/null
+++ b/test/align13.asm
@@ -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
diff --git a/test/align13s.asm b/test/align13s.asm
new file mode 100644
index 00000000..dab21a20
--- /dev/null
+++ b/test/align13s.asm
@@ -0,0 +1,16 @@
+; 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
diff --git a/test/andbyte.asm b/test/andbyte.asm
new file mode 100644
index 00000000..3d3b1c1a
--- /dev/null
+++ b/test/andbyte.asm
@@ -0,0 +1,15 @@
+;Testname=test; Arguments=-fbin -oandbyte.bin; Files=stdout stderr andbyte.bin
+;Testname=otest; Arguments=-Ox -fbin -oandbyte.bin; Files=stdout stderr andbyte.bin
+
+ 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
diff --git a/test/avx005.asm b/test/avx005.asm
new file mode 100644
index 00000000..08765140
--- /dev/null
+++ b/test/avx005.asm
@@ -0,0 +1,529 @@
+;Testname=avx005; Arguments=-fbin -oavx005.bin -Ox; Files=stdout stderr avx005.bin
+
+%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
+
+
diff --git a/test/br2148476.asm b/test/br2148476.asm
new file mode 100644
index 00000000..1b263c98
--- /dev/null
+++ b/test/br2148476.asm
@@ -0,0 +1,221 @@
+;Testname=test; Arguments=-fbin -obr2148476.bin; Files=.stdout .stderr br2148476.bin
+
+ bits 64
+
+ cvtdq2pd xmm0, xmm1
+ cvtdq2pd xmm0, [rdi]
+ cvtdq2pd xmm0, qword [rdi]
+
+ cvtdq2ps xmm0, xmm1
+ cvtdq2ps xmm0, [rdi]
+ cvtdq2ps xmm0, oword [rdi]
+
+ cvtpd2dq xmm0, xmm1
+ cvtpd2dq xmm0, [rdi]
+ cvtpd2dq xmm0, oword [rdi]
+
+ cvtpd2pi mm0, xmm1
+ cvtpd2pi mm0, [rdi]
+ cvtpd2pi mm0, oword [rdi]
+
+ cvtpd2ps xmm0, xmm1
+ cvtpd2ps xmm0, [rdi]
+ cvtpd2ps xmm0, oword [rdi]
+
+ cvtpi2pd xmm0, mm1
+ cvtpi2pd xmm0, [rdi]
+ cvtpi2pd xmm0, qword [rdi]
+
+ cvtpi2ps xmm0, mm1
+ cvtpi2ps xmm0, [rdi]
+ cvtpi2ps xmm0, qword [rdi]
+
+ cvtps2dq xmm0, xmm1
+ cvtps2dq xmm0, [rdi]
+ cvtps2dq xmm0, oword [rdi]
+
+ cvtps2pd xmm0, xmm1
+ cvtps2pd xmm0, [rdi]
+ cvtps2pd xmm0, qword [rdi]
+
+ cvtps2pi mm0, xmm1
+ cvtps2pi mm0, [rdi]
+ cvtps2pi mm0, qword [rdi]
+
+ cvtsd2si eax, xmm1
+ cvtsd2si eax, [rdi]
+ cvtsd2si eax, qword [rdi]
+ cvtsd2si rax, xmm1
+ cvtsd2si rax, [rdi]
+ cvtsd2si rax, qword [rdi]
+
+ cvtsd2ss xmm0, xmm1
+ cvtsd2ss xmm0, [rdi]
+ cvtsd2ss xmm0, qword [rdi]
+
+ cvtsi2sd xmm0, eax
+ cvtsi2sd xmm0, [rdi] ; Compatibility
+ cvtsi2sd xmm0, dword [rdi]
+ cvtsi2sd xmm0, rax
+ cvtsi2sd xmm0, qword [rdi]
+
+ cvtsi2ss xmm0, eax
+ cvtsi2ss xmm0, [rdi] ; Compatibility
+ cvtsi2ss xmm0, dword [rdi]
+ cvtsi2ss xmm0, rax
+ cvtsi2ss xmm0, qword [rdi]
+
+ cvtss2sd xmm0, xmm1
+ cvtss2sd xmm0, [rdi]
+ cvtss2sd xmm0, dword [rdi]
+
+ cvtss2si eax, xmm1
+ cvtss2si eax, [rdi]
+ cvtss2si eax, dword [rdi]
+ cvtss2si rax, xmm1
+ cvtss2si rax, [rdi]
+ cvtss2si rax, dword [rdi]
+
+ cvttpd2dq xmm0, xmm1
+ cvttpd2dq xmm0, [rdi]
+ cvttpd2dq xmm0, oword [rdi]
+
+ cvttpd2pi mm0, xmm1
+ cvttpd2pi mm0, [rdi]
+ cvttpd2pi mm0, oword [rdi]
+
+ cvttps2dq xmm0, xmm1
+ cvttps2dq xmm0, [rdi]
+ cvttps2dq xmm0, oword [rdi]
+
+ cvttps2pi mm0, xmm1
+ cvttps2pi mm0, [rdi]
+ cvttps2pi mm0, qword [rdi]
+
+ cvttsd2si eax, xmm1
+ cvttsd2si eax, [rdi] ; Compatibility
+ cvttsd2si eax, qword [rdi]
+ cvttsd2si rax, xmm1
+ cvttsd2si rax, [rdi]
+ cvttsd2si rax, qword [rdi]
+
+ cvttss2si eax, xmm1
+ cvttss2si eax, [rdi] ; Compatibility
+ cvttss2si eax, dword [rdi]
+ cvttss2si rax, xmm1
+ cvttss2si rax, [rdi]
+ cvttss2si rax, dword [rdi]
+
+ vcvtdq2pd xmm0, xmm1
+ vcvtdq2pd xmm0, [rdi]
+ vcvtdq2pd xmm0, qword [rdi]
+ vcvtdq2pd ymm0, xmm1
+ vcvtdq2pd ymm0, [rdi]
+ vcvtdq2pd ymm0, oword [rdi]
+
+ vcvtdq2ps xmm0, xmm1
+ vcvtdq2ps xmm0, [rdi]
+ vcvtdq2ps xmm0, oword [rdi]
+ vcvtdq2ps ymm0, ymm1
+ vcvtdq2ps ymm0, [rdi]
+ vcvtdq2ps ymm0, yword [rdi]
+
+ vcvtpd2dq xmm0, xmm1
+ vcvtpd2dq xmm0, oword [rdi]
+ vcvtpd2dq xmm0, ymm1
+ vcvtpd2dq xmm0, yword [rdi]
+
+ vcvtpd2ps xmm0, xmm1
+ vcvtpd2ps xmm0, oword [rdi]
+ vcvtpd2ps xmm0, ymm1
+ vcvtpd2ps xmm0, yword [rdi]
+
+ vcvtps2dq xmm0, xmm1
+ vcvtps2dq xmm0, [rdi]
+ vcvtps2dq xmm0, oword [rdi]
+ vcvtps2dq ymm0, ymm1
+ vcvtps2dq ymm0, [rdi]
+ vcvtps2dq ymm0, yword [rdi]
+
+ vcvtps2pd xmm0, xmm1
+ vcvtps2pd xmm0, [rdi]
+ vcvtps2pd xmm0, qword [rdi]
+ vcvtps2pd ymm0, xmm1
+ vcvtps2pd ymm0, [rdi]
+ vcvtps2pd ymm0, oword [rdi]
+
+ vcvtsd2si eax, xmm1
+ vcvtsd2si eax, [rdi]
+ vcvtsd2si eax, qword [rdi]
+ vcvtsd2si rax, xmm1
+ vcvtsd2si rax, [rdi]
+ vcvtsd2si rax, qword [rdi]
+
+ vcvtsd2ss xmm0, xmm1
+ vcvtsd2ss xmm0, [rdi]
+ vcvtsd2ss xmm0, qword [rdi]
+ vcvtsd2ss xmm0, xmm1, xmm2
+ vcvtsd2ss xmm0, xmm1, [rdi]
+ vcvtsd2ss xmm0, xmm1, qword [rdi]
+
+ vcvtsi2sd xmm0, eax
+ vcvtsi2sd xmm0, [rdi] ; Compatibility
+ vcvtsi2sd xmm0, dword [rdi]
+ vcvtsi2sd xmm0, rax
+ vcvtsi2sd xmm0, qword [rdi]
+ vcvtsi2sd xmm0, xmm1, eax
+ vcvtsi2sd xmm0, xmm1, [rdi] ; Compatibility
+ vcvtsi2sd xmm0, xmm1, dword [rdi]
+ vcvtsi2sd xmm0, xmm1, rax
+ vcvtsi2sd xmm0, xmm1, qword [rdi]
+
+ vcvtsi2ss xmm0, eax
+ vcvtsi2ss xmm0, [rdi] ; Compatibility
+ vcvtsi2ss xmm0, dword [rdi]
+ vcvtsi2ss xmm0, rax
+ vcvtsi2ss xmm0, qword [rdi]
+ vcvtsi2ss xmm0, xmm1, eax
+ vcvtsi2ss xmm0, xmm1, [rdi] ; Compatibility
+ vcvtsi2ss xmm0, xmm1, dword [rdi]
+ vcvtsi2ss xmm0, xmm1, rax
+ vcvtsi2ss xmm0, xmm1, qword [rdi]
+
+ vcvtss2sd xmm0, xmm1
+ vcvtss2sd xmm0, [rdi]
+ vcvtss2sd xmm0, dword [rdi]
+ vcvtss2sd xmm0, xmm1, xmm2
+ vcvtss2sd xmm0, xmm1, [rdi]
+ vcvtss2sd xmm0, xmm1, dword [rdi]
+
+ vcvtss2si eax, xmm1
+ vcvtss2si eax, [rdi]
+ vcvtss2si eax, dword [rdi]
+ vcvtss2si rax, xmm1
+ vcvtss2si rax, [rdi]
+ vcvtss2si rax, dword [rdi]
+
+ vcvttpd2dq xmm0, xmm1
+ vcvttpd2dq xmm0, oword [rdi]
+ vcvttpd2dq xmm0, ymm1
+ vcvttpd2dq xmm0, yword [rdi]
+
+ vcvttps2dq xmm0, xmm1
+ vcvttps2dq xmm0, [rdi]
+ vcvttps2dq xmm0, oword [rdi]
+ vcvttps2dq ymm0, ymm1
+ vcvttps2dq ymm0, [rdi]
+ vcvttps2dq ymm0, yword [rdi]
+
+ vcvttsd2si eax, xmm1
+ vcvttsd2si eax, [rdi] ; Compatibility
+ vcvttsd2si eax, qword [rdi]
+ vcvttsd2si rax, xmm1
+ vcvttsd2si rax, [rdi]
+ vcvttsd2si rax, qword [rdi]
+
+ vcvttss2si eax, xmm1
+ vcvttss2si eax, [rdi] ; Compatibility
+ vcvttss2si eax, dword [rdi]
+ vcvttss2si rax, xmm1
+ vcvttss2si rax, [rdi]
+ vcvttss2si rax, dword [rdi]
diff --git a/test/br2222615.asm b/test/br2222615.asm
new file mode 100644
index 00000000..7acef6c8
--- /dev/null
+++ b/test/br2222615.asm
@@ -0,0 +1,19 @@
+;Testname=noerror; Arguments=-fbin -obr2222615.bin; Files=stdout stderr br2222615.bin
+;Testname=error; Arguments=-DERROR -fbin -obr2222615.bin; Files=stdout stderr br2222615.bin
+
+%macro bluttan 0
+ nop
+%endmacro
+
+%ifnmacro bluttan
+ %error "bluttan is a macro"
+%endif
+
+%ifmacro blej
+ %error "blej is not a macro"
+%endif
+
+%ifdef ERROR
+ %ifnmacro
+ %endif
+%endif
diff --git a/test/br890790.asm b/test/br890790.asm
new file mode 100644
index 00000000..a0023825
--- /dev/null
+++ b/test/br890790.asm
@@ -0,0 +1,7 @@
+;Testname=test; Arguments=-fbin -obr890790.bin; Files=stdout stderr br890790.bin
+%rep 5
+ db 0
+ %include "br890790_i.asm"
+%endrep
+
+db 1
diff --git a/test/br890790_i.asm b/test/br890790_i.asm
new file mode 100644
index 00000000..7ff797f3
--- /dev/null
+++ b/test/br890790_i.asm
@@ -0,0 +1 @@
+db 2
diff --git a/test/crc32.asm b/test/crc32.asm
new file mode 100644
index 00000000..c1ddb296
--- /dev/null
+++ b/test/crc32.asm
@@ -0,0 +1,37 @@
+;Testname=test; Arguments=-fbin -ocrc32.bin; Files=stdout stderr crc32.bin
+
+ bits 16
+
+ crc32 eax,cl
+ crc32 eax,byte [di]
+ crc32 eax,cx
+ crc32 eax,word [di]
+ crc32 eax,ecx
+ crc32 eax,dword [di]
+
+ bits 32
+ align 16
+
+ crc32 eax,cl
+ crc32 eax,byte [edi]
+ crc32 eax,cx
+ crc32 eax,word [edi]
+ crc32 eax,ecx
+ crc32 eax,dword [edi]
+
+ bits 64
+ align 16
+
+ crc32 eax,cl
+ crc32 eax,byte [rdi]
+ crc32 eax,r9b
+ crc32 eax,cx
+ crc32 eax,word [rdi]
+ crc32 eax,ecx
+ crc32 eax,dword [rdi]
+ crc32 rax,cl
+ crc32 rax,byte [rdi]
+ crc32 rax,r9b
+ crc32 rax,rcx
+ crc32 rax,qword [rdi]
+ crc32 rax,r9
diff --git a/test/elf64so.asm b/test/elf64so.asm
new file mode 100644
index 00000000..f1b23464
--- /dev/null
+++ b/test/elf64so.asm
@@ -0,0 +1,118 @@
+; test source file for assembling to ELF64 shared library
+; build with:
+; nasm -f elf64 elf64so.asm
+; ld -shared -o elf64so.so elf64so.o
+; test with:
+; gcc -o elf64so elftest64.c ./elf64so.so
+; ./elf64so
+
+; 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 64
+ GLOBAL lrotate:function ; [1]
+ GLOBAL greet_s:function ; [1]
+ GLOBAL greet_m:function ; [1]
+ GLOBAL asmstr:data asmstr.end-asmstr ; [2]
+ GLOBAL textptr:data 8 ; [2]
+ GLOBAL selfptr:data 8 ; [2]
+ GLOBAL useless:data 8 ; [3]
+ GLOBAL integer:data 8 ; [3]
+ EXTERN printf ; [10]
+ COMMON commvar 8:8 ; [7]
+ EXTERN _GLOBAL_OFFSET_TABLE_
+
+ SECTION .text
+
+; prototype: long lrotate(long x, int num);
+lrotate: ; [1]
+ push rbp
+ mov rbp,rsp
+ mov rax,rdi
+ mov rcx,rsi
+.label rol rax,1 ; [4] [8]
+ loop .label ; [9] [12]
+ mov rsp,rbp
+ pop rbp
+ ret
+
+;; prototype: void greet_*(void);
+;;
+;; Arguments are: rdi - rsi - rdx - rcx - r8 - r9
+;; Registers: rbx, rbp, r12-r15 are saved
+;; greet_s() is Small PIC model, greet_m() is Medium PIC model
+;; (Large model cannot be linked with other code)
+;;
+greet_s:
+ ;; This instruction is useless, this is only a test...
+ cmp qword [rel integer wrt ..got],0
+ mov rax,[rel commvar wrt ..got] ; &commvar
+ mov rcx,[rax] ; commvar
+ mov rax,[rel integer wrt ..got] ; &integer
+ mov rsi,[rax]
+ lea rdx,[rsi+1]
+ mov [rel localint],rdx ; localint = integer+1
+ mov rax,[rel localptr] ; localptr
+ mov rdx,[rax] ; *localptr = localint
+ lea rdi,[rel printfstr]
+ xor eax,eax ; No fp arguments
+ jmp printf wrt ..plt ; [10]
+
+greet_m:
+ push r15 ; Used by convention...
+ lea r15,[rel _GLOBAL_OFFSET_TABLE_]
+ mov rax,[rel commvar wrt ..got] ; &commvar
+ mov rcx,[rax] ; commvar
+ mov rax,[rel integer wrt ..got] ; &integer
+ mov rsi,[rax]
+ lea rdx,[rsi+1]
+ mov rax,localint wrt ..gotoff ; &localint - r15
+ mov [rax+r15],rdx ; localint = integer+1
+ mov rax,localptr wrt ..gotoff ; &localptr - r15
+ mov rax,[rax+r15] ; localptr
+ mov rdx,[rax] ; *localptr = localint
+ mov rdi,printfstr wrt ..gotoff ; &printfstr - r15
+ add rdi,r15 ; &printfstr
+ xor eax,eax ; No fp arguments
+ pop r15
+ jmp printf wrt ..plt ; [10]
+
+ SECTION .data
+
+; a string
+asmstr db 'hello, world', 0 ; [2]
+.end:
+
+; a string for Printf
+printfstr db "integer=%ld, localint=%ld, commvar=%ld", 10, 0
+
+; some pointers
+localptr dq localint ; [5] [17]
+textptr dq greet_s wrt ..sym ; [15]
+selfptr dq selfptr wrt ..sym ; [16]
+
+ SECTION .bss
+; a useless symbol
+useless resq 1
+
+; an integer
+integer resq 1 ; [3]
+
+; a local integer
+localint resq 1 ; [6]
diff --git a/test/elftest64.c b/test/elftest64.c
new file mode 100644
index 00000000..1f3dec1f
--- /dev/null
+++ b/test/elftest64.c
@@ -0,0 +1,43 @@
+/*
+ * build with:
+ * nasm -f elf64 elf64so.asm
+ * ld -shared -o elf64so.so elf64so.o
+ * test with:
+ * gcc -o elf64so elftest64.c ./elf64so.so
+ * ./elf64so
+ */
+
+#include <stdio.h>
+#include <inttypes.h>
+
+extern long lrotate(long, int);
+extern void greet_s(void);
+extern void greet_m(void);
+extern int8_t asmstr[];
+extern void *selfptr;
+extern void *textptr;
+extern long integer;
+long commvar;
+
+int main(void)
+{
+
+ printf("Testing lrotate: should get 0x00400000, 0x00000001\n");
+ printf("lrotate(0x00040000, 4) = 0x%08lx\n", lrotate(0x40000, 4));
+ printf("lrotate(0x00040000, 46) = 0x%08lx\n", lrotate(0x40000, 46));
+
+ printf("This string should read `hello, world': `%s'\n", asmstr);
+
+ printf("&integer = %p, &commvar = %p\n", &integer, &commvar);
+ printf("The integers here should be 1234, 1235 and 4321:\n");
+ integer = 1234;
+ commvar = 4321;
+ greet_s();
+ greet_m();
+
+ printf("These pointers should be equal: %p and %p\n", &greet_s, textptr);
+
+ printf("So should these: %p and %p\n", selfptr, &selfptr);
+
+ return 0;
+}
diff --git a/test/fwdopt.asm b/test/fwdopt.asm
new file mode 100644
index 00000000..48dbc3fc
--- /dev/null
+++ b/test/fwdopt.asm
@@ -0,0 +1,133 @@
+;Testname=test; Arguments=-fbin -ofwdopt.bin; Files=stdout stderr fwdopt.bin
+n0: jmp n1
+n1: jmp n2
+n2: jmp n3
+n3: jmp n4
+n4: jmp n5
+n5: jmp n6
+n6: jmp n7
+n7: jmp n8
+n8: jmp n9
+n9: jmp n10
+n10: jmp n11
+n11: jmp n12
+n12: jmp n13
+n13: jmp n14
+n14: jmp n15
+n15: jmp n16
+n16: jmp n17
+n17: jmp n18
+n18: jmp n19
+n19: jmp n20
+n20: jmp n21
+n21: jmp n22
+n22: jmp n23
+n23: jmp n24
+n24: jmp n25
+n25: jmp n26
+n26: jmp n27
+n27: jmp n28
+n28: jmp n29
+n29: jmp n30
+n30: jmp n31
+n31: jmp n32
+n32: jmp n33
+n33: jmp n34
+n34: jmp n35
+n35: jmp n36
+n36: jmp n37
+n37: jmp n38
+n38: jmp n39
+n39: jmp n40
+n40: jmp n41
+n41: jmp n42
+n42: jmp n43
+n43: jmp n44
+n44: jmp n45
+n45: jmp n46
+n46: jmp n47
+n47: jmp n48
+n48: jmp n49
+n49: jmp n50
+n50: jmp n51
+n51: jmp n52
+n52: jmp n53
+n53: jmp n54
+n54: jmp n55
+n55: jmp n56
+n56: jmp n57
+n57: jmp n58
+n58: jmp n59
+n59: jmp n60
+n60: jmp n61
+n61: jmp n62
+n62: jmp n63
+n63: jmp n64
+n64: jmp n65
+n65: jmp n66
+n66: jmp n67
+n67: jmp n68
+n68: jmp n69
+n69: jmp n70
+n70: jmp n71
+n71: jmp n72
+n72: jmp n73
+n73: jmp n74
+n74: jmp n75
+n75: jmp n76
+n76: jmp n77
+n77: jmp n78
+n78: jmp n79
+n79: jmp n80
+n80: jmp n81
+n81: jmp n82
+n82: jmp n83
+n83: jmp n84
+n84: jmp n85
+n85: jmp n86
+n86: jmp n87
+n87: jmp n88
+n88: jmp n89
+n89: jmp n90
+n90: jmp n91
+n91: jmp n92
+n92: jmp n93
+n93: jmp n94
+n94: jmp n95
+n95: jmp n96
+n96: jmp n97
+n97: jmp n98
+n98: jmp n99
+n99: jmp n100
+n100: jmp n101
+n101: jmp n102
+n102: jmp n103
+n103: jmp n104
+n104: jmp n105
+n105: jmp n106
+n106: jmp n107
+n107: jmp n108
+n108: jmp n109
+n109: jmp n110
+n110: jmp n111
+n111: jmp n112
+n112: jmp n113
+n113: jmp n114
+n114: jmp n115
+n115: jmp n116
+n116: jmp n117
+n117: jmp n118
+n118: jmp n119
+n119: jmp n120
+n120: jmp n121
+n121: jmp n122
+n122: jmp n123
+n123: jmp n124
+n124: jmp n125
+n125: jmp n126
+n126: jmp n127
+n127: jmp n0
+
+ ;; This should emit exactly 3 NOP bytes
+ times 260-($-$$) nop
+ hlt
diff --git a/test/fwdoptpp.asm b/test/fwdoptpp.asm
new file mode 100644
index 00000000..e1f5dd63
--- /dev/null
+++ b/test/fwdoptpp.asm
@@ -0,0 +1,150 @@
+;Testname=error; Arguments=-fbin -DERROR -ofwdoptpp.bin; Files=stdout stderr fwdoptpp.bin
+;Testname=fatal; Arguments=-fbin -DFATAL -ofwdoptpp.bin; Files=stdout stderr fwdoptpp.bin
+;Testname=warning; Arguments=-fbin -DWARNING -ofwdoptpp.bin; Files=stdout stderr fwdoptpp.bin
+
+%ifndef ERROR
+ %ifndef FATAL
+ %ifndef WARNING
+ %define ERROR 1
+ %endif
+ %endif
+%endif
+
+n0: jmp n1
+n1: jmp n2
+n2: jmp n3
+n3: jmp n4
+n4: jmp n5
+n5: jmp n6
+n6: jmp n7
+n7: jmp n8
+n8: jmp n9
+n9: jmp n10
+n10: jmp n11
+n11: jmp n12
+n12: jmp n13
+n13: jmp n14
+n14: jmp n15
+n15: jmp n16
+n16: jmp n17
+n17: jmp n18
+n18: jmp n19
+n19: jmp n20
+n20: jmp n21
+n21: jmp n22
+n22: jmp n23
+n23: jmp n24
+n24: jmp n25
+n25: jmp n26
+n26: jmp n27
+n27: jmp n28
+n28: jmp n29
+n29: jmp n30
+n30: jmp n31
+n31: jmp n32
+n32: jmp n33
+n33: jmp n34
+n34: jmp n35
+n35: jmp n36
+n36: jmp n37
+n37: jmp n38
+n38: jmp n39
+n39: jmp n40
+n40: jmp n41
+n41: jmp n42
+n42: jmp n43
+n43: jmp n44
+n44: jmp n45
+n45: jmp n46
+n46: jmp n47
+n47: jmp n48
+n48: jmp n49
+n49: jmp n50
+n50: jmp n51
+n51: jmp n52
+n52: jmp n53
+n53: jmp n54
+n54: jmp n55
+n55: jmp n56
+n56: jmp n57
+n57: jmp n58
+n58: jmp n59
+n59: jmp n60
+n60: jmp n61
+n61: jmp n62
+n62: jmp n63
+n63: jmp n64
+n64: jmp n65
+n65: jmp n66
+n66: jmp n67
+n67: jmp n68
+n68: jmp n69
+n69: jmp n70
+n70: jmp n71
+n71: jmp n72
+n72: jmp n73
+n73: jmp n74
+n74: jmp n75
+n75: jmp n76
+n76: jmp n77
+n77: jmp n78
+n78: jmp n79
+n79: jmp n80
+n80: jmp n81
+n81: jmp n82
+n82: jmp n83
+n83: jmp n84
+n84: jmp n85
+n85: jmp n86
+n86: jmp n87
+n87: jmp n88
+n88: jmp n89
+n89: jmp n90
+n90: jmp n91
+n91: jmp n92
+n92: jmp n93
+n93: jmp n94
+n94: jmp n95
+n95: jmp n96
+n96: jmp n97
+n97: jmp n98
+n98: jmp n99
+n99: jmp n100
+n100: jmp n101
+n101: jmp n102
+n102: jmp n103
+n103: jmp n104
+n104: jmp n105
+n105: jmp n106
+n106: jmp n107
+n107: jmp n108
+n108: jmp n109
+n109: jmp n110
+n110: jmp n111
+n111: jmp n112
+n112: jmp n113
+n113: jmp n114
+n114: jmp n115
+n115: jmp n116
+n116: jmp n117
+n117: jmp n118
+n118: jmp n119
+n119: jmp n120
+n120: jmp n121
+n121: jmp n122
+n122: jmp n123
+n123: jmp n124
+n124: jmp n125
+n125: jmp n126
+n126: jmp n127
+n127: jmp n0
+
+%if ($-$$) > 257
+ %ifdef FATAL
+ %fatal "Out of space!"
+ %elifdef ERROR
+ %error "Out of space!"
+ %elifdef WARNING
+ %warning "Out of space!"
+ %endif
+%endif
diff --git a/test/gotoff64.asm b/test/gotoff64.asm
new file mode 100644
index 00000000..05f5882b
--- /dev/null
+++ b/test/gotoff64.asm
@@ -0,0 +1,25 @@
+;Testname=noerr; Arguments=-felf64 -ogotoff64.o; Files=stdout stderr gotoff64.o
+;Testname=err; Arguments=-DERROR -felf64 -ogotoff64.o; Files=stdout stderr gotoff64.o
+
+ bits 64
+ default rel
+
+ extern foo
+
+ mov r15,[foo wrt ..got]
+ lea r12,[foo wrt ..got]
+%ifdef ERROR
+ lea rax,[foo wrt ..gotoff]
+ mov rax,[foo wrt ..gotoff]
+%endif
+
+ default abs
+
+ mov r15,[foo wrt ..got]
+ lea r12,[foo wrt ..got]
+ mov rax,[qword foo wrt ..got]
+%ifdef ERROR
+ lea rax,[foo wrt ..gotoff]
+ mov rax,[foo wrt ..gotoff]
+%endif
+ mov rax,[qword foo wrt ..gotoff]
diff --git a/test/ifelse.asm b/test/ifelse.asm
new file mode 100644
index 00000000..bbb0d796
--- /dev/null
+++ b/test/ifelse.asm
@@ -0,0 +1,46 @@
+;Testname=ifelse; Arguments=-fbin -oifelse.bin; Files=stdout stderr ifelse.bin
+
+;No problems -> db 3
+%if 0
+ db 0
+%elif 0 > 0
+ db 1
+%elif 1 < 1
+ db 2
+%else
+ db 3
+%endif
+
+;Garbage after else, elif after else -> db 5
+%if 0
+ db 4
+%else trailing garbage
+ db 5
+%elif 1
+ db 6
+%endif
+
+;Garbage after endif ->
+%if 0
+ db 7
+%endif trailing garbage
+
+;else after else -> db 9
+%if 0
+ db 8
+%else
+ db 9
+%else
+ db 10
+%endif
+
+;Problem preprocessed out, no warning ->
+%if 0
+ %if 1
+ db 11
+ %else
+ db 12
+ %else
+ db 13
+ %endif
+%endif
diff --git a/test/immwarn.asm b/test/immwarn.asm
new file mode 100644
index 00000000..8bffbfae
--- /dev/null
+++ b/test/immwarn.asm
@@ -0,0 +1,91 @@
+;Testname=onowarn; Arguments=-Ox -DOPT=1 -DWARN=0 -fbin -oimmwarn.bin; Files=stdout stderr immwarn.bin
+;Testname=owarn; Arguments=-Ox -DOPT=1 -DWARN=1 -fbin -oimmwarn.bin; Files=stdout stderr immwarn.bin
+;Testname=nowarn; Arguments=-O0 -DOPT=0 -DWARN=0 -fbin -oimmwarn.bin; Files=stdout stderr immwarn.bin
+;Testname=warn; Arguments=-O0 -DOPT=1 -DWARN=1 -fbin -oimmwarn.bin; Files=stdout stderr immwarn.bin
+
+%ifndef WARN
+ %define WARN 1
+%endif
+
+ bits 16
+ push 1
+%if WARN
+ push 0ffffffffh
+%endif
+ push -1
+ push 0ffffh
+ push byte 0FFFFh
+
+ add ax,0FFFFh
+%if WARN
+ add ax,0FFFFFFFFh
+%endif
+ add ax,-1
+ add ax,byte 0FFFFh
+%if WARN
+ add ax,byte 0FFFFFFFFh
+%endif
+ add ax,-1
+
+ add cx,0FFFFh
+%if WARN
+ add cx,0FFFFFFFFh
+%endif
+ add cx,-1
+ add cx,byte 0FFFFh
+%if WARN
+ add cx,byte 0FFFFFFFFh
+%endif
+ add cx,-1
+
+ bits 32
+ push 1
+ push 0ffffffffh
+ push -1
+ push 0ffffh
+
+ push byte 1
+%if WARN
+ push byte 0ffffh
+%endif
+ push byte -1
+
+ push word 1
+ push word 0ffffh
+ push word -1
+
+ push dword 1
+ push dword 0ffffffffh
+ push dword -1
+
+ add eax,0FFFFh
+ add eax,0FFFFFFFFh
+ add eax,-1
+
+ add ecx,0FFFFh
+ add ecx,0FFFFFFFFh
+ add ecx,-1
+
+ bits 64
+ mov eax,7fffffffh
+ mov eax,80000000h
+ mov rax,7fffffffh
+ mov rax,80000000h
+%if WARN
+ mov rax,dword 80000000h
+%endif
+ add rcx,0FFFFh
+%if WARN
+ add rcx,0FFFFFFFFh
+%endif
+ add rcx,-1
+
+ add ecx,0FFFFh
+ add ecx,0FFFFFFFFh
+ add ecx,-1
+
+ push byte 1
+%if WARN
+ push byte 0ffffffffh
+%endif
+ push byte -1
diff --git a/test/imul.asm b/test/imul.asm
new file mode 100644
index 00000000..b1777120
--- /dev/null
+++ b/test/imul.asm
@@ -0,0 +1,90 @@
+;Testname=nowarn; Arguments=-fbin -oimul.bin; Files=stdout stderr imul.bin
+;Testname=warn; Arguments=-DWARN -fbin -oimul.bin; Files=stdout stderr imul.bin
+
+%macro test 1-2 5
+ bits %1
+
+%undef MEM
+%if %1 == 16
+ %define MEM [di]
+%elif %1 == 32
+ %define MEM [edi]
+%elif %1 == 64
+ %define MEM [rdi]
+%endif
+
+ imul al
+ imul byte MEM
+ imul ax
+ imul word MEM
+ imul eax
+ imul dword MEM
+%if %1 == 64
+ imul rdx
+ imul qword MEM
+%endif
+
+ imul ax,cx
+ imul ax,MEM
+ imul ax,word MEM
+ imul eax,ecx
+ imul eax,MEM
+ imul eax,dword MEM
+%if %1 == 64
+ imul rax,rcx
+ imul rax,MEM
+ imul rax,qword MEM
+%endif
+
+ imul ax,cx,%2
+ imul ax,cx,byte %2
+ imul ax,MEM,%2
+ imul ax,word MEM,%2
+ imul eax,ecx,%2
+ imul eax,ecx,byte %2
+ imul eax,MEM,%2
+ imul eax,dword MEM,%2
+%if %1 == 64
+ imul rax,rcx,%2
+ imul rax,rcx,byte %2
+ imul rax,MEM,%2
+ imul rax,qword MEM,%2
+%endif
+
+ imul ax,%2
+ imul ax,byte %2
+ imul eax,%2
+ imul eax,byte %2
+%if %1 == 64
+ imul rax,%2
+ imul rax,byte %2
+%endif
+
+ imul ax,cx,0x1234
+ imul ax,MEM,0x1234
+ imul ax,word MEM,0x1234
+ imul eax,ecx,0x12345678
+ imul eax,MEM,0x12345678
+ imul eax,dword MEM,0x12345678
+%if %1 == 64
+ imul rax,rcx,0x12345678
+ imul rax,MEM,0x12345678
+ imul rax,qword MEM,0x12345678
+%endif
+
+ imul ax,0x1234
+ imul eax,0x12345678
+%if %1 == 64
+ imul rax,0x12345678
+%endif
+%endmacro
+
+ test 16
+ test 32
+ test 64
+
+%ifdef WARN
+ test 16,0x999
+ test 32,0x999999
+ test 64,0x999999999
+%endif
diff --git a/test/optimization.asm b/test/optimization.asm
new file mode 100644
index 00000000..d78209d9
--- /dev/null
+++ b/test/optimization.asm
@@ -0,0 +1,104 @@
+;Testname=O0; Arguments=-O0 -fbin -ooptimization.bin; Files=stdout stderr optimization.bin
+;Testname=O1; Arguments=-O1 -fbin -ooptimization.bin; Files=stdout stderr optimization.bin
+;Testname=Ox; Arguments=-Ox -fbin -ooptimization.bin; Files=stdout stderr optimization.bin
+
+BITS 32
+
+; Simple
+jmp foo
+times 124 nop
+foo:
+
+; Must start short to converge optimally
+jmp car
+times 127 nop
+car:
+
+; Always near
+jmp cdr
+times 128 nop
+cdr:
+
+
+; Simple
+add eax, quux2 - quux1
+quux1:
+times 127 nop
+quux2:
+
+; Must start short
+corge1:
+add eax, corge2 - corge1
+times 127 - 3 nop
+corge2:
+
+
+; Simple
+lea eax, [bolug2-bolug1]
+bolug1:
+times 127 nop
+bolug2:
+
+; Must start short
+calog1:
+lea eax, [calog2-calog1]
+times 127 - 3 nop
+calog2:
+
+
+; Simple
+lea eax, [eax+dolug2-dolug1]
+dolug1:
+times 127 nop
+dolug2:
+
+; Must start short
+ealog1:
+lea eax, [eax+ealog2-ealog1]
+times 127 - 3 nop
+ealog2:
+
+; Must stay long!
+lea eax, [eax+folug2-folug1]
+folug1:
+times 128 nop
+folug2:
+
+; Must stay long!
+galog1:
+lea eax, [eax+galog2-galog1]
+times 128 - 3 nop
+galog2:
+
+; Sbyte tests...
+onetwentysix equ 126
+onetwentynine equ 129
+
+add eax,onetwentyseven ; sbyte (forward)
+add eax,onetwentyeight ; not sbyte (forward)
+add eax,onetwentyseven ; sbyte (forward)
+add eax,onetwentysix ; sbyte (backward)
+add eax,onetwentynine ; not sbyte (backward)
+add ecx,onetwentyseven ; sbyte (forward)
+add ecx,onetwentyeight ; not sbyte (forward)
+add ecx,onetwentyseven ; sbyte (forward)
+add ecx,onetwentysix ; sbyte (backward)
+add ecx,onetwentynine ; not sbyte (backward)
+
+onetwentyseven equ 127
+onetwentyeight equ 128
+
+; Simple
+add eax, holug2-holug1
+holug1:
+times 127 nop
+holug2:
+
+; Must start short
+ialog1:
+add eax, ialog2-ialog1
+times 127 - 3 nop
+ialog2:
+
+; Do not confuse forward references and segmentless addresses!
+jmp 12345
diff --git a/test/pinsr16.asm b/test/pinsr16.asm
new file mode 100644
index 00000000..f971598c
--- /dev/null
+++ b/test/pinsr16.asm
@@ -0,0 +1,52 @@
+ bits 16
+
+ pinsrw mm0,eax,0
+ pinsrw mm1,si,0
+ pinsrw mm2,[bx],0
+ pinsrw mm3,word [bx],0
+
+ pinsrb xmm0,eax,0
+ pinsrb xmm1,sil,0
+; pinsrb xmm1,bh,0
+ pinsrb xmm2,[bx],0
+ pinsrb xmm3,byte [bx],0
+
+ pinsrw xmm0,eax,0
+ pinsrw xmm1,si,0
+ pinsrw xmm2,[bx],0
+ pinsrw xmm3,word [bx],0
+
+ pinsrd xmm0,eax,0
+ pinsrd xmm1,esi,0
+ pinsrd xmm2,[bx],0
+ pinsrd xmm3,dword [bx],0
+
+ vpinsrb xmm0,eax,0
+ vpinsrb xmm1,bl,0
+ vpinsrb xmm2,[bx],0
+ vpinsrb xmm3,byte [bx],0
+
+ vpinsrw xmm0,eax,0
+ vpinsrw xmm1,si,0
+ vpinsrw xmm2,[bx],0
+ vpinsrw xmm3,word [bx],0
+
+ vpinsrd xmm0,eax,0
+ vpinsrd xmm1,esi,0
+ vpinsrd xmm2,[bx],0
+ vpinsrd xmm3,dword [bx],0
+
+ vpinsrb xmm4,xmm0,eax,0
+ vpinsrb xmm5,xmm1,bl,0
+ vpinsrb xmm6,xmm2,[bx],0
+ vpinsrb xmm7,xmm3,byte [bx],0
+
+ vpinsrw xmm4,xmm0,eax,0
+ vpinsrw xmm5,xmm1,si,0
+ vpinsrw xmm6,xmm2,[bx],0
+ vpinsrw xmm7,xmm3,word [bx],0
+
+ vpinsrd xmm4,xmm0,eax,0
+ vpinsrd xmm5,xmm1,esi,0
+ vpinsrd xmm6,xmm2,[bx],0
+ vpinsrd xmm7,xmm3,dword [bx],0
diff --git a/test/pinsr32.asm b/test/pinsr32.asm
new file mode 100644
index 00000000..834d1866
--- /dev/null
+++ b/test/pinsr32.asm
@@ -0,0 +1,52 @@
+ bits 32
+
+ pinsrw mm0,eax,0
+ pinsrw mm1,si,0
+ pinsrw mm2,[ecx],0
+ pinsrw mm3,word [ecx],0
+
+ pinsrb xmm0,eax,0
+ pinsrb xmm1,sil,0
+; pinsrb xmm1,bh,0
+ pinsrb xmm2,[ecx],0
+ pinsrb xmm3,byte [ecx],0
+
+ pinsrw xmm0,eax,0
+ pinsrw xmm1,si,0
+ pinsrw xmm2,[ecx],0
+ pinsrw xmm3,word [ecx],0
+
+ pinsrd xmm0,eax,0
+ pinsrd xmm1,esi,0
+ pinsrd xmm2,[ecx],0
+ pinsrd xmm3,dword [ecx],0
+
+ vpinsrb xmm0,eax,0
+ vpinsrb xmm1,bl,0
+ vpinsrb xmm2,[ecx],0
+ vpinsrb xmm3,byte [ecx],0
+
+ vpinsrw xmm0,eax,0
+ vpinsrw xmm1,si,0
+ vpinsrw xmm2,[ecx],0
+ vpinsrw xmm3,word [ecx],0
+
+ vpinsrd xmm0,eax,0
+ vpinsrd xmm1,esi,0
+ vpinsrd xmm2,[ecx],0
+ vpinsrd xmm3,dword [ecx],0
+
+ vpinsrb xmm4,xmm0,eax,0
+ vpinsrb xmm5,xmm1,bl,0
+ vpinsrb xmm6,xmm2,[ecx],0
+ vpinsrb xmm7,xmm3,byte [ecx],0
+
+ vpinsrw xmm4,xmm0,eax,0
+ vpinsrw xmm5,xmm1,si,0
+ vpinsrw xmm6,xmm2,[ecx],0
+ vpinsrw xmm7,xmm3,word [ecx],0
+
+ vpinsrd xmm4,xmm0,eax,0
+ vpinsrd xmm5,xmm1,esi,0
+ vpinsrd xmm6,xmm2,[ecx],0
+ vpinsrd xmm7,xmm3,dword [ecx],0
diff --git a/test/pinsr64.asm b/test/pinsr64.asm
new file mode 100644
index 00000000..bf837e9e
--- /dev/null
+++ b/test/pinsr64.asm
@@ -0,0 +1,68 @@
+ bits 64
+
+ pinsrw mm0,eax,0
+ pinsrw mm1,si,0
+ pinsrw mm2,[rcx],0
+ pinsrw mm3,word [rcx],0
+
+ pinsrb xmm0,eax,0
+ pinsrb xmm1,sil,0
+; pinsrb xmm1,bh,0
+ pinsrb xmm2,[rcx],0
+ pinsrb xmm3,byte [rcx],0
+
+ pinsrw xmm0,eax,0
+ pinsrw xmm1,si,0
+ pinsrw xmm2,[rcx],0
+ pinsrw xmm3,word [rcx],0
+
+ pinsrd xmm0,eax,0
+ pinsrd xmm1,esi,0
+ pinsrd xmm2,[rcx],0
+ pinsrd xmm3,dword [rcx],0
+
+ pinsrq xmm0,rax,0
+ pinsrq xmm1,rsi,0
+ pinsrq xmm2,[rcx],0
+ pinsrq xmm3,qword [rcx],0
+
+ vpinsrb xmm0,eax,0
+ vpinsrb xmm1,sil,0
+ vpinsrb xmm2,[rcx],0
+ vpinsrb xmm3,byte [rcx],0
+
+ vpinsrw xmm0,eax,0
+ vpinsrw xmm1,si,0
+ vpinsrw xmm2,[rcx],0
+ vpinsrw xmm3,word [rcx],0
+
+ vpinsrd xmm0,eax,0
+ vpinsrd xmm1,esi,0
+ vpinsrd xmm2,[rcx],0
+ vpinsrd xmm3,dword [rcx],0
+
+ vpinsrq xmm0,rax,0
+ vpinsrq xmm1,rsi,0
+ vpinsrq xmm2,[rcx],0
+ vpinsrq xmm3,qword [rcx],0
+
+ vpinsrb xmm4,xmm0,eax,0
+ vpinsrb xmm5,xmm1,sil,0
+ vpinsrb xmm6,xmm2,[rcx],0
+ vpinsrb xmm7,xmm3,byte [rcx],0
+
+ vpinsrw xmm4,xmm0,eax,0
+ vpinsrw xmm5,xmm1,si,0
+ vpinsrw xmm6,xmm2,[rcx],0
+ vpinsrw xmm7,xmm3,word [rcx],0
+
+ vpinsrd xmm4,xmm0,eax,0
+ vpinsrd xmm5,xmm1,esi,0
+ vpinsrd xmm6,xmm2,[rcx],0
+ vpinsrd xmm7,xmm3,dword [rcx],0
+
+ vpinsrq xmm4,xmm0,rax,0
+ vpinsrq xmm5,xmm1,rsi,0
+ vpinsrq xmm6,xmm2,[rcx],0
+ vpinsrq xmm7,xmm3,qword [rdx],0
+ \ No newline at end of file
diff --git a/test/popcnt.asm b/test/popcnt.asm
new file mode 100644
index 00000000..00096198
--- /dev/null
+++ b/test/popcnt.asm
@@ -0,0 +1,32 @@
+;Testname=test; Arguments=-fbin -opopcnt.bin; Files=stdout stderr popcnt.bin
+
+ bits 16
+
+ popcnt ax,cx
+ popcnt ax,[si]
+ popcnt ax,word [si]
+ popcnt eax,ecx
+ popcnt eax,[si]
+ popcnt eax,dword [si]
+
+ bits 32
+
+ popcnt ax,cx
+ popcnt ax,[esi]
+ popcnt ax,word [esi]
+ popcnt eax,ecx
+ popcnt eax,[esi]
+ popcnt eax,dword [esi]
+
+ bits 64
+
+ popcnt ax,cx
+ popcnt ax,[rsi]
+ popcnt ax,word [rsi]
+ popcnt eax,ecx
+ popcnt eax,[rsi]
+ popcnt eax,dword [rsi]
+ popcnt rax,rcx
+ popcnt rax,[rsi]
+ popcnt rax,qword [rsi]
+ \ No newline at end of file
diff --git a/test/ppindirect.asm b/test/ppindirect.asm
new file mode 100644
index 00000000..0a30d075
--- /dev/null
+++ b/test/ppindirect.asm
@@ -0,0 +1,42 @@
+;Testname=test; Arguments=-E -o ppindirect.out; Files=ppindirect.out
+
+; Fun tests of the preprocessor indirection mode...
+
+%assign foo1 11
+%assign foo11 1111
+%assign foo2 22
+%assign foo22 2222
+%assign foo3 33
+%assign foo33 3333
+%assign n 2
+foo%[foo%[n]]*100
+foo%[n]*100
+%assign foo%[foo%[n]] foo%[foo%[n]]*100
+;%assign foo%[n] foo%[n]*100
+
+ foo1
+ foo2
+ foo3
+ foo11
+ foo22
+ foo33
+
+%define foo33bar 999999
+ %[foo%[foo3]bar]
+
+%assign bctr 0
+%macro bluttan 0
+%assign bctr bctr+1
+%assign bluttan%[bctr] bctr
+%defstr bstr bluttan%[bctr]
+ bluttan%[bctr]
+ bstr
+%endmacro
+
+%rep 20
+ bluttan
+%endrep
+%rep 20
+ bluttan%[bctr]
+%assign bctr bctr-1
+%endrep
diff --git a/test/pushseg.asm b/test/pushseg.asm
new file mode 100644
index 00000000..7bd7c955
--- /dev/null
+++ b/test/pushseg.asm
@@ -0,0 +1,17 @@
+;Testname=test; Arguments=-fbin -opushseg.bin; Files=stdout stderr pushseg.bin
+
+ bits 16
+
+ push cs
+ push ds
+ push es
+ push ss
+ push fs
+ push gs
+
+ pop gs
+ pop fs
+ pop ss
+ pop es
+ pop ds
+ pop cs ; 8086 only, does not disassemble
diff --git a/test/riprel2.asm b/test/riprel2.asm
new file mode 100644
index 00000000..2d13d3e4
--- /dev/null
+++ b/test/riprel2.asm
@@ -0,0 +1,11 @@
+;Testname=unoptimized; Arguments=-fbin -oriprel2.bin -O0; Files=stdout stderr riprel.bin
+;Testname=optimized; Arguments=-fbin -oriprel2.bin -Ox; Files=stdout stderr riprel.bin
+
+ bits 64
+
+ default rel
+ mov dword [foo],12345678h
+ mov qword [foo],12345678h
+ mov [foo],rax
+ mov dword [foo],12345678h
+foo:
diff --git a/test/smartalign16.asm b/test/smartalign16.asm
new file mode 100644
index 00000000..42915de6
--- /dev/null
+++ b/test/smartalign16.asm
@@ -0,0 +1,36 @@
+;Testname=test; Arguments=-fbin -osmartalign16.bin; Files=stdout stderr smartalign16.bin
+
+%use smartalign
+
+ bits 16
+
+ alignmode nop, 32
+ add ax,ax
+ align 32
+
+ alignmode generic, 32
+ add ax,ax
+ align 32
+
+ alignmode k7, 32
+ add ax,ax
+ align 32
+
+ alignmode k8, 32
+ add ax,ax
+ align 32
+
+ alignmode p6, 32
+ add ax,ax
+ align 32
+
+ add ecx,ecx
+ align 32
+ add edx,edx
+ align 128
+ add ebx,ebx
+ align 256
+ add esi,esi
+ align 512
+
+ add edi,edi
diff --git a/test/smartalign32.asm b/test/smartalign32.asm
new file mode 100644
index 00000000..64d65b0b
--- /dev/null
+++ b/test/smartalign32.asm
@@ -0,0 +1,36 @@
+;Testname=test; Arguments=-fbin -osmartalign32.bin; Files=stdout stderr smartalign32.bin
+
+%use smartalign
+
+ bits 32
+
+ alignmode nop, 32
+ add ax,ax
+ align 32
+
+ alignmode generic, 32
+ add ax,ax
+ align 32
+
+ alignmode k7, 32
+ add ax,ax
+ align 32
+
+ alignmode k8, 32
+ add ax,ax
+ align 32
+
+ alignmode p6, 32
+ add ax,ax
+ align 32
+
+ add ecx,ecx
+ align 32
+ add edx,edx
+ align 128
+ add ebx,ebx
+ align 256
+ add esi,esi
+ align 512
+
+ add edi,edi
diff --git a/test/smartalign64.asm b/test/smartalign64.asm
new file mode 100644
index 00000000..74454ca8
--- /dev/null
+++ b/test/smartalign64.asm
@@ -0,0 +1,36 @@
+;Testname=test; Arguments=-fbin -osmartalign64.bin; Files=stdout stderr smartalign64.bin
+
+%use smartalign
+
+ bits 64
+
+ alignmode nop, 32
+ add ax,ax
+ align 32
+
+ alignmode generic, 32
+ add ax,ax
+ align 32
+
+ alignmode k7, 32
+ add ax,ax
+ align 32
+
+ alignmode k8, 32
+ add ax,ax
+ align 32
+
+ alignmode p6, 32
+ add ax,ax
+ align 32
+
+ add ecx,ecx
+ align 32
+ add edx,edx
+ align 128
+ add ebx,ebx
+ align 256
+ add esi,esi
+ align 512
+
+ add edi,edi
diff --git a/test/struc.asm b/test/struc.asm
new file mode 100644
index 00000000..3c8c1b47
--- /dev/null
+++ b/test/struc.asm
@@ -0,0 +1,33 @@
+;Testname=test; Arguments=-fbin -ostruc.bin; Files=stdout stderr struc.bin
+
+bits 32
+
+; Simple struc example
+struc teststruc1
+ .long: resd 1
+ .word: resw 1
+ .byte: resb 1
+ .str: resb 32
+endstruc
+
+; Reference with offset
+mov [ebp - 40 + teststruc1.word], ax
+
+istruc teststruc1
+ at .word, db 5
+iend
+
+; Struc with base offset
+; should be the same as the previous stuc
+struc teststruc2, -40
+ .long: resd 1
+ .word: resw 1
+ .byte: resb 1
+ .str: resb 32
+endstruc
+
+mov [ebp + teststruc2.word], ax
+
+istruc teststruc2
+ at .word, db 5
+iend
diff --git a/test/weirdpaste.asm b/test/weirdpaste.asm
new file mode 100644
index 00000000..46bfa90a
--- /dev/null
+++ b/test/weirdpaste.asm
@@ -0,0 +1,29 @@
+;Testname=preproc; Arguments=-E; Files=stdout stderr
+;Testname=bin; Arguments=-fbin -oweirdpaste.bin; Files=stdout stderr weirdpaste.bin
+
+ %define foo xyzzy
+%define bar 1e+10
+
+%define xyzzy1e 15
+
+%macro dx 2
+%assign xx %1%2
+ dw xx
+%endmacro
+
+ dx foo, bar
+
+%macro df 2
+%assign xy __float32__(%1e+%2)
+ dd xy
+ dd %1e+%2
+%endmacro
+
+ df 1, 36
+ df 33, 20
+ df 0, 2
+ df 1.2, 5
+
+
+%define N 1e%++%+ 5
+ dd N, 1e+5
diff --git a/ver.c b/ver.c
new file mode 100644
index 00000000..a7c4608e
--- /dev/null
+++ b/ver.c
@@ -0,0 +1,51 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include "nasm.h"
+#include "version.h"
+
+/* This is printed when entering nasm -v */
+const char nasm_version[] = NASM_VER;
+const char nasm_date[] = __DATE__;
+const char nasm_compile_options[] = ""
+#ifdef DEBUG
+ " with -DDEBUG"
+#endif
+ ;
+
+/* These are used by some backends. */
+const char nasm_comment[] =
+ "The Netwide Assembler " NASM_VER;
+
+const char nasm_signature[] =
+ "NASM " NASM_VER;