summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rw-r--r--Doxyfile752
-rw-r--r--assemble.c6
-rw-r--r--disasm.c12
-rw-r--r--doc/nasmdoc.src11
-rw-r--r--insns.dat139
-rw-r--r--macros.c16
-rw-r--r--macros.pl3
-rw-r--r--misc/exasm.zipbin6058 -> 491 bytes
-rw-r--r--nasm.c10
-rw-r--r--nasm.h9
-rw-r--r--ndisasm.c16
-rw-r--r--ndisasm.doc2
-rw-r--r--parser.c9
-rw-r--r--rdoff/Makefile.in170
-rw-r--r--rdoff/ldrdf.c1378
-rw-r--r--rdoff/rdflib.c1
-rw-r--r--rdoff/rdfload.c1
-rw-r--r--rdoff/rdoff.h305
-rw-r--r--test/bintest.asm90
20 files changed, 1161 insertions, 1771 deletions
diff --git a/AUTHORS b/AUTHORS
index fb10957..b6764d7 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -40,7 +40,7 @@ D: New Athlon instructions
D: Makefile.vc fix
N: John Coffman
-E: johninsd@users.sourceforge.net
+E: johninsd@san.rr.com
D: added Jcc optimizations; CPU level checks
D: bug fixes, compilation fixes
diff --git a/Doxyfile b/Doxyfile
new file mode 100644
index 0000000..1bb1cc3
--- /dev/null
+++ b/Doxyfile
@@ -0,0 +1,752 @@
+# Doxyfile 1.2.5
+
+# This file describes the settings to be used by doxygen for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = "NASM - the Netwide Assembler"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 0.98
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = doxy
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese,
+# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian,
+# Polish, Portuguese and Slovene.
+
+OUTPUT_LANGUAGE = English
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these class will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH =
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a class diagram (in Html and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off.
+
+CLASS_DIAGRAMS = YES
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower case letters. If set to YES upper case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# users are adviced to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+
+INHERIT_DOCS = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# The ENABLE_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consist of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = .
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+FILE_PATTERNS = *.c *.h
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+
+INPUT_FILTER =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse.
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript and frames is required (for instance Netscape 4.0+
+# or Internet explorer 4.0+).
+
+GENERATE_TREEVIEW = YES
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimised for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = YES
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using a WORD or other.
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assigments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tagfiles.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to
+# YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other
+# documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to
+# YES then doxygen will generate a graph for each documented header file showing
+# the documented files that directly or indirectly include this file
+
+INCLUDED_BY_GRAPH = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
+
+# The CGI_NAME tag should be the name of the CGI script that
+# starts the search engine (doxysearch) with the correct parameters.
+# A script with this name will be generated by doxygen.
+
+CGI_NAME = search.cgi
+
+# The CGI_URL tag should be the absolute URL to the directory where the
+# cgi binaries are located. See the documentation of your http daemon for
+# details.
+
+CGI_URL =
+
+# The DOC_URL tag should be the absolute URL to the directory where the
+# documentation is located. If left blank the absolute path to the
+# documentation, with file:// prepended to it, will be used.
+
+DOC_URL =
+
+# The DOC_ABSPATH tag should be the absolute path to the directory where the
+# documentation is located. If left blank the directory on the local machine
+# will be used.
+
+DOC_ABSPATH =
+
+# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
+# is installed.
+
+BIN_ABSPATH = /usr/local/bin/
+
+# The EXT_DOC_PATHS tag can be used to specify one or more paths to
+# documentation generated for other projects. This allows doxysearch to search
+# the documentation for these projects as well.
+
+EXT_DOC_PATHS =
diff --git a/assemble.c b/assemble.c
index 8058979..39ffd46 100644
--- a/assemble.c
+++ b/assemble.c
@@ -152,7 +152,7 @@ static int jmp_match (long segment, long offset, int bits,
if (c != 0370) return 0;
- if (ins->oprs[0].opflags & OPFLAG_FORWARD) return (! pass0); /*1;*/ /* match a forward reference */
+ if (ins->oprs[0].opflags & OPFLAG_FORWARD) return (!pass0); /* match a forward reference */
isize = calcsize (segment, offset, bits, ins, code);
if (ins->oprs[0].segment != segment) return 0;
@@ -546,7 +546,7 @@ static int is_sbyte (insn *ins, int op, int size)
int ret;
ret = !(ins->forw_ref && ins->oprs[op].opflags ) && /* dead in the water on forward reference or External */
- !(ins->oprs[op].type & (BITS16|BITS32)) && /* John Coffman's 3/24/01 patch - fbk - 10/16/01 */
+ (optimizing || !(ins->oprs[op].type & (BITS16|BITS32))) &&
ins->oprs[op].wrt==NO_SEG && ins->oprs[op].segment==NO_SEG;
v = ins->oprs[op].offset;
@@ -791,7 +791,7 @@ static void gencode (long segment, long offset, int bits,
data = ins->oprs[c-034].offset;
size = ((ins->oprs[c-034].addr_size ?
ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4);
- if (size==16 && (data < -65536L || data > 65535L))
+ if (size==2 && (data < -65536L || data > 65535L))
errfunc (ERR_WARNING, "word value exceeds bounds");
out (offset, segment, &data, OUT_ADDRESS+size,
ins->oprs[c-034].segment, ins->oprs[c-034].wrt);
diff --git a/disasm.c b/disasm.c
index e7e634e..9184686 100644
--- a/disasm.c
+++ b/disasm.c
@@ -377,13 +377,23 @@ static int matches (struct itemplate *t, unsigned char *data, int asize,
ins->oprs[c-070].offset |= (((long) *data++) << 24);
ins->oprs[c-070].segment |= SEG_32BIT | SEG_RELATIVE;
}
- if (c >= 0100 && c <= 0177) {
+ if (c >= 0100 && c < 0130) {
int modrm = *data++;
ins->oprs[c & 07].basereg = (modrm >> 3) & 07;
ins->oprs[c & 07].segment |= SEG_RMREG;
data = do_ea (data, modrm, asize, segsize,
&ins->oprs[(c >> 3) & 07]);
}
+ if (c >= 0130 && c <= 0132) {
+ ins->oprs[c-0130].offset = *data++;
+ ins->oprs[c-0130].offset |= (*data++ << 8);
+ }
+ if (c >= 0140 && c <= 0142) {
+ ins->oprs[c-0140].offset = *data++;
+ ins->oprs[c-0140].offset |= (*data++ << 8);
+ ins->oprs[c-0140].offset |= (((long) *data++) << 16);
+ ins->oprs[c-0140].offset |= (((long) *data++) << 24);
+ }
if (c >= 0200 && c <= 0277) {
int modrm = *data++;
if (((modrm >> 3) & 07) != (c & 07))
diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src
index f91861b..66825ed 100644
--- a/doc/nasmdoc.src
+++ b/doc/nasmdoc.src
@@ -5810,7 +5810,8 @@ form of the instruction.
\c ADDPS xmmreg,xmmreg ; 0f 58 /r [KATMAI,SSE]
\c{ADDPS} performs addition on each of four packed SP FP
-number items dst(0-31):=dst(0-31)+src(0-31), ..(63-32), etc.
+number items dst(0-31):=dst(0-31)+src(0-31)
+, ..(63-32), etc.
\H{insADDSS} \i\c{ADDSS}: Scalar Single FP ADD
@@ -6219,13 +6220,17 @@ first unequal or equal byte is found.
EQ, LT, LE, UNORD, NEQ, NLT, NLE, ORD
-\H{insCMPUNORDPS} \i\c{CMPUNORDPS}: Packed Single FP Compare (CMPPS)
+\H{insCMPUNORDPS} \i\c{CMPUNORDPS}: Packed Single FP Compare
+
+ (CMPPS)
\c CMPUNORDPS xmmreg,memory ; ?? [KATMAI,SSE]
\c CMPUNORDPS xmmreg,xmmreg ; ?? [KATMAI,SSE]
-\H{insCMPUNORDSS} \i\c{CMPUNORDSS}: Scalar Single FP Compare (CMPSS)
+\H{insCMPUNORDSS} \i\c{CMPUNORDSS}: Scalar Single FP Compare
+
+ (CMPSS)
\c CMPUNORDSS xmmreg,memory ; ?? [KATMAI,SSE]
\c CMPUNORDSS xmmreg,xmmreg ; ?? [KATMAI,SSE]
diff --git a/insns.dat b/insns.dat
index e167a77..c34fa0e 100644
--- a/insns.dat
+++ b/insns.dat
@@ -37,14 +37,15 @@ ADC rm16,imm8 \320\300\1\x83\202\15 8086
ADC rm32,imm8 \321\300\1\x83\202\15 386
ADC reg_al,imm \1\x14\21 8086,SM
ADC reg_ax,imm \320\1\x15\31 8086,SM
-ADC reg_eax,sbyte \321\1\x83\202\15 386,ND
-ADC reg_eax,imm \321\1\x15\41 386,SM
+ADC reg_eax,sbyte \321\1\x83\202\15 386,SM,ND
+ADC reg_eax,sbig \321\1\x15\41 386,SM,ND
+ADC reg_eax,imm32 \321\1\x15\41 386
ADC rm8,imm \300\1\x80\202\21 8086,SM
-ADC rm16,imm \320\300\134\1\x81\202\131 8086,SM,ND
-ADC rm32,imm \321\300\144\1\x81\202\141 386,SM,ND
+ADC rm16,imm \320\300\134\1\x81\202\131 8086,SM
+ADC rm32,imm \321\300\144\1\x81\202\141 386,SM
ADC mem,imm8 \300\1\x80\202\21 8086,SM
-ADC mem,imm16 \320\300\134\1\x81\202\131 8086,SM,ND
-ADC mem,imm32 \321\300\144\1\x81\202\141 386,SM,ND
+ADC mem,imm16 \320\300\134\1\x81\202\131 8086,SM
+ADC mem,imm32 \321\300\144\1\x81\202\141 386,SM
ADD mem,reg8 \300\17\101 8086,SM
ADD reg8,reg8 \300\17\101 8086
ADD mem,reg16 \320\300\1\x01\101 8086,SM
@@ -61,14 +62,15 @@ ADD rm16,imm8 \320\300\1\x83\200\15 8086
ADD rm32,imm8 \321\300\1\x83\200\15 386
ADD reg_al,imm \1\x04\21 8086,SM
ADD reg_ax,imm \320\1\x05\31 8086,SM
-ADD reg_eax,sbyte \321\1\x83\200\15 386,ND
-ADD reg_eax,imm \321\1\x05\41 386,SM
+ADD reg_eax,sbyte \321\1\x83\200\15 386,SM,ND
+ADD reg_eax,sbig \321\1\x05\41 386,SM,ND
+ADD reg_eax,imm32 \321\1\x05\41 386
ADD rm8,imm \300\1\x80\200\21 8086,SM
-ADD rm16,imm \320\300\134\1\x81\200\131 8086,SM,ND
-ADD rm32,imm \321\300\144\1\x81\200\141 386,SM,ND
+ADD rm16,imm \320\300\134\1\x81\200\131 8086,SM
+ADD rm32,imm \321\300\144\1\x81\200\141 386,SM
ADD mem,imm8 \300\1\x80\200\21 8086,SM
-ADD mem,imm16 \320\300\134\1\x81\200\131 8086,SM,ND
-ADD mem,imm32 \321\300\144\1\x81\200\141 386,SM,ND
+ADD mem,imm16 \320\300\134\1\x81\200\131 8086,SM
+ADD mem,imm32 \321\300\144\1\x81\200\141 386,SM
AND mem,reg8 \300\1\x20\101 8086,SM
AND reg8,reg8 \300\1\x20\101 8086
AND mem,reg16 \320\300\1\x21\101 8086,SM
@@ -85,14 +87,15 @@ AND rm16,imm8 \320\300\1\x83\204\15 8086
AND rm32,imm8 \321\300\1\x83\204\15 386
AND reg_al,imm \1\x24\21 8086,SM
AND reg_ax,imm \320\1\x25\31 8086,SM
-AND reg_eax,sbyte \321\1\x83\204\15 386,ND
-AND reg_eax,imm \321\1\x25\41 386,SM
+AND reg_eax,sbyte \321\1\x83\204\15 386,SM,ND
+AND reg_eax,sbig \321\1\x25\41 386,SM,ND
+AND reg_eax,imm32 \321\1\x25\41 386
AND rm8,imm \300\1\x80\204\21 8086,SM
-AND rm16,imm \320\300\134\1\x81\204\131 8086,SM,ND
-AND rm32,imm \321\300\144\1\x81\204\141 386,SM,ND
+AND rm16,imm \320\300\134\1\x81\204\131 8086,SM
+AND rm32,imm \321\300\144\1\x81\204\141 386,SM
AND mem,imm8 \300\1\x80\204\21 8086,SM
-AND mem,imm16 \320\300\134\1\x81\204\131 8086,SM,ND
-AND mem,imm32 \321\300\144\1\x81\204\141 386,SM,ND
+AND mem,imm16 \320\300\134\1\x81\204\131 8086,SM
+AND mem,imm32 \321\300\144\1\x81\204\141 386,SM
ARPL mem,reg16 \300\1\x63\101 286,PROT,SM
ARPL reg16,reg16 \300\1\x63\101 286,PROT
BOUND reg16,mem \320\301\1\x62\110 186
@@ -178,14 +181,15 @@ CMP rm16,imm8 \320\300\1\x83\207\15 8086
CMP rm32,imm8 \321\300\1\x83\207\15 386
CMP reg_al,imm \1\x3C\21 8086,SM
CMP reg_ax,imm \320\1\x3D\31 8086,SM
-CMP reg_eax,sbyte \321\1\x83\207\15 386,ND
-CMP reg_eax,imm \321\1\x3D\41 386,SM
+CMP reg_eax,sbyte \321\1\x83\207\15 386,SM,ND
+CMP reg_eax,sbig \321\1\x3D\41 386,SM,ND
+CMP reg_eax,imm32 \321\1\x3D\41 386
CMP rm8,imm \300\1\x80\207\21 8086,SM
-CMP rm16,imm \320\300\134\1\x81\207\131 8086,SM,ND
-CMP rm32,imm \321\300\144\1\x81\207\141 386,SM,ND
+CMP rm16,imm \320\300\134\1\x81\207\131 8086,SM
+CMP rm32,imm \321\300\144\1\x81\207\141 386,SM
CMP mem,imm8 \300\1\x80\207\21 8086,SM
-CMP mem,imm16 \320\300\134\1\x81\207\131 8086,SM,ND
-CMP mem,imm32 \321\300\144\1\x81\207\141 386,SM,ND
+CMP mem,imm16 \320\300\134\1\x81\207\131 8086,SM
+CMP mem,imm32 \321\300\144\1\x81\207\141 386,SM
CMPSB void \332\1\xA6 8086
CMPSD void \332\321\1\xA7 386
CMPSW void \332\320\1\xA7 8086
@@ -423,17 +427,29 @@ IMUL reg16,reg16 \320\2\x0F\xAF\110 386
IMUL reg32,mem \321\301\2\x0F\xAF\110 386,SM
IMUL reg32,reg32 \321\2\x0F\xAF\110 386
IMUL reg16,mem,imm8 \320\301\1\x6B\110\16 186,SM
-IMUL reg16,reg16,imm8 \320\301\1\x6B\110\16 186
-IMUL reg16,mem,imm \320\301\135\1\x69\110\132 186,SM
-IMUL reg16,reg16,imm \320\135\1\x69\110\132 186,SM
+IMUL reg16,mem,sbyte \320\301\1\x6B\110\16 186,SM,ND
+IMUL reg16,mem,imm16 \320\301\1\x69\110\32 186,SM
+IMUL reg16,mem,imm \320\301\135\1\x69\110\132 186,SM,ND
+IMUL reg16,reg16,imm8 \320\1\x6B\110\16 186
+IMUL reg16,reg16,sbyte \320\1\x6B\110\16 186,SM,ND
+IMUL reg16,reg16,imm16 \320\1\x69\110\32 186
+IMUL reg16,reg16,imm \320\135\1\x69\110\132 186,SM,ND
IMUL reg32,mem,imm8 \321\301\1\x6B\110\16 386,SM
+IMUL reg32,mem,sbyte \321\301\1\x6B\110\16 386,SM,ND
+IMUL reg32,mem,imm32 \321\301\1\x69\110\42 386,SM
+IMUL reg32,mem,imm \321\301\145\1\x69\110\142 386,SM,ND
IMUL reg32,reg32,imm8 \321\1\x6B\110\16 386
-IMUL reg32,mem,imm \321\301\145\1\x69\110\142 386,SM
-IMUL reg32,reg32,imm \321\145\1\x69\110\142 386,SM
+IMUL reg32,reg32,sbyte \321\1\x6B\110\16 386,SM,ND
+IMUL reg32,reg32,imm32 \321\1\x69\110\42 386
+IMUL reg32,reg32,imm \321\145\1\x69\110\142 386,SM,ND
IMUL reg16,imm8 \320\1\x6B\100\15 186
-IMUL reg16,imm \320\134\1\x69\100\131 186,SM
+IMUL reg16,sbyte \320\1\x6B\100\15 186,SM,ND
+IMUL reg16,imm16 \320\1\x69\100\31 186
+IMUL reg16,imm \320\134\1\x69\100\131 186,SM,ND
IMUL reg32,imm8 \321\1\x6B\100\15 386
-IMUL reg32,imm \321\144\1\x69\100\141 386,SM
+IMUL reg32,sbyte \321\1\x6B\100\15 386,SM,ND
+IMUL reg32,imm32 \321\1\x69\100\41 386
+IMUL reg32,imm \321\144\1\x69\100\141 386,SM,ND
IN reg_al,imm \1\xE4\25 8086,SB
IN reg_ax,imm \320\1\xE5\25 8086,SB
IN reg_eax,imm \321\1\xE5\25 386,SB
@@ -542,9 +558,9 @@ LSS reg32,mem \321\301\2\x0F\xB2\110 386
LTR mem \300\1\x0F\17\203 286,PROT,PRIV
LTR mem16 \300\1\x0F\17\203 286,PROT,PRIV
LTR reg16 \300\1\x0F\17\203 286,PROT,PRIV
-MOV mem,reg_cs \300\1\x8C\201 8086,SM
-MOV mem,reg_dess \300\1\x8C\101 8086,SM
-MOV mem,reg_fsgs \300\1\x8C\101 386,SM
+MOV mem,reg_cs \300\1\x8C\201 8086,SM
+MOV mem,reg_dess \300\1\x8C\101 8086,SM
+MOV mem,reg_fsgs \300\1\x8C\101 386,SM
MOV reg16,reg_cs \320\300\1\x8C\201 8086
MOV reg16,reg_dess \320\300\1\x8C\101 8086
MOV reg16,reg_fsgs \320\300\1\x8C\101 386
@@ -637,14 +653,15 @@ OR rm16,imm8 \320\300\1\x83\201\15 8086
OR rm32,imm8 \321\300\1\x83\201\15 386
OR reg_al,imm \1\x0C\21 8086,SM
OR reg_ax,imm \320\1\x0D\31 8086,SM
-OR reg_eax,sbyte \321\1\x83\201\15 386,ND
-OR reg_eax,imm \321\1\x0D\41 386,SM
+OR reg_eax,sbyte \321\1\x83\201\15 386,SM,ND
+OR reg_eax,sbig \321\1\x0D\41 386,SM,ND
+OR reg_eax,imm32 \321\1\x0D\41 386
OR rm8,imm \300\1\x80\201\21 8086,SM
-OR rm16,imm \320\300\134\1\x81\201\131 8086,SM,ND
-OR rm32,imm \321\300\144\1\x81\201\141 386,SM,ND
+OR rm16,imm \320\300\134\1\x81\201\131 8086,SM
+OR rm32,imm \321\300\144\1\x81\201\141 386,SM
OR mem,imm8 \300\1\x80\201\21 8086,SM
-OR mem,imm16 \320\300\134\1\x81\201\131 8086,SM,ND
-OR mem,imm32 \321\300\144\1\x81\201\141 386,SM,ND
+OR mem,imm16 \320\300\134\1\x81\201\131 8086,SM
+OR mem,imm32 \321\300\144\1\x81\201\141 386,SM
OUT imm,reg_al \1\xE6\24 8086,SB
OUT imm,reg_ax \320\1\xE7\24 8086,SB
OUT imm,reg_eax \321\1\xE7\24 386,SB
@@ -826,9 +843,10 @@ PUSH rm32 \321\300\1\xFF\206 386
PUSH reg_fsgs \1\x0F\7 386
PUSH reg_sreg \6 8086
PUSH imm8 \1\x6A\14 186
-PUSH sbyte \1\x6A\14 186,ND
PUSH imm16 \320\133\1\x68\130 186
PUSH imm32 \321\143\1\x68\140 386
+PUSH sbyte \1\x6A\14 186,ND
+PUSH imm \1\x68\34 186,ND
PUSHA void \322\1\x60 186
PUSHAD void \321\1\x60 386
PUSHAW void \320\1\x60 186
@@ -928,14 +946,15 @@ SBB rm16,imm8 \320\300\1\x83\203\15 8086
SBB rm32,imm8 \321\300\1\x83\203\15 8086
SBB reg_al,imm \1\x1C\21 8086,SM
SBB reg_ax,imm \320\1\x1D\31 8086,SM
-SBB reg_eax,sbyte \321\1\x83\203\15 386,ND
-SBB reg_eax,imm \321\1\x1D\41 386,SM
+SBB reg_eax,sbyte \321\1\x83\203\15 386,SM,ND
+SBB reg_eax,sbig \321\1\x1D\41 386,SM,ND
+SBB reg_eax,imm32 \321\1\x1D\41 386
SBB rm8,imm \300\1\x80\203\21 8086,SM
-SBB rm16,imm \320\300\134\1\x81\203\131 8086,SM,ND
-SBB rm32,imm \321\300\144\1\x81\203\141 386,SM,ND
+SBB rm16,imm \320\300\134\1\x81\203\131 8086,SM
+SBB rm32,imm \321\300\144\1\x81\203\141 386,SM
SBB mem,imm8 \300\1\x80\203\21 8086,SM
-SBB mem,imm16 \320\300\134\1\x81\203\131 8086,SM,ND
-SBB mem,imm32 \321\300\144\1\x81\203\141 386,SM,ND
+SBB mem,imm16 \320\300\134\1\x81\203\131 8086,SM
+SBB mem,imm32 \321\300\144\1\x81\203\141 386,SM
SCASB void \332\1\xAE 8086
SCASD void \332\321\1\xAF 386
SCASW void \332\320\1\xAF 8086
@@ -1010,14 +1029,15 @@ SUB rm16,imm8 \320\300\1\x83\205\15 8086
SUB rm32,imm8 \321\300\1\x83\205\15 386
SUB reg_al,imm \1\x2C\21 8086,SM
SUB reg_ax,imm \320\1\x2D\31 8086,SM
-SUB reg_eax,sbyte \321\1\x83\205\15 386,ND
-SUB reg_eax,imm \321\1\x2D\41 386,SM
+SUB reg_eax,sbyte \321\1\x83\205\15 386,SM,ND
+SUB reg_eax,sbig \321\1\x2D\41 386,SM,ND
+SUB reg_eax,imm32 \321\1\x2D\41 386
SUB rm8,imm \300\1\x80\205\21 8086,SM
-SUB rm16,imm \320\300\134\1\x81\205\131 8086,SM,ND
-SUB rm32,imm \321\300\144\1\x81\205\141 386,SM,ND
+SUB rm16,imm \320\300\134\1\x81\205\131 8086,SM
+SUB rm32,imm \321\300\144\1\x81\205\141 386,SM
SUB mem,imm8 \300\1\x80\205\21 8086,SM
-SUB mem,imm16 \320\300\134\1\x81\205\131 8086,SM,ND
-SUB mem,imm32 \321\300\144\1\x81\205\141 386,SM,ND
+SUB mem,imm16 \320\300\134\1\x81\205\131 8086,SM
+SUB mem,imm32 \321\300\144\1\x81\205\141 386,SM
SVDC mem80,reg_sreg \300\2\x0F\x78\101 486,CYRIX,SMM
SVLDT mem80 \300\2\x0F\x7A\200 486,CYRIX,SMM
SVTS mem80 \300\2\x0F\x7C\200 486,CYRIX,SMM
@@ -1112,14 +1132,15 @@ XOR rm16,imm8 \320\300\1\x83\206\15 8086
XOR rm32,imm8 \321\300\1\x83\206\15 386
XOR reg_al,imm \1\x34\21 8086,SM
XOR reg_ax,imm \320\1\x35\31 8086,SM
-XOR reg_eax,sbyte \321\1\x83\206\15 386,ND
-XOR reg_eax,imm \321\1\x35\41 386,SM
+XOR reg_eax,sbyte \321\1\x83\206\15 386,SM,ND
+XOR reg_eax,sbig \321\1\x35\41 386,SM,ND
+XOR reg_eax,imm32 \321\1\x35\41 386
XOR rm8,imm \300\1\x80\206\21 8086,SM
-XOR rm16,imm \320\300\134\1\x81\206\131 8086,SM,ND
-XOR rm32,imm \321\300\144\1\x81\206\141 386,SM,ND
+XOR rm16,imm \320\300\134\1\x81\206\131 8086,SM
+XOR rm32,imm \321\300\144\1\x81\206\141 386,SM
XOR mem,imm8 \300\1\x80\206\21 8086,SM
-XOR mem,imm16 \320\300\134\1\x81\206\131 8086,SM,ND
-XOR mem,imm32 \321\300\144\1\x81\206\141 386,SM,ND
+XOR mem,imm16 \320\300\134\1\x81\206\131 8086,SM
+XOR mem,imm32 \321\300\144\1\x81\206\141 386,SM
CMOVcc reg16,mem \320\301\1\x0F\330\x40\110 P6,SM
CMOVcc reg16,reg16 \320\301\1\x0F\330\x40\110 P6
CMOVcc reg32,mem \321\301\1\x0F\330\x40\110 P6,SM
diff --git a/macros.c b/macros.c
index ed70a75..38a7e0f 100644
--- a/macros.c
+++ b/macros.c
@@ -1,6 +1,12 @@
/* This file auto-generated from standard.mac by macros.pl - don't edit it */
static char *stdmac[] = {
+ "%idefine IDEAL",
+ "%idefine JUMPS",
+ "%idefine P386",
+ "%idefine P486",
+ "%idefine P586",
+ "%idefine END",
"%define __NASM_MAJOR__ 0",
"%define __NASM_MINOR__ 98",
"%define __FILE__",
@@ -57,6 +63,12 @@ static char *stdmac[] = {
"%imacro bits 1+.nolist",
"[bits %1]",
"%endmacro",
+ "%imacro use16 0.nolist",
+ "[bits 16]",
+ "%endmacro",
+ "%imacro use32 0.nolist",
+ "[bits 32]",
+ "%endmacro",
"%imacro global 1-*.nolist",
"%rep %0",
"[global %1]",
@@ -69,5 +81,9 @@ static char *stdmac[] = {
"%rotate 1",
"%endrep",
"%endmacro",
+ "%imacro cpu 1+.nolist",
+ "[cpu %1]",
+ "%endmacro",
NULL
};
+#define TASM_MACRO_COUNT 6
diff --git a/macros.pl b/macros.pl
index e1d9ed0..ecf0595 100644
--- a/macros.pl
+++ b/macros.pl
@@ -6,7 +6,8 @@
# Julian Hall. All rights reserved. The software is
# redistributable under the licence given in the file "Licence"
# distributed in the NASM archive.
-use strict;
+
+# use strict; # if your PERL's got it
my $fname;
my $line = 0;
diff --git a/misc/exasm.zip b/misc/exasm.zip
index b4e9e58..e813018 100644
--- a/misc/exasm.zip
+++ b/misc/exasm.zip
Binary files differ
diff --git a/nasm.c b/nasm.c
index cd7f714..c3575cd 100644
--- a/nasm.c
+++ b/nasm.c
@@ -51,7 +51,7 @@ static struct ofmt *ofmt = NULL;
static FILE *error_file; /* Where to write error messages */
static FILE *ofile = NULL;
-static int optimizing = 0; /* number of optimization passes to take */
+int optimizing = 0; /* number of optimization passes to take */
static int sb, cmd_sb = 16; /* by default */
static unsigned long cmd_cpu = IF_PLEVEL; /* highest level by default */
static unsigned long cpu = IF_PLEVEL; /* passed to insn_size & assemble.c */
@@ -429,15 +429,15 @@ static int process_arg (char *p, char *q)
" or nasm -r for version info (obsolete)\n"
" or nasm -v for version info (preferred)\n\n"
" -t Assemble in SciTech TASM compatible mode\n"
- " -g Generate debug information in selected format.\n"
- " -e preprocess only (writes output to stdout by default)\n"
+ " -g Generate debug information in selected format.\n");
+ printf(" -e preprocess only (writes output to stdout by default)\n"
" -a don't preprocess (assemble only)\n"
" -M generate Makefile dependencies on stdout\n\n"
" -E<file> redirect error messages to file\n"
" -s redirect error messages to stdout\n\n"
" -F format select a debugging format\n\n"
- " -I<path> adds a pathname to the include file path\n"
- " -O<digit> optimize branch offsets (-O0 disables, default)\n"
+ " -I<path> adds a pathname to the include file path\n");
+ printf(" -O<digit> optimize branch offsets (-O0 disables, default)\n"
" -P<file> pre-includes a file\n"
" -D<macro>[=<value>] pre-defines a macro\n"
" -U<macro> undefines a macro\n"
diff --git a/nasm.h b/nasm.h
index d4079dc..55d8a8f 100644
--- a/nasm.h
+++ b/nasm.h
@@ -13,7 +13,7 @@
#define NASM_MAJOR_VER 0
#define NASM_MINOR_VER 98
-#define NASM_VER "0.98.09"
+#define NASM_VER "0.98.11"
#ifndef NULL
#define NULL 0
@@ -426,8 +426,10 @@ enum {
/* special type of immediate operand */
#define ONENESS 0x00800000L /* so UNITY == IMMEDIATE | ONENESS */
#define UNITY 0x00802000L /* for shift/rotate instructions */
-#define BYTENESS 0x80000000L /* so SBYTE == IMMEDIATE | BYTENESS */
-#define SBYTE 0x80002000L /* for op r16/32,immediate instrs. */
+#define BYTENESS 0x40000000L /* so SBYTE == IMMEDIATE | BYTENESS */
+#define SBYTE 0x40002000L /* for op r16/32,immediate instrs. */
+#define BIGNESS 0x80000000L /* so SBIG == IMMEDIATE | BIGNESS */
+#define SBIG 0x80002000L /* for eax immediate instrs. */
/*
* Next, the codes returned from the parser, for registers and
@@ -867,5 +869,6 @@ extern int tasm_compatible_mode;
*/
extern int pass0; /* this is globally known */
+extern int optimizing;
#endif
diff --git a/ndisasm.c b/ndisasm.c
index 354ea3c..227dde7 100644
--- a/ndisasm.c
+++ b/ndisasm.c
@@ -27,7 +27,7 @@ static const char *help =
" -u sets USE32 (32-bit mode)\n"
" -b 16 or -b 32 sets number of bits too\n"
" -h displays this text\n"
-" -r displays the version number\n"
+" -r or -v displays the version number\n"
" -e skips <bytes> bytes of header\n"
" -k avoids disassembling <bytes> bytes from position <start>\n"
" -p selects the preferred vendor instruction set (intel, amd, cyrix, idt)\n";
@@ -42,7 +42,8 @@ int main(int argc, char **argv)
char *pname = *argv;
char *filename = NULL;
unsigned long nextsync, synclen, initskip = 0L;
- int lenread, lendis;
+ int lenread;
+ long lendis;
int autosync = FALSE;
int bits = 16;
int eof = FALSE;
@@ -68,7 +69,8 @@ int main(int argc, char **argv)
fprintf(stderr, help);
return 0;
case 'r':
- fprintf(stderr, "NDISASM version " NASM_VER "\n");
+ case 'v':
+ fprintf(stderr, "NDISASM version %s compiled " __DATE__ "\n", NASM_VER);
return 0;
case 'u': /* USE32 */
bits = 32;
@@ -181,6 +183,10 @@ int main(int argc, char **argv)
}
p = ""; /* force to next argument */
break;
+ default: /*bf*/
+ fprintf(stderr, "%s: unrecognised option `-%c'\n",
+ pname, *p);
+ return 1;
}
} else if (!filename) {
filename = p;
@@ -227,7 +233,7 @@ int main(int argc, char **argv)
} else
lenread = 0;
p += lenread;
- if (offset == nextsync) {
+ if ((unsigned long)offset == nextsync) {
if (synclen) {
printf("%08lX skipping 0x%lX bytes\n", offset, synclen);
offset += synclen;
@@ -239,7 +245,7 @@ int main(int argc, char **argv)
while (p > q && (p - q >= INSN_MAX || lenread == 0)) {
lendis = disasm (q, outbuf, bits, offset, autosync, prefer);
if (!lendis || lendis > (p - q) ||
- lendis > nextsync-offset)
+ (unsigned long)lendis > nextsync-offset)
lendis = eatbyte (q, outbuf);
output_ins (offset, q, lendis, outbuf);
q += lendis;
diff --git a/ndisasm.doc b/ndisasm.doc
index 76367f5..5b5374a 100644
--- a/ndisasm.doc
+++ b/ndisasm.doc
@@ -174,7 +174,7 @@ Bugs and Improvements
=====================
There are no known bugs. However, any you find, with patches if
-possible, should be sent to <jules@earthcorp.com> or
+possible, should be sent to <jules@dcs.warwick.ac.uk> or
<anakin@pobox.com>, and we'll try to fix them. Feel free to send
contributions and new features as well.
diff --git a/parser.c b/parser.c
index 00dfcad..d802f05 100644
--- a/parser.c
+++ b/parser.c
@@ -686,9 +686,12 @@ insn *parse_line (int pass, char *buffer, insn *result,
if (is_simple(value)) {
if (reloc_value(value)==1)
result->oprs[operand].type |= UNITY;
- if (reloc_value(value) >= -128 &&
- reloc_value(value) <= 127)
- result->oprs[operand].type |= SBYTE;
+ if (optimizing) {
+ if (reloc_value(value) >= -128 &&
+ reloc_value(value) <= 127)
+ result->oprs[operand].type |= SBYTE;
+ else result->oprs[operand].type |= SBIG;
+ }
}
}
else /* it's a register */
diff --git a/rdoff/Makefile.in b/rdoff/Makefile.in
index 5ea14a0..38620d7 100644
--- a/rdoff/Makefile.in
+++ b/rdoff/Makefile.in
@@ -1,84 +1,86 @@
-# $Id$
-#
-# Auto-configuring Makefile for RDOFF object file utils; part of the
-# Netwide Assembler
-#
-# The Netwide Assembler is copyright (C) 1996 Simon Tatham and
-# Julian Hall. All rights reserved. The software is
-# redistributable under the licence given in the file "Licence"
-# distributed in the NASM archive.
-
-top_srcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-bindir = @bindir@
-mandir = @mandir@
-
-CC = @CC@
-CFLAGS = @CFLAGS@ @GCCFLAGS@ -I$(srcdir) -I$(top_srcdir)
-LDFLAGS = @LDFLAGS@
-
-INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_DATA = @INSTALL_DATA@
-LN_S = @LN_S@
-
-LDRDFLIBS = rdoff.o nasmlib.o symtab.o collectn.o rdlib.o segtab.o hash.o
-RDXLIBS = rdoff.o rdfload.o symtab.o collectn.o hash.o
-
-.c.o:
- $(CC) -c $(CFLAGS) $<
-
-all: rdfdump ldrdf rdx rdflib rdf2bin rdf2com rdf2ihx
-
-rdfdump: rdfdump.o
- $(CC) $(LDFLAGS) -o rdfdump rdfdump.o
-ldrdf: ldrdf.o $(LDRDFLIBS)
- $(CC) $(LDFLAGS) -o ldrdf ldrdf.o $(LDRDFLIBS)
-rdx: rdx.o $(RDXLIBS)
- $(CC) $(LDFLAGS) -o rdx rdx.o $(RDXLIBS)
-rdflib: rdflib.o
- $(CC) $(LDFLAGS) -o rdflib rdflib.o
-rdf2bin: rdf2bin.o $(RDXLIBS) nasmlib.o
- $(CC) $(LDFLAGS) -o rdf2bin rdf2bin.o $(RDXLIBS) nasmlib.o
-rdf2com:
- rm -f rdf2com && $(LN_S) rdf2bin rdf2com
-rdf2ihx: rdf2ihx.o $(RDXLIBS) nasmlib.o
- $(CC) $(LDFLAGS) -o rdf2ihx rdf2ihx.o $(RDXLIBS) nasmlib.o
-
-rdf2ihx.o: rdf2ihx.c
-rdf2bin.o: rdf2bin.c
-rdfdump.o: rdfdump.c
-rdoff.o: rdoff.c rdoff.h
-ldrdf.o: ldrdf.c rdoff.h $(top_srcdir)/nasmlib.h symtab.h collectn.h rdlib.h
-symtab.o: symtab.c symtab.h
-collectn.o: collectn.c collectn.h
-rdx.o: rdx.c rdoff.h rdfload.h symtab.h
-rdfload.o: rdfload.c rdfload.h rdoff.h collectn.h symtab.h
-rdlib.o: rdlib.c rdlib.h
-rdflib.o: rdflib.c
-segtab.o: segtab.c
-
-nasmlib.o: $(top_srcdir)/nasmlib.c
-## $(CC) -c $(CFLAGS) $(top_srcdir)/nasmlib.c
- cd $(top_srcdir);make nasmlib.o
- cp $(top_srcdir)/nasmlib.o $(srcdir)
-
-clean:
- rm -f *.o rdfdump ldrdf rdx rdflib rdf2bin rdf2com rdf2ihx
-
-spotless: clean
- rm -f Makefile
-
-distclean: spotless
-
-install: rdfdump ldrdf rdx rdflib rdf2bin rdf2com rdf2ihx
- $(INSTALL_PROGRAM) rdfdump $(INSTALLROOT)$(bindir)/rdfdump
- $(INSTALL_PROGRAM) ldrdf $(INSTALLROOT)$(bindir)/ldrdf
- $(INSTALL_PROGRAM) rdx $(INSTALLROOT)$(bindir)/rdx
- $(INSTALL_PROGRAM) rdflib $(INSTALLROOT)$(bindir)/rdflib
- $(INSTALL_PROGRAM) rdf2bin $(INSTALLROOT)$(bindir)/rdf2bin
- $(INSTALL_PROGRAM) rdf2ihx $(INSTALLROOT)$(bindir)/rdf2ihx
- cd $(INSTALLROOT)$(bindir) && rm -f rdf2com && $(LN_S) rdf2bin rdf2com
+***************
+*** 1,4 ****
+- # $Id$
+ #
+ # Auto-configuring Makefile for RDOFF object file utils; part of the
+ # Netwide Assembler
+--- 1,4 ----
++ # $Id$
+ #
+ # Auto-configuring Makefile for RDOFF object file utils; part of the
+ # Netwide Assembler
+***************
+*** 31,37 ****
+ .c.o:
+ $(CC) -c $(CFLAGS) $<
+
+- all: rdfdump ldrdf rdx rdflib rdf2bin rdf2com
+
+ rdfdump: rdfdump.o
+ $(CC) $(LDFLAGS) -o rdfdump rdfdump.o
+--- 31,37 ----
+ .c.o:
+ $(CC) -c $(CFLAGS) $<
+
++ all: rdfdump ldrdf rdx rdflib rdf2bin rdf2com rdf2ihx
+
+ rdfdump: rdfdump.o
+ $(CC) $(LDFLAGS) -o rdfdump rdfdump.o
+***************
+*** 45,51 ****
+ $(CC) $(LDFLAGS) -o rdf2bin rdf2bin.o $(RDXLIBS) nasmlib.o
+ rdf2com:
+ rm -f rdf2com && $(LN_S) rdf2bin rdf2com
+
+ rdf2bin.o: rdf2bin.c
+ rdfdump.o: rdfdump.c
+ rdoff.o: rdoff.c rdoff.h
+--- 45,54 ----
+ $(CC) $(LDFLAGS) -o rdf2bin rdf2bin.o $(RDXLIBS) nasmlib.o
+ rdf2com:
+ rm -f rdf2com && $(LN_S) rdf2bin rdf2com
++ rdf2ihx: rdf2ihx.o $(RDXLIBS) nasmlib.o
++ $(CC) $(LDFLAGS) -o rdf2ihx rdf2ihx.o $(RDXLIBS) nasmlib.o
+
++ rdf2ihx.o: rdf2ihx.c
+ rdf2bin.o: rdf2bin.c
+ rdfdump.o: rdfdump.c
+ rdoff.o: rdoff.c rdoff.h
+***************
+*** 62,78 ****
+ $(CC) -c $(CFLAGS) $(top_srcdir)/nasmlib.c
+
+ clean:
+- rm -f *.o rdfdump ldrdf rdx rdflib rdf2bin rdf2com
+
+ spotless: clean
+ rm -f Makefile
+
+ distclean: spotless
+
+- install: rdfdump ldrdf rdx rdflib rdf2bin rdf2com
+ $(INSTALL_PROGRAM) rdfdump $(INSTALLROOT)$(bindir)/rdfdump
+ $(INSTALL_PROGRAM) ldrdf $(INSTALLROOT)$(bindir)/ldrdf
+ $(INSTALL_PROGRAM) rdx $(INSTALLROOT)$(bindir)/rdx
+ $(INSTALL_PROGRAM) rdflib $(INSTALLROOT)$(bindir)/rdflib
+ $(INSTALL_PROGRAM) rdf2bin $(INSTALLROOT)$(bindir)/rdf2bin
+ cd $(INSTALLROOT)$(bindir) && rm -f rdf2com && $(LN_S) rdf2bin rdf2com
+--- 65,82 ----
+ $(CC) -c $(CFLAGS) $(top_srcdir)/nasmlib.c
+
+ clean:
++ rm -f *.o rdfdump ldrdf rdx rdflib rdf2bin rdf2com rdf2ihx
+
+ spotless: clean
+ rm -f Makefile
+
+ distclean: spotless
+
++ install: rdfdump ldrdf rdx rdflib rdf2bin rdf2com rdf2ihx
+ $(INSTALL_PROGRAM) rdfdump $(INSTALLROOT)$(bindir)/rdfdump
+ $(INSTALL_PROGRAM) ldrdf $(INSTALLROOT)$(bindir)/ldrdf
+ $(INSTALL_PROGRAM) rdx $(INSTALLROOT)$(bindir)/rdx
+ $(INSTALL_PROGRAM) rdflib $(INSTALLROOT)$(bindir)/rdflib
+ $(INSTALL_PROGRAM) rdf2bin $(INSTALLROOT)$(bindir)/rdf2bin
++ $(INSTALL_PROGRAM) rdf2ihx $(INSTALLROOT)$(bindir)/rdf2ihx
+ cd $(INSTALLROOT)$(bindir) && rm -f rdf2com && $(LN_S) rdf2bin rdf2com
diff --git a/rdoff/ldrdf.c b/rdoff/ldrdf.c
index 3d9d749..d9aac2f 100644
--- a/rdoff/ldrdf.c
+++ b/rdoff/ldrdf.c
@@ -1,1347 +1,31 @@
-/* ldrdf.c RDOFF Object File linker/loader main program
- *
- * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
- * Julian Hall. All rights reserved. The software is
- * redistributable under the licence given in the file "Licence"
- * distributed in the NASM archive.
- */
-
-/*
- * TODO: actually get this new version working!
- * - finish off write_output() - appears to be done
- * - implement library searching - appears to be done
- * - maybe we only want to do one pass, for performance reasons?
- * this makes things a little harder, but unix 'ld' copes...
- * - implement command line options - appears to be done
- * - improve symbol table implementation - done, thanks to Graeme Defty
- * - keep a cache of symbol names in each library module so
- * we don't have to constantly recheck the file
- * - general performance improvements
- *
- * BUGS & LIMITATIONS: this program doesn't support multiple code, data
- * or bss segments, therefore for 16 bit programs whose code, data or BSS
- * segment exceeds 64K in size, it will not work. This program probably
- * wont work if compiled by a 16 bit compiler. Try DJGPP if you're running
- * under DOS. '#define STINGY_MEMORY' may help a little.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "multboot.h"
-#include "rdoff.h"
-#include "symtab.h"
-#include "collectn.h"
-#include "rdlib.h"
-#include "segtab.h"
-
-#define LDRDF_VERSION "1.02"
-
-#define RDF_MAXSEGS 64
-/* #define STINGY_MEMORY */
-
-/* =======================================================================
- * Types & macros that are private to this program
- */
-
-struct segment_infonode {
- int dest_seg; /* output segment to be placed into, -1 to
- skip linking this segment */
- long reloc; /* segment's relocation factor */
-};
-
-
-struct modulenode {
- rdffile f; /* the RDOFF file structure */
- struct segment_infonode seginfo[RDF_MAXSEGS]; /* what are we doing
- with each segment? */
- void * header;
- char * name;
- struct modulenode * next;
- long bss_reloc;
-};
-
-#include "ldsegs.h"
-
-#define newstr(str) strcpy(malloc(strlen(str) + 1),str)
-#define newstrcat(s1,s2) strcat(strcpy(malloc(strlen(s1)+strlen(s2)+1),s1),s2)
-
-/* ==========================================================================
- * Function prototypes of private utility functions
- */
-
-void processmodule(const char * filename, struct modulenode * mod);
-int allocnewseg(int16 type,int16 reserved);
-int findsegment(int16 type,int16 reserved);
-void symtab_add(const char * symbol, int segment, long offset);
-int symtab_get(const char * symbol, int * segment, long * offset);
-
-/* =========================================================================
- * Global data structures.
- */
-
-/* a linked list of modules that will be included in the output */
-struct modulenode * modules = NULL;
-struct modulenode * lastmodule = NULL;
-
-/* a linked list of libraries to be searched for unresolved imported symbols */
-struct librarynode * libraries = NULL;
-struct librarynode * lastlib = NULL;
-
-/* the symbol table */
-void * symtab = NULL;
-
-/* objects search path */
-char * objpath = NULL;
-
-/* libraries search path */
-char * libpath = NULL;
-
-/* error file */
-static FILE * error_file;
-
-#ifdef _MULTBOOT_H
-
-/* loading address for multiboot header */
-unsigned MBHloadAddr;
-
-/*
- * Tiny code that moves RDF loader to its working memory region:
- * mov esi,SOURCE_ADDR ; BE xx xx xx xx
- * mov edi,DEST_ADDR ; BF xx xx xx xx
- * mov esp,edi ; 89 FC
- * push edi ; 57
- * mov ecx,RDFLDR_LENGTH/4 ; B9 xx xx xx xx
- * cld ; FC
- * rep movsd ; F3 A5
- * ret ; C3
- */
-
-#define RDFLDR_LENGTH 4096 /* Loader will be moved to unused */
-#define RDFLDR_DESTLOC 0xBF000 /* video page */
-
-unsigned char RDFloaderMover[]={
- 0xBE, 0, 0, 0, 0, 0xBF, 0, 0xF0, 0xB, 0,
- 0x89, 0xFC, 0x57,
- 0xB9, 0, 4, 0, 0,
- 0xFC, 0xF3, 0xA5, 0xC3
-};
-
-#endif
-
-/* the header of the output file, built up stage by stage */
-rdf_headerbuf * newheader = NULL;
-
-/* The current state of segment allocation, including information about
- * which output segment numbers have been allocated, and their types and
- * amount of data which has already been allocated inside them.
- */
-struct SegmentHeaderRec outputseg[RDF_MAXSEGS];
-int nsegs = 0;
-long bss_length;
-
-/* global options which affect how the program behaves */
-struct ldrdfoptions {
- int verbose;
- int align;
- int warnUnresolved;
- int errorUnresolved;
- int strip;
- int respfile;
- int stderr_redir;
- int objpath;
- int libpath;
- int addMBheader;
-} options;
-
-int errorcount = 0; /* determines main program exit status */
-
-/* =========================================================================
- * Utility functions
- */
-
-
-/*
- * initsegments()
- *
- * sets up segments 0, 1, and 2, the initial code data and bss segments
- */
-
-void initsegments()
-{
- nsegs = 3;
- outputseg[0].type = 1;
- outputseg[0].number = 0;
- outputseg[0].reserved = 0;
- outputseg[0].length = 0;
- outputseg[1].type = 2;
- outputseg[1].number = 1;
- outputseg[1].reserved = 0;
- outputseg[1].length = 0;
- outputseg[2].type = 0xFFFF; /* reserved segment type */
- outputseg[2].number = 2;
- outputseg[2].reserved = 0;
- outputseg[2].length = 0;
- bss_length = 0;
-}
-
-/*
- * loadmodule
- *
- * Determine the characteristics of a module, and decide what to do with
- * each segment it contains (including determining destination segments and
- * relocation factors for segments that are kept).
- */
-
-void loadmodule(const char * filename)
-{
- if (options.verbose)
- printf("loading `%s'\n", filename);
-
- /* allocate a new module entry on the end of the modules list */
- if (!modules)
- {
- modules = malloc (sizeof(*modules));
- lastmodule = modules;
- }
- else
- {
- lastmodule->next = malloc (sizeof(*modules));
- lastmodule = lastmodule->next;
- }
-
- if ( ! lastmodule)
- {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
-
- /* open the file using 'rdfopen', which returns nonzero on error */
-
- if (rdfopen(&lastmodule->f, filename) != 0)
- {
- rdfperror("ldrdf", filename);
- exit(1);
- }
-
- /*
- * store information about the module, and determine what segments
- * it contains, and what we should do with them (determine relocation
- * factor if we decide to keep them)
- */
-
- lastmodule->header = NULL;
- lastmodule->name = strdup(filename);
- lastmodule->next = NULL;
-
- processmodule(filename, lastmodule);
-}
-
-/*
- * processmodule()
- *
- * step through each segment, determine what exactly we're doing with
- * it, and if we intend to keep it, determine (a) which segment to
- * put it in and (b) whereabouts in that segment it will end up.
- * (b) is fairly easy, cos we're now keeping track of how big each segment
- * in our output file is...
- */
-
-void processmodule(const char * filename, struct modulenode * mod)
-{
- struct segconfig sconf;
- int seg, outseg;
- void * header;
- rdfheaderrec * hr;
- long bssamount = 0;
-
- for (seg = 0; seg < mod->f.nsegs; seg++)
- {
- /*
- * get the segment configuration for this type from the segment
- * table. getsegconfig() is a macro, defined in ldsegs.h.
- */
- getsegconfig(sconf, mod->f.seg[seg].type);
-
- if (options.verbose > 1) {
- printf ("%s %04x [%04x:%10s] ", filename, mod->f.seg[seg].number,
- mod->f.seg[seg].type, sconf.typedesc);
- }
- /*
- * sconf->dowhat tells us what to do with a segment of this type.
- */
- switch (sconf.dowhat) {
- case SEG_IGNORE:
- /*
- * Set destination segment to -1, to indicate that this segment
- * should be ignored for the purpose of output, ie it is left
- * out of the linked executable.
- */
- mod->seginfo[seg].dest_seg = -1;
- if (options.verbose > 1) printf("IGNORED\n");
- break;
-
- case SEG_NEWSEG:
- /*
- * The configuration tells us to create a new segment for
- * each occurrence of this segment type.
- */
- outseg = allocnewseg(sconf.mergetype,
- mod->f.seg[seg].reserved);
- mod->seginfo[seg].dest_seg = outseg;
- mod->seginfo[seg].reloc = 0;
- outputseg[outseg].length = mod->f.seg[seg].length;
- if (options.verbose > 1)
- printf ("=> %04x:%08lx (+%04lx)\n", outseg,
- mod->seginfo[seg].reloc,
- mod->f.seg[seg].length);
- break;
-
- case SEG_MERGE:
- /*
- * The configuration tells us to merge the segment with
- * a previously existing segment of type 'sconf.mergetype',
- * if one exists. Otherwise a new segment is created.
- * This is handled transparently by 'findsegment()'.
- */
- outseg = findsegment(sconf.mergetype,
- mod->f.seg[seg].reserved);
- mod->seginfo[seg].dest_seg = outseg;
-
- /*
- * We need to add alignment to these segments.
- */
- if (outputseg[outseg].length % options.align != 0)
- outputseg[outseg].length +=
- options.align - (outputseg[outseg].length % options.align);
-
- mod->seginfo[seg].reloc = outputseg[outseg].length;
- outputseg[outseg].length += mod->f.seg[seg].length;
-
- if (options.verbose > 1)
- printf ("=> %04x:%08lx (+%04lx)\n", outseg,
- mod->seginfo[seg].reloc,
- mod->f.seg[seg].length);
- }
-
- }
-
- /*
- * extract symbols from the header, and dump them into the
- * symbol table
- */
- header = malloc(mod->f.header_len);
- if (!header) {
- fprintf(stderr, "ldrdf: not enough memory\n");
- exit(1);
- }
- if (rdfloadseg(&mod->f, RDOFF_HEADER, header)) {
- rdfperror("ldrdf", filename);
- exit(1);
- }
-
- while ((hr = rdfgetheaderrec (&mod->f)))
- {
- switch(hr->type) {
- case 2: /* imported symbol - define with seg = -1 */
- case 7:
- symtab_add(hr->i.label, -1, 0);
- break;
-
- case 3: /* exported symbol */
- {
- int destseg;
- long destreloc;
-
- if (hr->e.segment == 2)
- {
- destreloc = bss_length;
- if (destreloc % options.align != 0)
- destreloc += options.align - (destreloc % options.align);
- destseg = 2;
- }
- else
- {
- if ((destseg = mod->seginfo[(int)hr->e.segment].dest_seg) == -1)
- continue;
- destreloc = mod->seginfo[(int)hr->e.segment].reloc;
- }
- symtab_add(hr->e.label, destseg, destreloc + hr->e.offset);
- break;
- }
-
- case 5: /* BSS reservation */
- /*
- * first, amalgamate all BSS reservations in this module
- * into one, because we allow this in the output format.
- */
- bssamount += hr->b.amount;
- break;
- }
- }
-
- if (bssamount != 0)
- {
- /*
- * handle the BSS segment - first pad the existing bss length
- * to the correct alignment, then store the length in bss_reloc
- * for this module. Then add this module's BSS length onto
- * bss_length.
- */
- if (bss_length % options.align != 0)
- bss_length += options.align - (bss_length % options.align);
-
- mod->bss_reloc = bss_length;
- if (options.verbose > 1) {
- printf ("%s 0002 [ BSS] => 0002:%08lx (+%04lx)\n",
- filename, bss_length, bssamount);
- }
- bss_length += bssamount;
- }
-
-#ifdef STINGY_MEMORY
- /*
- * we free the header buffer here, to save memory later.
- * this isn't efficient, but probably halves the memory usage
- * of this program...
- */
- mod->f.header_loc = NULL;
- free(header);
-
-#endif
-
-}
-
-
-/*
- * Look in list for module by its name.
- */
-int lookformodule(const char *name)
- {
- struct modulenode *curr=modules;
-
- while(curr) {
- if (!strcmp(name,curr->name)) return 1;
- curr = curr->next;
- }
- return 0;
- }
-
-
-/*
- * allocnewseg()
- * findsegment()
- *
- * These functions manipulate the array of output segments, and are used
- * by processmodule(). allocnewseg() allocates a segment in the array,
- * initialising it to be empty. findsegment() first scans the array for
- * a segment of the type requested, and if one isn't found allocates a
- * new one.
- */
-int allocnewseg(int16 type,int16 reserved)
-{
- outputseg[nsegs].type = type;
- outputseg[nsegs].number = nsegs;
- outputseg[nsegs].reserved = reserved;
- outputseg[nsegs].length = 0;
- outputseg[nsegs].offset = 0;
- outputseg[nsegs].data = NULL;
-
- return nsegs++;
-}
-
-int findsegment(int16 type,int16 reserved)
-{
- int i;
-
- for (i = 0; i < nsegs; i++)
- if (outputseg[i].type == type) return i;
-
- return allocnewseg(type,reserved);
-}
-
-/*
- * symtab_add()
- *
- * inserts a symbol into the global symbol table, which associates symbol
- * names either with addresses, or a marker that the symbol hasn't been
- * resolved yet, or possibly that the symbol has been defined as
- * contained in a dynamic [load time/run time] linked library.
- *
- * segment = -1 => not yet defined
- * segment = -2 => defined as dll symbol
- *
- * If the symbol is already defined, and the new segment >= 0, then
- * if the original segment was < 0 the symbol is redefined, otherwise
- * a duplicate symbol warning is issued. If new segment == -1, this
- * routine won't change a previously existing symbol. It will change
- * to segment = -2 only if the segment was previously < 0.
- */
-
-void symtab_add(const char * symbol, int segment, long offset)
-{
- symtabEnt * ste;
-
- ste = symtabFind(symtab, symbol);
- if (ste)
- {
- if (ste->segment >= 0) {
- /*
- * symbol previously defined
- */
- if (segment < 0) return;
- fprintf (error_file, "warning: `%s' redefined\n", symbol);
- return;
- }
-
- /*
- * somebody wanted the symbol, and put an undefined symbol
- * marker into the table
- */
- if (segment == -1) return;
- /*
- * we have more information now - update the symbol's entry
- */
- ste->segment = segment;
- ste->offset = offset;
- ste->flags = 0;
- return;
- }
- /*
- * this is the first declaration of this symbol
- */
- ste = malloc(sizeof(symtabEnt));
- if (!ste) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
- ste->name = strdup(symbol);
- ste->segment = segment;
- ste->offset = offset;
- ste->flags = 0;
- symtabInsert(symtab, ste);
-}
-
-/*
- * symtab_get()
- *
- * Retrieves the values associated with a symbol. Undefined symbols
- * are assumed to have -1:0 associated. Returns 1 if the symbol was
- * successfully located.
- */
-
-int symtab_get(const char * symbol, int * segment, long * offset)
-{
- symtabEnt * ste = symtabFind(symtab, symbol);
- if (!ste) {
- *segment = -1;
- *offset = 0;
- return 0;
- }
- else
- {
- *segment = ste->segment;
- *offset = ste->offset;
- return 1;
- }
-}
-
-/*
- * add_library()
- *
- * checks that a library can be opened and is in the correct format,
- * then adds it to the linked list of libraries.
- */
-
-void add_library(const char * name)
-{
- if (rdl_verify(name)) {
- rdl_perror("ldrdf", name);
- errorcount++;
- return;
- }
- if (! libraries)
- {
- lastlib = libraries = malloc(sizeof(*libraries));
- if (! libraries) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
- }
- else
- {
- lastlib->next = malloc(sizeof(*libraries));
- if (!lastlib->next) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
- lastlib = lastlib->next;
- }
- lastlib->next = NULL;
- if (rdl_open(lastlib, name)) {
- rdl_perror("ldrdf", name);
- errorcount++;
- return;
- }
-}
-
-/*
- * search_libraries()
- *
- * scans through the list of libraries, attempting to match symbols
- * defined in library modules against symbols that are referenced but
- * not defined (segment = -1 in the symbol table)
- *
- * returns 1 if any extra library modules are included, indicating that
- * another pass through the library list should be made (possibly).
- */
-
-int search_libraries()
-{
- struct librarynode * cur;
- rdffile f;
- int i;
- void * header;
- int segment;
- long offset;
- int doneanything = 0, pass = 1, keepfile;
- rdfheaderrec * hr;
-
- cur = libraries;
-
- while (cur)
- {
- if (options.verbose > 2)
- printf("scanning library `%s', pass %d...\n", cur->name, pass);
-
- for (i = 0; rdl_openmodule(cur, i, &f) == 0; i++)
- {
- if (pass == 2 && lookformodule(f.name)) continue;
-
- if (options.verbose > 3)
- printf(" looking in module `%s'\n", f.name);
-
- header = malloc(f.header_len);
- if (!header) {
- fprintf(stderr, "ldrdf: not enough memory\n");
- exit(1);
- }
- if (rdfloadseg(&f, RDOFF_HEADER, header)) {
- rdfperror("ldrdf", f.name);
- errorcount++;
- return 0;
- }
-
- keepfile = 0;
-
- while ((hr = rdfgetheaderrec (&f)))
- {
- /* we're only interested in exports, so skip others: */
- if (hr->type != 3) continue;
-
- /*
- * Find the symbol in the symbol table. If the symbol isn't
- * defined, we aren't interested, so go on to the next.
- * If it is defined as anything but -1, we're also not
- * interested. But if it is defined as -1, insert this
- * module into the list of modules to use, and go
- * immediately on to the next module...
- */
- if (! symtab_get(hr->e.label, &segment, &offset)
- || segment != -1)
- {
- continue;
- }
-
- doneanything = 1;
- keepfile = 1;
-
- /*
- * as there are undefined symbols, we can assume that
- * there are modules on the module list by the time
- * we get here.
- */
- lastmodule->next = malloc(sizeof(*lastmodule->next));
- if (!lastmodule->next) {
- fprintf(stderr, "ldrdf: not enough memory\n");
- exit(1);
- }
- lastmodule = lastmodule->next;
- memcpy(&lastmodule->f, &f, sizeof(f));
- lastmodule->name = strdup(f.name);
- lastmodule->next = NULL;
- processmodule(f.name, lastmodule);
- break;
- }
- if (!keepfile)
- {
- free(f.name);
- f.name = NULL;
- f.fp = NULL;
- }
- }
- if (rdl_error != 0 && rdl_error != RDL_ENOTFOUND)
- rdl_perror("ldrdf", cur->name);
-
- cur = cur->next;
- if (cur == NULL && pass == 1) {
- cur = libraries;
- pass++;
- }
- }
-
- return doneanything;
-}
-
-/*
- * write_output()
- *
- * this takes the linked list of modules, and walks through it, merging
- * all the modules into a single output module, and then writes this to a
- * file.
- */
-void write_output(const char * filename)
-{
- FILE * f;
- rdf_headerbuf * rdfheader;
- struct modulenode * cur;
- int i, availableseg, seg, localseg, isrelative;
- void * header;
- rdfheaderrec * hr, newrec;
- symtabEnt * se;
- segtab segs;
- long offset;
- byte * data;
-
- if ((f = fopen(filename, "wb"))==NULL) {
- fprintf(stderr, "ldrdf: couldn't open %s for output\n", filename);
- exit(1);
- }
- if ((rdfheader=rdfnewheader())==NULL) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
-
- /*
- * Add multiboot header if appropriate option is specified.
- * Multiboot record *MUST* be the first record in output file.
- */
- if (options.addMBheader) {
- if (options.verbose)
- puts("\nadding multiboot header record");
-
- hr = (rdfheaderrec *) malloc(sizeof(struct MultiBootHdrRec));
- hr->mbh.type = 9;
- hr->mbh.reclen = sizeof(struct tMultiBootHeader)+RDFLDRMOVER_SIZE;
-
- hr->mbh.mb.Magic = MB_MAGIC;
- hr->mbh.mb.Flags = MB_FL_KLUDGE;
- hr->mbh.mb.Checksum = ~(MB_MAGIC+MB_FL_KLUDGE-1);
- hr->mbh.mb.HeaderAddr = MBHloadAddr+16;
- hr->mbh.mb.LoadAddr = MBHloadAddr;
- hr->mbh.mb.Entry = MBHloadAddr+16+sizeof(struct tMultiBootHeader);
-
- memcpy(hr->mbh.mover,RDFloaderMover,RDFLDRMOVER_SIZE);
-
- rdfaddheader(rdfheader,hr);
- free(hr);
- }
-
- if (options.verbose)
- printf ("\nbuilding output module (%d segments)\n", nsegs);
-
- /*
- * Allocate the memory for the segments. We may be better off
- * building the output module one segment at a time when running
- * under 16 bit DOS, but that would be a slower way of doing this.
- * And you could always use DJGPP...
- */
- for (i = 0; i < nsegs; i++)
- {
- outputseg[i].data=NULL;
- if(!outputseg[i].length) continue;
- outputseg[i].data = malloc(outputseg[i].length);
- if (!outputseg[i].data) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
- }
-
- /*
- * initialise availableseg, used to allocate segment numbers for
- * imported and exported labels...
- */
- availableseg = nsegs;
-
- /*
- * Step through the modules, performing required actions on each one
- */
- for (cur = modules; cur; cur=cur->next)
- {
- /*
- * Read the actual segment contents into the correct places in
- * the newly allocated segments
- */
-
- for (i = 0; i < cur->f.nsegs; i++)
- {
- int dest = cur->seginfo[i].dest_seg;
-
- if (dest == -1) continue;
- if (rdfloadseg(&cur->f, i,
- outputseg[dest].data + cur->seginfo[i].reloc))
- {
- rdfperror("ldrdf", cur->name);
- exit(1);
- }
- }
-
- /*
- * Perform fixups, and add new header records where required
- */
-
- header = malloc(cur->f.header_len);
- if (!header) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
-
- if (cur->f.header_loc)
- rdfheaderrewind(&cur->f);
- else
- if (rdfloadseg(&cur->f, RDOFF_HEADER, header))
- {
- rdfperror("ldrdf", cur->name);
- exit(1);
- }
-
- /*
- * we need to create a local segment number -> location
- * table for the segments in this module.
- */
- init_seglocations(&segs);
- for (i = 0; i < cur->f.nsegs; i++)
- {
- add_seglocation(&segs, cur->f.seg[i].number,
- cur->seginfo[i].dest_seg, cur->seginfo[i].reloc);
- }
- /*
- * and the BSS segment (doh!)
- */
- add_seglocation (&segs, 2, 2, cur->bss_reloc);
-
- while ((hr = rdfgetheaderrec(&cur->f)))
- {
- switch(hr->type) {
- case 1: /* relocation record - need to do a fixup */
- /*
- * First correct the offset stored in the segment from
- * the start of the segment (which may well have changed).
- *
- * To do this we add to the number stored the relocation
- * factor associated with the segment that contains the
- * target segment.
- *
- * The relocation could be a relative relocation, in which
- * case we have to first subtract the amount we've relocated
- * the containing segment by.
- */
-
- if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset))
- {
- fprintf(stderr, "%s: reloc to undefined segment %04x\n",
- cur->name, (int) hr->r.refseg);
- errorcount++;
- break;
- }
-
- isrelative = (hr->r.segment & 64) == 64;
- hr->r.segment &= 63;
-
- if (hr->r.segment == 2 ||
- (localseg = rdffindsegment(&cur->f, hr->r.segment)) == -1)
- {
- fprintf(stderr, "%s: reloc from %s segment (%d)\n",
- cur->name,
- hr->r.segment == 2 ? "BSS" : "unknown",
- hr->r.segment);
- errorcount++;
- break;
- }
-
- if (hr->r.length != 1 && hr->r.length != 2 && hr->r.length!=4)
- {
- fprintf(stderr, "%s: nonstandard length reloc "
- "(%d bytes)\n", cur->name, hr->r.length);
- errorcount++;
- break;
- }
-
- /*
- * okay, now the relocation is in the segment pointed to by
- * cur->seginfo[localseg], and we know everything else is
- * okay to go ahead and do the relocation
- */
- data = outputseg[cur->seginfo[localseg].dest_seg].data;
- data += cur->seginfo[localseg].reloc + hr->r.offset;
-
- /*
- * data now points to the reference that needs
- * relocation. Calculate the relocation factor.
- * Factor is:
- * offset of referred object in segment [in offset]
- * (- relocation of localseg, if ref is relative)
- * For simplicity, the result is stored in 'offset'.
- * Then add 'offset' onto the value at data.
- */
-
- if (isrelative) offset -= cur->seginfo[localseg].reloc;
- switch (hr->r.length)
- {
- case 1:
- offset += *data;
- if (offset < -127 || offset > 128)
- fprintf(error_file, "warning: relocation out of range "
- "at %s(%02x:%08lx)\n", cur->name,
- (int)hr->r.segment, hr->r.offset);
- *data = (char) offset;
- break;
- case 2:
- offset += * (short *)data;
- if (offset < -32767 || offset > 32768)
- fprintf(error_file, "warning: relocation out of range "
- "at %s(%02x:%08lx)\n", cur->name,
- (int)hr->r.segment, hr->r.offset);
- * (short *)data = (short) offset;
- break;
- case 4:
- * (long *)data += offset;
- /* we can't easily detect overflow on this one */
- break;
- }
-
- /*
- * If the relocation was relative between two symbols in
- * the same segment, then we're done.
- *
- * Otherwise, we need to output a new relocation record
- * with the references updated segment and offset...
- */
- if (! isrelative
- || cur->seginfo[localseg].dest_seg != seg)
- {
- hr->r.segment = cur->seginfo[localseg].dest_seg;
- hr->r.offset += cur->seginfo[localseg].reloc;
- hr->r.refseg = seg;
- rdfaddheader(rdfheader, hr);
- }
- break;
-
- case 2: /* import symbol */
- case 7:
- /*
- * scan the global symbol table for the symbol
- * and associate its location with the segment number
- * for this module
- */
- se = symtabFind(symtab, hr->i.label);
- if (!se || se->segment == -1) {
- if (options.warnUnresolved) {
- fprintf(error_file, "warning: unresolved reference to `%s'"
- " in module `%s'\n", hr->i.label, cur->name);
- if (options.errorUnresolved==1) errorcount++;
- }
- /*
- * we need to allocate a segment number for this
- * symbol, and store it in the symbol table for
- * future reference
- */
- if (!se) {
- se=malloc(sizeof(*se));
- if (!se) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
- se->name = strdup(hr->i.label);
- se->flags = 0;
- se->segment = availableseg++;
- se->offset = 0;
- symtabInsert(symtab, se);
- }
- else {
- se->segment = availableseg++;
- se->offset = 0;
- }
- /*
- * output a header record that imports it to the
- * recently allocated segment number...
- */
- newrec = *hr;
- newrec.i.segment = se->segment;
- rdfaddheader(rdfheader, &newrec);
- }
-
- add_seglocation(&segs, hr->i.segment, se->segment, se->offset);
-
- break;
-
- case 3: /* export symbol */
- /*
- * need to insert an export for this symbol into the new
- * header, unless we're stripping symbols [unless this
- * symbol is in an explicit keep list]. *** FIXME ***
- */
- if (options.strip)
- break;
-
- if (hr->e.segment == 2) {
- seg = 2;
- offset = cur->bss_reloc;
- }
- else {
- localseg = rdffindsegment(&cur->f, hr->e.segment);
- if (localseg == -1) {
- fprintf(stderr, "%s: exported symbol `%s' from "
- "unrecognised segment\n", cur->name,
- hr->e.label);
- errorcount++;
- break;
- }
- offset = cur->seginfo[localseg].reloc;
- seg = cur->seginfo[localseg].dest_seg;
- }
-
- hr->e.segment = seg;
- hr->e.offset += offset;
- rdfaddheader(rdfheader, hr);
- break;
-
- case 8: /* module name */
- /*
- * insert module name record if export symbols
- * are not stripped.
- */
- if (options.strip) break;
-
- rdfaddheader(rdfheader, hr);
- break;
-
- case 6: /* segment fixup */
- /*
- * modify the segment numbers if necessary, and
- * pass straight through to the output module header
- *
- * *** FIXME ***
- */
- if (hr->r.segment == 2) {
- fprintf(stderr, "%s: segment fixup in BSS section\n",
- cur->name);
- errorcount++;
- break;
- }
- localseg = rdffindsegment(&cur->f, hr->r.segment);
- if (localseg == -1) {
- fprintf(stderr, "%s: segment fixup in unrecognised"
- " segment (%d)\n", cur->name, hr->r.segment);
- errorcount++;
- break;
- }
- hr->r.segment = cur->seginfo[localseg].dest_seg;
- hr->r.offset += cur->seginfo[localseg].reloc;
-
- if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset))
- {
- fprintf(stderr, "%s: segment fixup to undefined "
- "segment %04x\n", cur->name, (int)hr->r.refseg);
- errorcount++;
- break;
- }
- hr->r.refseg = seg;
- rdfaddheader(rdfheader, hr);
- break;
- }
- }
-
- free(header);
- done_seglocations(&segs);
-
- }
-
- /*
- * combined BSS reservation for the entire results
- */
- newrec.type = 5;
- newrec.b.reclen = 4;
- newrec.b.amount = bss_length;
- rdfaddheader(rdfheader, &newrec);
-
- /*
- * Write the header
- */
- for (i = 0; i < nsegs; i++)
- {
- if (i == 2) continue;
- rdfaddsegment (rdfheader, outputseg[i].length);
- }
-
- if (options.addMBheader) {
- struct MultiBootHdrRec *mbhrec = (struct MultiBootHdrRec *)(rdfheader->buf->buffer);
- unsigned l = membuflength(rdfheader->buf) + 14 +
- 10*rdfheader->nsegments + rdfheader->seglength;
- unsigned *ldraddr = (unsigned *)(mbhrec->mover+1);
-
- mbhrec->mb.LoadEndAddr = MBHloadAddr+l+10+RDFLDR_LENGTH;
- mbhrec->mb.BSSendAddr = mbhrec->mb.LoadEndAddr;
- *ldraddr = MBHloadAddr+l+10;
- }
-
- rdfwriteheader(f, rdfheader);
- rdfdoneheader(rdfheader);
- /*
- * Step through the segments, one at a time, writing out into
- * the output file
- */
-
- for (i = 0; i < nsegs; i++)
- {
- int16 s;
- long l;
-
- if (i == 2) continue;
-
- s = translateshort(outputseg[i].type);
- fwrite(&s, 2, 1, f);
- s = translateshort(outputseg[i].number);
- fwrite(&s, 2, 1, f);
- s = translateshort(outputseg[i].reserved);
- fwrite(&s, 2, 1, f);
- l = translatelong(outputseg[i].length);
- fwrite(&l, 4, 1, f);
-
- fwrite(outputseg[i].data, outputseg[i].length, 1, f);
- }
-
- fwrite("\0\0\0\0\0\0\0\0\0\0", 10, 1, f);
-}
-
-/* =========================================================================
- * Main program
- */
-
-void usage()
-{
- printf("usage:\n");
- printf(" ldrdf [options] object modules ... [-llibrary ...]\n");
- printf(" ldrdf -r\n");
- printf("options:\n");
- printf(" -v[=n] increases verbosity by 1, or sets it to n\n");
- printf(" -a nn sets segment alignment value (default 16)\n");
- printf(" -s strips exported symbols\n");
- printf(" -x warn about unresolved symbols\n");
- printf(" -o name write output in file 'name'\n");
- printf(" -j path specify objects search path\n");
- printf(" -L path specify libraries search path\n");
- printf(" -mbh [address] add multiboot header to output file. Default\n");
- printf(" loading address is 0x110000\n");
- exit(0);
-}
-
-int main(int argc, char ** argv)
-{
- char * outname = "aout.rdf";
- int moduleloaded = 0;
- char *respstrings[128] = {0, };
-
- options.verbose = 0;
- options.align = 16;
- options.warnUnresolved = 0;
- options.strip = 0;
-
- error_file = stderr;
-
- argc --, argv ++;
- if (argc == 0) usage();
- while (argc && **argv == '-' && argv[0][1] != 'l')
- {
- switch(argv[0][1]) {
- case 'r':
- printf("ldrdf (linker for RDF files) version " LDRDF_VERSION "\n");
- printf( _RDOFF_H "\n");
- exit(0);
- case 'v':
- if (argv[0][2] == '=') {
- options.verbose = argv[0][3] - '0';
- if (options.verbose < 0 || options.verbose > 9) {
- fprintf(stderr, "ldrdf: verbosity level must be a number"
- " between 0 and 9\n");
- exit(1);
- }
- }
- else
- options.verbose++;
- break;
- case 'a':
- options.align = atoi(argv[1]);
- if (options.align <= 0) {
- fprintf(stderr,
- "ldrdf: -a expects a positive number argument\n");
- exit(1);
- }
- argv++, argc--;
- break;
- case 's':
- options.strip = 1;
- break;
- case 'x':
- options.warnUnresolved = 1;
- if (argv[0][2]=='e')
- options.errorUnresolved = 1;
- break;
- case 'o':
- outname = argv[1];
- argv++, argc--;
- break;
- case 'j':
- if (!objpath)
- {
- options.objpath = 1;
- objpath = argv[1];
- argv++, argc--;
- break;
- }
- else
- {
- fprintf(stderr,"ldrdf: more than one objects search path specified\n");
- exit(1);
- }
- case 'L':
- if (!libpath)
- {
- options.libpath = 1;
- libpath = argv[1];
- argv++, argc--;
- break;
- }
- else
- {
- fprintf(stderr,"ldrdf: more than one libraries search path specified\n");
- exit(1);
- }
- case '@': {
- int i=0;
- char buf[256];
- FILE *f;
-
- options.respfile = 1;
- if (argv[1] != NULL) f = fopen(argv[1],"r");
- else
- {
- fprintf(stderr,"ldrdf: no response file name specified\n");
- exit(1);
- }
-
- if (f == NULL)
- {
- fprintf(stderr,"ldrdf: unable to open response file\n");
- exit(1);
- }
- argc-=2;
- while(fgets(buf,sizeof(buf)-1,f)!=NULL)
- {
- char *p;
- if (buf[0]=='\n') continue;
- if ((p = strchr(buf,'\n')) != 0)
- *p=0;
- if (i >= 128)
- {
- fprintf(stderr,"ldrdf: too many input files\n");
- exit(1);
- }
- *(respstrings+i) = newstr(buf);
- argc++, i++;
- }
- goto done;
- }
- case '2':
- options.stderr_redir = 1;
- error_file = stdout;
- break;
- case 'm':
- if (argv[0][2] == 'b' && argv[0][3] == 'h') {
- if (argv[1][0] != '-') {
- MBHloadAddr = atoi(argv[1]);
- } else {
- MBHloadAddr = MB_DEFAULTLOADADDR;
- }
- options.addMBheader = 1;
- break;
- }
- default:
- usage();
- }
- argv++, argc--;
- }
-done:
- if (options.verbose > 4) {
- printf("ldrdf invoked with options:\n");
- printf(" section alignment: %d bytes\n", options.align);
- printf(" output name: `%s'\n", outname);
- if (options.strip)
- printf(" strip symbols\n");
- if (options.warnUnresolved)
- printf(" warn about unresolved symbols\n");
- if (options.errorUnresolved)
- printf(" error if unresolved symbols\n");
- if (options.objpath)
- printf(" objects search path: %s\n",objpath);
- if (options.libpath)
- printf(" libraries search path: %s\n",libpath);
- if (options.addMBheader)
- printf(" loading address for multiboot header: 0x%X\n",MBHloadAddr);
- printf("\n");
- }
-
- symtab = symtabNew();
- initsegments();
-
- if (!symtab) {
- fprintf(stderr, "ldrdf: out of memory\n");
- exit(1);
- }
-
- if (*respstrings) argv = respstrings;
- while (argc)
- {
- if (!strncmp(*argv, "-l", 2)) /* library */
- {
- if(libpath) add_library(newstrcat(libpath,*argv + 2));
- else add_library(*argv + 2);
- }
- else {
- if(objpath) loadmodule(newstrcat(objpath,*argv));
- else loadmodule(*argv);
- moduleloaded = 1;
- }
- argv++, argc--;
- }
-
- if (! moduleloaded) {
- printf("ldrdf: nothing to do. ldrdf -h for usage\n");
- return 0;
- }
-
-
- search_libraries();
-
- if (options.verbose > 2)
- {
- printf ("symbol table:\n");
- symtabDump(symtab, stdout);
- }
-
- write_output(outname);
-
- if (errorcount > 0) exit(1);
- return 0;
-}
+***************
+*** 29,42 ****
+ #include <stdlib.h>
+ #include <string.h>
+
+ #include "rdoff.h"
+ #include "symtab.h"
+ #include "collectn.h"
+ #include "rdlib.h"
+ #include "segtab.h"
+- #include "multboot.h"
+
+- #define LDRDF_VERSION "1.01 alpha 2"
+
+ #define RDF_MAXSEGS 64
+ /* #define STINGY_MEMORY */
+--- 29,42 ----
+ #include <stdlib.h>
+ #include <string.h>
+
++ #include "multboot.h"
+ #include "rdoff.h"
+ #include "symtab.h"
+ #include "collectn.h"
+ #include "rdlib.h"
+ #include "segtab.h"
+
++ #define LDRDF_VERSION "1.02"
+
+ #define RDF_MAXSEGS 64
+ /* #define STINGY_MEMORY */
diff --git a/rdoff/rdflib.c b/rdoff/rdflib.c
index 7a00fc6..5a8cf69 100644
--- a/rdoff/rdflib.c
+++ b/rdoff/rdflib.c
@@ -19,6 +19,7 @@
*/
#include <stdio.h>
+#include <stdlib.h>
#include <errno.h>
#include <string.h>
diff --git a/rdoff/rdfload.c b/rdoff/rdfload.c
index 4737282..6928ca2 100644
--- a/rdoff/rdfload.c
+++ b/rdoff/rdfload.c
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include "rdfload.h"
#include "symtab.h"
diff --git a/rdoff/rdoff.h b/rdoff/rdoff.h
index 0c57231..15f26bc 100644
--- a/rdoff/rdoff.h
+++ b/rdoff/rdoff.h
@@ -1,199 +1,106 @@
-/* rdoff.h RDOFF Object File manipulation routines header file
- *
- * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
- * Julian Hall. All rights reserved. The software is
- * redistributable under the licence given in the file "Licence"
- * distributed in the NASM archive.
- *
- * Permission to use this file in your own projects is granted, as long
- * as acknowledgement is given in an appropriate manner to its authors,
- * with instructions of how to obtain a copy via ftp.
- */
-
-#ifndef _RDOFF_H
-#define _RDOFF_H "RDOFF2 support routines v0.3"
-
-/* Some systems don't define this automatically */
-extern char *strdup(const char *);
-
-typedef unsigned short int16;
-typedef unsigned char byte;
-
-#define RDF_MAXSEGS 64
-
-/* the records that can be found in the RDOFF header */
-
-struct RelocRec {
- byte type; /* must be 1 */
- byte reclen; /* content length */
- byte segment; /* only 0 for code, or 1 for data supported,
- but add 64 for relative refs (ie do not require
- reloc @ loadtime, only linkage) */
- long offset; /* from start of segment in which reference is loc'd */
- byte length; /* 1 2 or 4 bytes */
- int16 refseg; /* segment to which reference refers to */
-};
-
-struct ImportRec {
- byte type; /* must be 2 */
- byte reclen; /* content length */
- int16 segment; /* segment number allocated to the label for reloc
- records - label is assumed to be at offset zero
- in this segment, so linker must fix up with offset
- of segment and of offset within segment */
- char label[33]; /* zero terminated... should be written to file until
- the zero, but not after it - max len = 32 chars */
-};
-
-struct ExportRec {
- byte type; /* must be 3 */
- byte reclen; /* content length */
- byte segment; /* segment referred to (0/1/2) */
- long offset; /* offset within segment */
- char label[33]; /* zero terminated as above. max len = 32 chars */
-};
-
-struct DLLRec {
- byte type; /* must be 4 */
- byte reclen; /* content length */
- char libname[128]; /* name of library to link with at load time */
-};
-
-struct BSSRec {
- byte type; /* must be 5 */
- byte reclen; /* content length */
- long amount; /* number of bytes BSS to reserve */
-};
-
-struct ModRec {
- byte type; /* must be 8 */
- byte reclen; /* content length */
- char modname[128]; /* module name */
-};
-
-#ifdef _MULTBOOT_H
-
-#define RDFLDRMOVER_SIZE 22
-
-struct MultiBootHdrRec {
- byte type; /* must be 9 */
- byte reclen; /* content length */
-#ifdef __GNUC__
- struct tMultiBootHeader mb __attribute__ ((packed)); /* MultiBoot header */
-#else
- struct tMultiBootHeader mb;
-#endif
- byte mover[RDFLDRMOVER_SIZE]; /* Mover of RDF loader */
-};
-#endif
-
-/* GenericRec - contains the type and length field, plus a 128 byte
- char array 'data', which will probably never be used! */
-
-struct GenericRec {
- byte type;
- byte reclen;
- char data[128];
-};
-
-typedef union RDFHeaderRec {
- char type; /* invariant throughout all below */
- struct GenericRec g;
- struct RelocRec r; /* type == 1 / 6 */
- struct ImportRec i; /* type == 2 / 7 */
- struct ExportRec e; /* type == 3 */
- struct DLLRec d; /* type == 4 */
- struct BSSRec b; /* type == 5 */
- struct ModRec m; /* type == 8 */
-#ifdef _MULTBOOT_H
- struct MultiBootHdrRec mbh; /* type == 9 */
-#endif
-} rdfheaderrec;
-
-struct SegmentHeaderRec {
- /* information from file */
- int16 type;
- int16 number;
- int16 reserved;
- long length;
-
- /* information built up here */
- long offset;
- byte *data; /* pointer to segment data if it exists in memory */
-};
-
-typedef struct RDFFileInfo {
- FILE *fp; /* file descriptor; must be open to use this struct */
- int rdoff_ver; /* should be 1; any higher => not guaranteed to work */
- long header_len;
- long header_ofs;
-
- byte *header_loc; /* keep location of header */
- long header_fp; /* current location within header for reading */
-
- struct SegmentHeaderRec seg[RDF_MAXSEGS];
- int nsegs;
-
- long eof_offset; /* offset of the first byte beyond the end of this
- module */
-
- char *name; /* name of module in libraries */
- int *refcount; /* pointer to reference count on file, or NULL */
-} rdffile;
-
-#define BUF_BLOCK_LEN 4088 /* selected to match page size (4096)
- * on 80x86 machines for efficiency */
-typedef struct memorybuffer {
- int length;
- byte buffer[BUF_BLOCK_LEN];
- struct memorybuffer *next;
-} memorybuffer;
-
-typedef struct {
- memorybuffer * buf; /* buffer containing header records */
- int nsegments; /* number of segments to be written */
- long seglength; /* total length of all the segments */
-} rdf_headerbuf;
-
-/* segments used by RDOFF, understood by rdoffloadseg */
-#define RDOFF_CODE 0
-#define RDOFF_DATA 1
-#define RDOFF_HEADER -1
-/* mask for 'segment' in relocation records to find if relative relocation */
-#define RDOFF_RELATIVEMASK 64
-/* mask to find actual segment value in relocation records */
-#define RDOFF_SEGMENTMASK 63
-
-extern int rdf_errno;
-
-/* utility functions */
-int16 translateshort(int16 in);
-long translatelong(long in);
-
-/* RDOFF file manipulation functions */
-int rdfopen(rdffile *f,const char *name);
-int rdfopenhere(rdffile *f, FILE *fp, int *refcount, const char *name);
-int rdfclose(rdffile *f);
-int rdffindsegment(rdffile * f, int segno);
-int rdfloadseg(rdffile *f,int segment,void *buffer);
-rdfheaderrec *rdfgetheaderrec(rdffile *f); /* returns static storage */
-void rdfheaderrewind(rdffile *f); /* back to start of header */
-void rdfperror(const char *app,const char *name);
-
-/* functions to write a new RDOFF header to a file -
- use rdfnewheader to allocate a header, rdfaddheader to add records to it,
- rdfaddsegment to notify the header routines that a segment exists, and
- to tell it how long the segment will be.
- rdfwriteheader to write the file id, object length, and header
- to a file, and then rdfdoneheader to dispose of the header */
-
-rdf_headerbuf *rdfnewheader(void);
-int rdfaddheader(rdf_headerbuf *h,rdfheaderrec *r);
-int rdfaddsegment(rdf_headerbuf *h, long seglength);
-int rdfwriteheader(FILE *fp,rdf_headerbuf *h);
-void rdfdoneheader(rdf_headerbuf *h);
-
-/* This is needed by linker to write multiboot header record */
-int membuflength(memorybuffer *b);
-
-#endif /* _RDOFF_H */
+***************
+*** 9,15 ****
+ * as acknowledgement is given in an appropriate manner to its authors,
+ * with instructions of how to obtain a copy via ftp.
+ */
+-
+ #ifndef _RDOFF_H
+ #define _RDOFF_H "RDOFF2 support routines v0.3"
+
+--- 9,15 ----
+ * as acknowledgement is given in an appropriate manner to its authors,
+ * with instructions of how to obtain a copy via ftp.
+ */
++
+ #ifndef _RDOFF_H
+ #define _RDOFF_H "RDOFF2 support routines v0.3"
+
+***************
+*** 48,54 ****
+ struct ExportRec {
+ byte type; /* must be 3 */
+ byte reclen; /* content length */
+- byte segment; /* segment referred to (0/1) */
+ long offset; /* offset within segment */
+ char label[33]; /* zero terminated as above. max len = 32 chars */
+ };
+--- 48,54 ----
+ struct ExportRec {
+ byte type; /* must be 3 */
+ byte reclen; /* content length */
++ byte segment; /* segment referred to (0/1/2) */
+ long offset; /* offset within segment */
+ char label[33]; /* zero terminated as above. max len = 32 chars */
+ };
+***************
+*** 65,70 ****
+ long amount; /* number of bytes BSS to reserve */
+ };
+
+ /* GenericRec - contains the type and length field, plus a 128 byte
+ char array 'data', which will probably never be used! */
+
+--- 65,92 ----
+ long amount; /* number of bytes BSS to reserve */
+ };
+
++ struct ModRec {
++ byte type; /* must be 8 */
++ byte reclen; /* content length */
++ char modname[128]; /* module name */
++ };
++
++ #ifdef _MULTBOOT_H
++
++ #define RDFLDRMOVER_SIZE 22
++
++ struct MultiBootHdrRec {
++ byte type; /* must be 9 */
++ byte reclen; /* content length */
++ #ifdef __GNUC__
++ struct tMultiBootHeader mb __attribute__ ((packed)); /* MultiBoot header */
++ #else
++ struct tMultiBootHeader mb;
++ #endif
++ byte mover[RDFLDRMOVER_SIZE]; /* Mover of RDF loader */
++ };
++ #endif
++
+ /* GenericRec - contains the type and length field, plus a 128 byte
+ char array 'data', which will probably never be used! */
+
+***************
+*** 82,87 ****
+ struct ExportRec e; /* type == 3 */
+ struct DLLRec d; /* type == 4 */
+ struct BSSRec b; /* type == 5 */
+ } rdfheaderrec;
+
+ struct SegmentHeaderRec {
+--- 104,113 ----
+ struct ExportRec e; /* type == 3 */
+ struct DLLRec d; /* type == 4 */
+ struct BSSRec b; /* type == 5 */
++ struct ModRec m; /* type == 8 */
++ #ifdef _MULTBOOT_H
++ struct MultiBootHdrRec mbh; /* type == 9 */
++ #endif
+ } rdfheaderrec;
+
+ struct SegmentHeaderRec {
+***************
+*** 166,170 ****
+ int rdfaddsegment(rdf_headerbuf *h, long seglength);
+ int rdfwriteheader(FILE *fp,rdf_headerbuf *h);
+ void rdfdoneheader(rdf_headerbuf *h);
+
+ #endif /* _RDOFF_H */
+--- 192,199 ----
+ int rdfaddsegment(rdf_headerbuf *h, long seglength);
+ int rdfwriteheader(FILE *fp,rdf_headerbuf *h);
+ void rdfdoneheader(rdf_headerbuf *h);
++
++ /* This is needed by linker to write multiboot header record */
++ int membuflength(memorybuffer *b);
+
+ #endif /* _RDOFF_H */
diff --git a/test/bintest.asm b/test/bintest.asm
index 94d2bf7..96a1dce 100644
--- a/test/bintest.asm
+++ b/test/bintest.asm
@@ -1,56 +1,34 @@
-; test source file for assembling to binary files
-; build with:
-; nasm -f bin -o bintest.com bintest.asm
-
-; When run (as a DOS .COM file), this program should print
-; hello, world
-; on two successive lines, then exit cleanly.
-
-; This file should test the following:
-; [1] Define a text-section symbol
-; [2] Define a data-section symbol
-; [3] Define a BSS-section symbol
-; [4] Define a NASM local label
-; [5] Reference a NASM local label
-; [6] Reference a text-section symbol in the text section
-; [7] Reference a data-section symbol in the text section
-; [8] Reference a BSS-section symbol in the text section
-; [9] Reference a text-section symbol in the data section
-; [10] Reference a data-section symbol in the data section
-; [11] Reference a BSS-section symbol in the data section
-
- BITS 16
- ORG 0x100
-
- SECTION .text
-
- jmp start ; [6]
-
-endX mov ax,0x4c00 ; [1]
- int 0x21
-
-start mov byte [bss_sym],',' ; [1] [8]
- mov bx,[bssptr] ; [7]
- mov al,[bx]
- mov bx,[dataptr] ; [7]
- mov [bx],al
- mov cx,2
-.loop mov dx,datasym ; [1] [4] [7]
- mov ah,9
- push cx
- int 0x21
- pop cx
- loop .loop ; [5] [6]
- mov bx,[textptr] ; [7]
- jmp bx
-
- SECTION .data
-
-datasym db 'hello world', 13, 10, '$' ; [2]
-bssptr dw bss_sym ; [2] [11]
-dataptr dw datasym+5 ; [2] [10]
-textptr dw endX ; [2] [9]
-
- SECTION .bss
-
-bss_sym resb 1 ; [3]
+***************
+*** 26,32 ****
+
+ jmp start ; [6]
+
+- end mov ax,0x4c00 ; [1]
+ int 0x21
+
+ start mov byte [bss_sym],',' ; [1] [8]
+--- 26,32 ----
+
+ jmp start ; [6]
+
++ endX mov ax,0x4c00 ; [1]
+ int 0x21
+
+ start mov byte [bss_sym],',' ; [1] [8]
+***************
+*** 49,55 ****
+ datasym db 'hello world', 13, 10, '$' ; [2]
+ bssptr dw bss_sym ; [2] [11]
+ dataptr dw datasym+5 ; [2] [10]
+- textptr dw end ; [2] [9]
+
+ SECTION .bss
+
+--- 49,55 ----
+ datasym db 'hello world', 13, 10, '$' ; [2]
+ bssptr dw bss_sym ; [2] [11]
+ dataptr dw datasym+5 ; [2] [10]
++ textptr dw endX ; [2] [9]
+
+ SECTION .bss
+